i need a function who checks zipcode with cities in a database and give back the city name in a form input field.
So i have set rules in my model like:
public function rules()
{
return [
...
[['zipcode'], 'getCity', 'when' => function ($model, $attribute) {
return $model->{$attribute} !== $model->getOldAttribute($attribute);
}
],
...
];
}
And i have a function called getCity in the model like:
public function getCity($attribute, $params) {
$city=checkZipcodeDatabase($this->$attribute);
if($city) {
// there will be a function who search the zipcode
// in a data table and returns the city name
$this->city=$city // sets the form field city with found city name from database;
return true;
} else {
$this->addError('city', 'city is wrong'); //sets the error from form field city
return false;
}
}
When the user add a zipcode in the form field the function must look in a database if the zipcode and the city exists and give the city name back. if there is nothing, the function give false back.
If there is a city name found, the value of the city field in the form must set to the city name. If there is nothing there must shown a error at the city form field. But at the moment, the error message only will be added to the city attribute. But the message will no shown at the form field.
I can see this if i debugging with browser:
Is this possible to set the value form a form field from another field when using rules?
You can achieve it in at least two ways. First, server side way, if you set your model attribute to the city name you have got with your db query (ran within zipcode field rule for example) and then render the view again, it will be there. Second, JS way, you can respond on the JS afterValidate event, send some ajax request with zip code and fill your form field with the city name.
I don’t know how i can refresh the view after validation. You mean that i completly reload the site or can i only reload the form?
And the second way with JS means for example?
// JS afterValidate function
$('.validate-form').on('afterValidate', function (event, messages, errorAttributes) {
//load the city name from db with a ajax function
return false;
});
Can you give me a few more tips? Thank you very much…
In the simplest way you can reload whole page (or form via pjax). Think the form lifecycle way on server side. In pseudo-code:
load form model
// zipcode present but city NOT
if(form->zipcode && !form->city) {
load city from db
update form model -> city
return render form
}
// zipcode AND city present
if(form->zipcode && form->city) {
procceed form
save data etc.
return render success :))
}
$this->registerJs(<<<JS
$('#yourform').on('afterValidateAttribute', function (e, a, m) {
// check if it is zipcode attribute
// ...
// if so, do some ajax request
// ...
// update your 'city' field value
$("#yourcityformfield").val(//ajax response)
});
JS);