You are viewing revision #9 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
Overview ¶
This wiki is to show you how to use jQuery get and JSON to get data from a dropdown/any form field and fill form fields with the values instantaneously. First, I'll give example use cases of what I'm going to teach you so you can quickly see if this is for you.
Use Case ¶
Lets say you have a database table that stores locations. These locations have an address associated with them (id, name, address, city, state, zip).
You may also have another table that stores user locations (id, user_id, address, city, state, zip).
You allow the user to select a location from a dropdown. This dropdown will now get the data for that location and input the information into the current form and fill the address, city, state, and zip from it.
Introduction ¶
The above is just a very simple example. You can use what I'm about to show you for numerous things including pulling data from an external API and filling your form data with it. One way I personally use this is on my address forms I have the user type in a postal code and then I pull the city, state, and country from it.
Data we are pulling from ¶
For this example we will have a model called "locations" this locations model will have a database table with the following fields.
id
name
address
city
state
zip
Where we are putting the Data ¶
i will also have another model called UserLocations with the following fields
id
user_id
address
city
state
zip
This model will also have a controller called UserLocations.
first we will go in our controller and create a function to retrieve the location and return it's data via JSON.
Controller ¶
UserlocationsContrller
use yii\helpers\Html;
use yii\web\Response;
public function actionGetLocationAddress($id) {
Yii::$app->response->format = Response::FORMAT_JSON;
echo Locations::find()->where('id = :id', [':id' => $id])->one();
}
Since the function is camelCased you should note that it needs to accessed like. userlocations/get-location-address
if it wasn't camelCased i.e.
actionGetlocationaddress
it would be accessed like
userlocations/getloctionaddress
Form ¶
Now we go to our UserLocationForm here for simplicity of this example I am not putting any styling, id's, placeholders etc. I am also placing the JS inline. It should be noted that it is recommend to register your JS using Yii2 asset functions.
<?php
use frontend\models\Locations;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin();?>
<?= $form->field($model, 'location')->dropDownList(ArrayHelper::map(Locations::find()->all(), 'id', 'name')) ?>
<?= $form->field($model, 'city')->textInput(); ?>
<?= $form->field($model, 'city')->textInput(); ?>
<?= $form->field($model, 'state')->textInput(); ?>
//this is type tel so it propmts the number pad on mobile devices.
<?= $form->field($model, 'zip')->input('tel'); ?>
<?php ActiveForm::end(); ?>
<script type="text/javascript">
//the dropdown list id; This doesn't have to be a dropdown it can be any field type.
$("#user-locations-location").on("change", function() {
//the dropdown list selected locations id
var id = $(this).val();
//call the action we created above in the conrller
$.get("<?= Url::to(['userlocations/get-location-address']); ?>", {id: id}, function(data) {
//get the JSON data from the action
var data = $.parseJSON(data);
//check if the system found any data
if (data !== null) {
//if yes fill the form field with the ids address,city, state & zip.
//we use .blur because yii will fire validation for those field after they are filled
$("#user-locations-address").val(data.address).blur();
$("#user-locations-city").val(data.city).blur();
$("#user-locations-state").val(data.state).blur();
$("#user-locations-zip").val(data.zip).blur();
} else {
//if data wasn't found the alert.
alert('We\'re sorry but we couldn\'t load the the location data!');
}
});
});
</script>
Also, to get the proper ids (#user-location-address) you must use a tool like firebug or Firefox inspect element to get them. By default yii will do (all lowercase) #modelname-attributename / #modelname-attribute_name;
i.e.
locations model state field will become
locations-state ¶
- Overview
- Use Case
- Introduction
- Data we are pulling from
- Where we are putting the Data
- Controller
- Form
or locations model postal_code will become
locations-postal_code ¶
You can also set the Id in the options array of the form field.
<?= $form->field($model, 'state')->textInput(['id'=>'state']); ?>
However, if you manually set them then make sure you set the options array selectors in the form to match or client side validation won't work.
<?= $form->field($model, 'state',['selectors' => ['input' => '#state']])->textInput(['id'=>'state']); ?>
That is all you have to do for this very basic example. You can also switch the url portion of the jQuery to an external JSON API to get data. If you have questions post below and I'll try and answer them if I can.
Example without ugly hacks
RE: Example without ugly hacks
Edit: corrected wiki @zelenin good catch.
RE: Example without ugly hacks
@skworden oh, you must read about pdo binding because you're not right
How I got it to work Yii2
1) Changed url format in javascript function
From this:
$.get("<?= Url::to(['userlocations/get-location-address']); ?>", {id: id},
To this:
$.get("userlocations/get-location-address", {id: id},
2) Changed Controller function that queries data
From this:
echo Locations::find()->where('id = :id', [':id' => $id])->one();
To this:
return Locations::find()->where('id = :id', [':id' => $id])->one();
Now it works for me.
I also needed a formfill with JSON. Tank you for the wiki.
With Yii 2.0.14 I changed this:
$.get("<?= Url::to(['userlocations/get-location-address']); ?>", {id: id},
to this:
$.get("index.php?r=userlocations/get-location-address", {id: id},
However I didn't need this:
var data = $.parseJSON(data);
This run in my app
in controller
`
phppublic function actionGetLocationAddress($id) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; return Yii::$app->response->data = \app\models\Tb05comuni::findOne($id); }
in client ```js $.get("index.php?r=userlocations/get-location-address", {id: id}, function(data) { if (data !== null) { $("#user-locations-address").val(data['address']).blur(); } }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.