I have form open in Boootstrap modal and want to submit form via ajax so it creates new record in database and show either success or fail message.
below is my form code which opens in modal popup
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="address-form">
<?php $form = ActiveForm::begin([
'options' => ['id' => 'addressForm'],
]); ?>
<?= $form->field($model, 'address_1')->textInput(['maxlength' => 45]) ?>
<?= $form->field($model, 'address_2')->textInput(['maxlength' => 45]) ?>
<?= $form->field($model, 'suburb')->textInput(['maxlength' => 45]) ?>
<?= $form->field($model, 'postcode')->textInput() ?>
<?php echo $form->field($model, 'state')->dropDownList(\common\models\ValueHelpers::getStateList(), ['prompt' => 'Please Choose One']); ?>
<?= $form->field($model, 'country')->textInput(['maxlength' => 45]) ?>
<div class="form-group">
<?php echo Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
my js is as below for testing
$(function() {
$('#addressForm').on('ajaxBeforeSend', function (event, jqXHR, settings) {
alert(1);
}).on('ajaxComplete', function (event, jqXHR, textStatus) {
alert(2);
});
});
however on form submit it doesn’t give me this alerts and redirect directly to http://something.com/index.php?r=address%2Fcreate rather than staying on popup.
You need more cowbell…
You need to stop the form from submitting so you don’t close the modal and set up your controller to handle the Ajax request.
I tried to make this as much default Yii as possible and comment everything so it is clear for you and others.
You can do something like the following
in your controller
/**
* Creates a new Address record.
* @return mixed
*/
public function actionCreate() {
//inieate the model
$model = new Address();
//check if user is trying to save post request
if ($model->load(Yii::$app->request->post()) && $model->save()) {
//if it saves check if the request was ajax or pjax
if (Yii::$app->request->isPjax || Yii::$app->request->isAjax) {
//if it was ajax or pjax return json data back.
//you can return whatever you want here
return json_encode([ 'address_1' => $model->address_1, 'randomItem'=>'Randomness']);
} else {
//if it wasn't a ajax or pjax request or if it failed for whatever reason go to view page
return $this->redirect(['view', 'id' => (string) $model->_id]);
}
} else {
//if user is just trying to view the page or for has errors
//check if request if ajax or pjax if so then render on the page content and not the whole layout
if (Yii::$app->request->isPjax || Yii::$app->request->isAjax) {
return $this->renderAjax('_form', [ 'model' => $model]);
} else {
//if is not ajax /pjax request or
//if the ajax /pjax fails then render the page normally
return $this->render('_form', [ 'model' => $model]);
}
}
}
in your form view file add the following
<script type="text/javascript">
//on clicking form submit button hyjack default form action and send via ajax/json
$(document).ready(
$('#addressForm').on('beforeSubmit', function(event) {
var form = $(this);
//if the form has errors then stop
//else serialize data and send
if (form.find('#addressForm .has-error').length) {
return false;
} else {
$.ajax({
//this will use the default form action
url: form.attr('action'),
type: 'post',
dataType: 'json',
data: form.serialize(),
//if error occurs alert with pop up that there was an error with the ajax request
error: function() {
alert('There was an error processing your request!');
},
//if ajax success
success: function(data) {
alert('You have successfully created the address at '+data.address_1+ ' street. You also returned some random item with the value:'+data.randomItem+'!');
//this will close your modal if you want i use closest just incase your modals are nested it will only close the top level one
// $('#addressForm').closest('.modal').modal('hide');
// you can also put if else statements here to conditionally do things
//this will reload a pjax element if you use it.
//$.pjax.reload({container: "#address-list"});
}
}
});
//Stop everything if nothing above is met
return false;
}
}));
</script>
The same thing without comments to be able to read the code better.
public function actionCreate() {
$model = new Address();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if (Yii::$app->request->isPjax || Yii::$app->request->isAjax) {
return json_encode([ 'address_1' => $model->address_1, 'randomItem' => 'Randomness']);
} else {
return $this->redirect(['view', 'id' => (string) $model->id]);
}
} else {
if (Yii::$app->request->isPjax || Yii::$app->request->isAjax) {
return $this->renderAjax('_form', [ 'model' => $model]);
} else {
return $this->render('_form', [ 'model' => $model]);
}
}
}
<script type="text/javascript">
$(document).ready($('#addressForm').on('beforeSubmit', function(event) {
var form = $(this);
if (form.find('#addressForm .has-error').length) {
return false;
} else {
$.ajax({
url: form.attr('action'),
type: 'post',
dataType: 'json',
data: form.serialize(),
error: function() {
alert('There was an error processing your request!');
},
success: function(data) {
alert('You have successfully created the address at ' + data.address_1 + ' street. You also returned some random item with the value:' + data.randomItem + '!');
}
}
});
return false;
}
}));
</script>
i will give it a go and update the post.
thanks for the help