Yii2 success modal window - ajax

In view I have a form:
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true, 'placeholder' => 'Name'])->label(false) ?>
<?= $form->field($model, 'phone')->textInput(['maxlength' => true, 'placeholder' => 'Phone'])->label(false) ?>
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
Controller is:
if ($model->load(Yii::$app->request->post()) && $model->save()) {
\Yii::$app->session->setFlash('success', 'Created');
}
return $this->redirect(Yii::$app->request->referrer);
Then in view I put a modal:
<?php if (Yii::$app->session->hasFlash('success')) :?>
<!-- <div class="container">
<?= Yii::$app->session->getFlash('success', null, true) ?>
</div> -->
<div class="modal hide fade" id="myModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Modal header</h3>
</div>
<div class="modal-body">
<p><?= Yii::$app->session->getFlash('success', null, true) ?></p>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
<?php endif ;?>
And JS code is:
$(window).load(function(){
$('#myModal').modal('show');
});
I want to open success modal window after clicking submit button. But now nothing happens. Just reloads the page. How to do that I want? And please explain how to do that without reloading the page.

This might be no the best decidion, but i use class myAjaxModalClass and a simple js code, that submit all form with that class via ajax and parse json result:
{result:0, data:'new modal content'}
That allows me to load form with validation erros without page reloading. Also you may add your result status to submit redirect. Expample:
{result: 2, url:'http://yoursite.net'}

Related

Yii2 ActiveForm: display Ajax validation response at the top of the form or in errorSummary()

I'm using ActiveForm and I would need to display the validation errors not close to the input fields but rather at the top of the form.
As shown in the sample code below, setting errorOptions I avoid to display the error message in the default position.
Ajax validation is working but the $form->errorSummary($model) doesn't show any message, even if here it seems like it should and in the documentation I could not find a clear answer.
Also, adding Html::error($model, 'username') does not help with Ajax validation.
<?php
$form = ActiveForm::begin([
'id' => 'test-form',
'options' => ['class' => 'form-horizontal'],
'enableAjaxValidation' => true,
'enableClientValidation' => true,
])
?>
<?= $form->errorSummary($model) ?>
<?= Html::error($model, 'username') ?>
<div class="form-row">
<div class="form-group col-md-3">
<?= $form->field($model, 'username', ['errorOptions' => ['tag' => false]])->textInput()->label("Username") ?>
</div>
</div>
<?php ActiveForm::end() ?>
In Yii1.1 the validation errors can be displayed in a more flexible way, since you could define label, input and error individually. Something like this:
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
In that case you can simply move $form->error($model,'username'); anywhere within the form.
How is it possible to obtain the same results with Yii2 without using the Javascript API?
Display the Ajax validation errors for individual input at the top of the form.
Display the Ajax validation errors with errorSummary()
Edit
I forgot to mention that I'm using Bootstrap4 through the extension yii2-bootstrap4. Part of the problems I'm having with the error display may be related to this bug.
Considering the answer from #serghei-leonenco I add here some complete minimal code to replicate the problem.
Model
namespace frontend\models;
use Yii;
use yii\base\Model;
class AjaxForm extends \yii\base\Model
{
public $demo;
public function rules()
{
return [
// define validation rules here
[['demo'], 'required'],
[['demo'], 'string', 'length' => [2, 4]],
];
}
}
View
<div class="row">
<div class="col-lg-6">
<?php $form = ActiveForm::begin(['id' => 'test-form',
'options' => [
'class' => 'form-horizontal'],
'enableAjaxValidation' => true,
'enableClientValidation' => false,]) ?>
<div class="form-row">
<div class="form-group col-md-3">
<?php echo $form->field($model, 'demo', ['template' => '{error}']); ?>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3">
<?= $form->field($model, 'demo')->textInput()->label("Demo") ?>
<?php echo $form->field($model, 'demo', ['template' => '{error}']); ?>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Submit 1', ['class' => 'btn btn-primary','name' => 'submit1']) ?>
</div>
</div>
<?php ActiveForm::end() ?>
</div>
</div>
Controller
public function actionTestajax()
{
$model = new AjaxForm();
// Ajax validation
if (Yii::$app->request->isAjax){
$model->load(Yii::$app->request->post());
Yii::$app->response->format = Response::FORMAT_JSON;
$ret = ActiveForm::validate($model);
Yii::info("Ajax validation: " . json_encode($ret));
return $ret;
}
// form submit
if ($model->load(Yii::$app->request->post())) {
if($model->validate()){
// valid data received in $model
//var_dump($model);
return $this->render('testajax_submit', ['model' => $model]);
} else {
return $this->render('testajax', ['model' => $model]);
}
}
return $this->render('testajax', ['model' => $model]);
}
Out of the three <div class="invalid-feedback">Demo cannot be blank.</div>, only one is shown, the other two maintain the style .invalid-feedback {display: none;}.
The $form->errorSummary($model):
after the validation is performed, returns this:
<div style="display:none">
<p>Please fix the following errors:</p>
<ul></ul>
</div>
after the form is submitted, returns this:
<div class="alert alert-danger" style="">
<p>Please fix the following errors:</p>
<ul>
<li>Demo cannot be blank.</li>
<li>Demo cannot be blank.</li>
<li>Demo cannot be blank.</li>
</ul>
</div>
I did tested out $form->errorSummary(); and it does shows the desired output, but in the form of:
Please fix the following errors:
Please enter Username.
Like an option, you can do it this way:
<?php $form = ActiveForm::begin([
'id' => 'test-form',
'options' => ['class' => 'form-horizontal'],
'enableAjaxValidation' => true,
'enableClientValidation' => true,
]); ?>
<div class="form-group col-md-3">
<div class="error-block text-center">
<?php
$error = $form->field($model, 'username');
$error->template = '{error}';
echo $error;
?>
</div>
<?php
$username = $form->field($model, 'username');
$username->template = "{input}";
echo $username->textInput(['autofocus' => true]);
?>
</div>
<?php ActiveForm::end() ?>
The output will be right above the form field will be the response with:
Please enter Username

Onchange in dropdown rendering partial a dynamic form yii2 using ajax

i have a create form, Which posts value to actionCreate() like
Form - dropdown
Dynamic form depending on the dropdown above
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']);?>
<?=
$form->field($model, 'techpark_id')->dropDownList($techparks, ['prompt' => '- Choose a Techpark -',
'onchange' => '
$.get( "' . Yii::$app->urlManager->createUrl('campaign-request/techpark-details?id=') . '"+$(this).val(), function( data ) {
$( "#details" ).html( data );
});
']);
?>
<div id="details">
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Now the onchange event in the dropdown -> techpark_id will post id to campaign-request/teckpark-details
Yii::$app->urlManager->createUrl('campaign-request/techpark-details?id=7)
This actionTechparkDetails will renderPartial like this with values to dropdown list depending upon the value $id
public function actionTechparkDetails($id) {
$details = [new \app\models\CampaignRequestAdDetails];
$connection = Yii::$app->getDb();
$command = $connection->createCommand('
SELECT adspace_type_id,type,number_of_adspace,number_of_filled,adspace_value FROM `Techpark`
JOIN techpark_adspace ON techpark.id = techpark_id
JOIN adspace_type ON adspace_type_id = adspace_type.id
WHERE techpark.id=:id', [':id' => $id]);
$result = $command->queryAll();
$adspace_type_id = ArrayHelper::map($result, 'adspace_type_id', 'type');
return $this->renderAjax('_campaignDetails', [
'details' => (empty($details)) ? [new \app\models\CampaignRequestAdDetails] : $details,
'adspace_type_id' => $adspace_type_id
]);
}
campaignDetails has a dynamic form which populates the value depending on the selected dropdown() value ($id)
My _campaignDetails.php
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']);?>
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i> Campaign details</h4></div>
<div class="panel-body">
<?php
DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 20, // the maximum times, an element can be cloned (default 999)
'min' => 4, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $details[0],
'formId' => 'dynamic-form',
'formFields' => [
'adspace_type_id',
'number_of_adspace',
],
]);
?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($details as $i => $detail): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (!$detail->isNewRecord) {
echo Html::activeHiddenInput($detail, "[{$i}]id");
}
?>
<div class="row">
<div class="col-sm-4">
<?= $form->field($detail, "[{$i}]adspace_type_id")->dropDownList($adspace_type_id) ?>
</div>
<div class="col-sm-4">
<?= $form->field($detail, "[{$i}]number_of_adspace")->textInput() ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
Now when i fill up the form and submit, i am unable to get the values of form (_campaignDetails.php which was rendered partially), inside actionCreate().
And also the remove item is not working in the dynamic form. Which would perfectly working if rendered inside the same form(i have another form which works fine with add/remove item of dynamic form).
I am using widget to dynamic form github.com/wbraganca/yii2-dynamicform
OR tell me how can i achieve the above scenario in any other format/manner using differnt approach. If you donot get what i want to achieve is
Depending on a dropdown value, i want a dynamic form which collects input with respect to value selected.
Thanks

YII2 gridview custom search with ajax

I am working with Yii2.0 search functionality,if we show the grid as its means the ajax search is working fine,but i have to changed the layout(see the screen below), from that right side form i have to do the search using ajax.
I also search with google but not get the related one.
Thanks in advance for your help.
I suggest you the use of a separated filter form like explain in this Yii2 guide
http://www.yiiframework.com/doc-2.0/guide-output-data-widgets.html#separate-filter-form
Using a partial view _search.php with (eg:) the following contents:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="post-search">
<?php $form = ActiveForm::begin([
'action' => ['index'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'creation_date') ?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
<?= Html::submitButton('Reset', ['class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
and include it in index.php view like so:
<?= $this->render('_search', ['model' => $searchModel]) ?>

model->validate displays errors for text field which has value in yii

I have an application where user has to fill a lengthy form, so I split the form into three and created steps - Step 1, Step 2 etc. So it has to be convenient for users. Now I face a problem, after filling out the details, a text field shows an error. When using model->get Errors() the error is 'address cannot be blank'. When I use $_POST the arrays displays value for the field address. I started yii framework last week and I do not know where I have gone wrong. Any help appreciated.
The view code i use forloop to reduce my code -
<fieldset>
<?php if(!Yii::app()->user->hasFlash('success')):
Yii::app()->user->setFlash('warning','All Fields are mandatory!');
endif; ?>
<?php echo CHtml::errorSummary($model, null, null, array(
'class' => 'alert alert-danger col-lg-offset-2',
)); ?>
<?php $rrr = -1;
foreach($model->attributeLabels() as $a){ $rrr++;
if($rrr<27 && $rrr>=12){
?>
<div class="form-group">
<?php echo CHtml::activeLabel($model, $a, array('class' => 'col-lg-3 control-label')); ?>
<div class="col-lg-7">
<?php echo CHtml::activeTextField($model,array_keys($model->attributeLabels())[$rrr],array('value'=>'a','size'=>255,'maxlength'=>255,'class'=>'form-control formtype1')); ?>
</div>
</div>
<?php
}}
?>
<?php $rrr = -1;
foreach($model2->attributeLabels() as $a){ $rrr++;
if($rrr>1 && $rrr<6){
?>
<div class="form-group">
<?php echo CHtml::activeLabel($model2, $a, array('class' => 'col-lg-3 control-label')); ?>
<div class="col-lg-7">
<?php echo CHtml::activeTextField($model2,array_keys($model2->attributeLabels())[$rrr],array('value'=>'a','size'=>255,'maxlength'=>255,'class'=>'form-control formtype1')); ?>
</div>
</div>
<?php
}}
?>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-sm btn-primary" type="submit"><?php echo Yii::t("user", "Submit") ?></button>
</div>
</div>
</fieldset>
</form>

CActiveForm ajax validation error not displaying in the form

I have created a form using CActiveForm in yii. I am using ajax to submit the form using CHtml::ajaxSubmitButton. Form submission using ajax is working correctly and I am able to get the values in the control using $_POST['modelname']['fieldname']. But the ajax form validation is not working correctly. Below is the code
<?php
$form=$this->beginWidget('CActiveForm', array(
'id'=>'item-brand-form',
'enableAjaxValidation' => true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
'htmlOptions'=>array(
'class'=>'form-horizontal',
),
)); ?>
<div class="form-group">
<?php echo $form->labelEx($model,'Brand Name',array('class'=>'control-label col-lg-4','for'=>'ItemBrand_brand_name')); ?>
<div class="col-lg-6">
<?php echo $form->textField($model,'brand_name',array('class'=>'form-control')); ?>
<?php echo $form->error($model,'brand_name'); ?>
</div>
<!-- End col-lg-6 -->
</div><!-- End Form Group -->
<div class="form-group">
<?php echo $form->labelEx($model,'Brand Code',array('class'=>'control-label col-lg-4','for'=>'ItemBrand_brand_code')); ?>
<div class="col-lg-6">
<?php echo $form->textField($model,'brand_code',array('class'=>'form-control')); ?>
</div>
<!-- End col-lg-6 -->
</div><!-- End Form Group -->
<div class="form-group">
<div class="col-lg-4"></div>
<div class="col-lg-2">
<?php echo CHtml::ajaxSubmitButton('Apply',array('class'=>'btn btn-lg btn-primary')); ?>
</div>
</div>
<?php $this->endWidget(); ?>
Also in the controller action following code is not working.
if(isset($_POST['ajax']) && $_POST['ajax']==='item-brand-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
so instead I am using
if(Yii::app()->getRequest()->getIsAjaxRequest())
{
echo CActiveForm::validate( array( $model));
Yii::app()->end();
}
While checking in the browser I am getting the response
{"ItemBrand_brand_name":["Brand Name cannot be blank."]}
But the error message is not displaying in the form. Also why the $_POST['ajax'] is not working ? Please help.
Thanks in advance.
I have solved this by using CHtml::submitButton instead of CHtml::ajaxSubmitButton and then submitting the form using jQuery $.ajax function in the form 'afterValidate' option. Please see the details here

Resources