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.
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
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.