Ads 4 You

Yii2 Render a form in a Modal Popup using ajax

Email Id : phpmk888@gmail.com


@1 Method 
Submit form with ajax.

Yii2 form submit model with ajax

Yii2 Form Submit Ajax with model popup

This is Controller Action Code : 

<?php

use yii\web\Response;
use yii\widgets\ActiveForm;

   /**
     * Create a User popup submit form
     * If creation is successful, the browser will be redirected to the 'view' page.     
     */
    public function actionCreatePopup() {
        $this->activeBreadcrumb = "Create";
        $model = new User();

        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
            Yii::$app->response->format = Response::FORMAT_JSON;
            return $err = ActiveForm::validate($model);
        }
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            $model->created_at = time();
            if ($model->save(false)) {
                $model->sendRegistrationEmail();
                Yii::$app->session->setFlash("success", "User registered successfully.");
                return $this->redirect(['view', 'id' => $model->id]);
            }
        } else {
            $model->mobile = $model->country_code . $model->mobile;
        }
        return $this->renderAjax('create-ajax', [
                    'model' => $model,
        ]);
    }

View File Code : 

   
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use borales\extensions\phoneInput\PhoneInput;
/* @var $this yii\web\View */
/* @var $model app\models\User */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="user-form">
    <?php
    $form = ActiveForm::begin([
                    //'id' => 'leave-apply-form',
                    //'enableAjaxValidation' => true,
                    //'enableClientValidation' => false,
                    //'options' => ['class' => 'model-form']
    ]);
    ?>
    <?= $form->field($model, 'first_name')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'last_name')->textInput(['maxlength' => true]) ?>
    <?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>
    <div class="form-group">
        <?= Html::submitButton(Yii::t('app', 'Save'), ['class' => 'btn btn-success']) ?>
        <?= Html::a(Yii::t('app', 'Cancel'), 'index', ['class' => 'btn btn-default', 'data-dismiss' => 'modal']) ?>
    </div>
    <?php ActiveForm::end(); ?>
</div>

This is a Model Dialog Code : 


<div class="modal inmodal" id="myModal2" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content animated fadeIn">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                <h3 class="modal-title">Create New User</h3>
                <small class="font-bold"></small>
            </div>
            <div class="modal-body">
                <div id='modalContent'></div>
            </div>            
        </div>
    </div>
</div>

<button href="<?php echo Url::to('create-popup');?>" type="button" class="btn btn-primary openModal">Create New User</button>


Model Open JavaScript Code : 

<?php
$script = <<< JS
    //Open Modal And Saved
    $(document).on('click',".openModal",function(e) {
        $("#myModal2").modal("show");
        $("#myModal2").find("#modalContent").load($(this).attr("href"));
    });
JS;
$this->registerJs($script);
?>




@2 Method 
First of all, sorry by my english.

now I'm here to show how I did it. Just for knowing, the article teach about puting a button that calls a modal in your site. I'm going to do a button that calls a modal in your form, getting back the Id to you proced in your form.

Folowing the article, you must create a Js file and add the file on your assets file:


 




class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/site.css',
    ];
    public $js = [
        'scripts/myScript.js',
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}

Now, in your views\myFirst\_form.php, put this code(here we have some changes):
 


     $model->isNewRecord 
                    ?Url::to(['mySecond/create'])  //Put here the url to the Create page
                    :Url::to(['mySecond/update','id'=>$model->myAttribute]), //and here to the update Page with the id attribute
            'id'=>'changeMyAttribute',
            'for'=>'#myModel1-myAttribute' //Put here the id of the field you want to update 
        ]) 
    ?>

    .... 

 
     'myModal']);
 
    echo "
"; Modal::end(); ?>
This will put the button and the base for our modal. In the button I'm using the value to pass the Url and the for to indicate wich field update. You can change it, but you must change in other places too. Going on, we need to change the Create and the Update actions of our Controller. Open controller\MySecondController.php and do the changes needed.
 


   public function actionCreate()
    {
        $model = new address();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            $model->refresh();
            Yii::$app->response->format = 'json';
            return ['message' => Yii::t('app','Success Create!'), 'id'=>$model->id];
        }
        return $this->renderAjax('create',['model'=>$model]);
    }
      public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            $model->refresh();
            Yii::$app->response->format = 'json';
            return ['message' => Yii::t('app','Success Update!'), 'id'=>$model->id];
        }
        return $this->renderAjax('update',['model'=>$model]);
    }



Now we are going to change our second view to accept the BeforeSubmit. On views\myDecond\_form.php, change the ActiveForm declararion:
 
   

 $model->formName()
    ]); ?>
    
    
    formName()."').on('beforeSubmit', function(e){
            var \$form = $(this);
            submitMySecondForm(\$form);
        }).on('submit', function(e){
            e.preventDefault();
        });";
    $this->registerJs($js);
    ?>

This solution I got from: www.ramirezcobos.com/2014/09/12/how-to-implement-form-events-on-yii2/ Finally, we need to create our script.(Yeah, we could put with registerJs, but I don't like it...)
 


$("#changeMyAttribute").click(function(){
    $("#myModal").modal('show')
            .find("#myModalContent")
            .load($(this).attr('value'));
});

function submitMySecondForm($form){
    $.post(
        $form.attr("action"),
        $form.serialize()
    )
        .done(function(result){
            $form.parent().html(result.message);
            $($("#changeMyAttribute").attr('for')).attr('value', result.id); //actualize the ID on the input hidden
            $("#changeMyAttribute").attr('value','/index.php?r=mySecond%2Fupdate&id='+result.id); //change here to the url of update view.
            $('#myModal').modal('hide');
        })
        .fail(function(){
            console.log("server error");
            $form.replaceWith('').fadeOut()
        });
    return false;
}

and it's done. If anyone has some help to improve this, feel free to comment. I think that isn't the best way to do this, but it's working well, and isn't hard to do.

Comments

  1. Really awesome blog. Your blog is really useful for me. Thanks for sharing this informative blog. Keep update your blog.
    Hire Yii Framework Team in India

    ReplyDelete

Post a Comment