A
A
Andrey Zakharov2017-12-19 00:11:43
This
Andrey Zakharov, 2017-12-19 00:11:43

Yii2 how to make a form submit using ajax?

Hello!
Can't seem to get the form to submit without reloading the page. Please tell me what could be the problem:
I tried to do it using https://webformyself.com/yii2-ajax/ But even $('form').on('beforeSubmit', function() does not work . The
page is reloaded anyway. Probably Is the controller written incorrectly

?

<div class="container">
            <div class="row">
                <div class="arroud-form">
                    <div class="col-md-offset-1 col-xs-4">
                            <?php $form = ActiveForm::begin(['id' => 'contact-form', 'method' => 'POST', 'options' => ['enctype' => 'multipart/form-data']]); ?>

                            <?= $form->field($model, 'name')->label(false)->textInput(['placeholder' => 'Имя:', 'class' => 'form-field']) ?>

                            <?= $form->field($model, 'email')->label(false)->textInput(['placeholder' => 'E-Mail:', 'class' => 'form-field']) ?>

                            <?= $form->field($model, 'telef')->label(false)->textInput(['placeholder' => 'Телефон:', 'class' => 'form-field', 'pattern' => '^[ 0-9]+$']) ?>
                    </div>
                    <div class="col-xs-7">
                            <?= $form->field($model, 'body')->label(false)->textarea(['rows' => 6, 'placeholder' => 'Напишите ваш комментарий', 'class' => 'form-area']) ?>
                            <?= $form->field($model, 'file')->fileInput() ?>
                            <br><label for="myform-file"><span class="paperclip">Прикрепить <i class="fa fa-paperclip fa-2x"></i></span></label>
                    </div>
                    <div class="clear"></div>
                    	<div class="agreement">
                        	<input type="checkbox" id="ua-check" name="change" checked class="ua-check">
                        	<label id="ua-label" for="ua-check">я согласен с обработкой моих персональных данных.</label> <span class="user-agr">Пользовательское соглашение</span>
                        </div>
                        <div class="ua-text">
                        	<div class="ua-close">X</div>
                        	<?php 
                        		$agreement = file_get_contents(__DIR__ . '/soglashenie/soglashenie.tpl');
                        		echo $agreement;
                        	?>
                        </div>
                        <div class="clear"><br /></div>
                        <div class="row">
                            <div class="col-md-offset-1 col-md-4">
                                <div class="form-group">
                                    <?= Html::submitButton('Отправить', ['class' => 'btn form-button', 'id' => 'buttonAjax', 'name' => 'contact-button']) ?>
                                </div>
                                <div class="formAlert">Необходимо принять пользовательское соглашение</div>
                            </div>
                        </div>
                        <br>
                         <?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
                                <div class="alert alert-success">
                                    Спасибо за ваше сообщение. Мы свяжемся с Вами.
                                </div>
                            <?php endif; ?>
                        <?php ActiveForm::end(); ?>
                    </div>
                </div>
            </div>
<?php
$js = <<<JS
 $('#contact-form').on('beforeSubmit', function(){
 alert('Работает!'); // Даже этот alert не работает
 return false;
 });
JS;

$this->registerJs($js);
?>


Controller:

public function actionIndex()
    {
        $model = new MyForm();

        if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
            $model->file = UploadedFile::getInstance($model, 'file');

            Yii::$app->session->setFlash('contactFormSubmitted');

            return $this->refresh();
        }
        return $this->render('index', [
            'model' => $model,
        ]);
    }


Model:

namespace app\models;

use Yii;
use yii\base\Model;
use app\models\UploadForm;
use yii\web\UploadedFile;
/**
 * ContactForm is the model behind the contact form.
 */
class MyForm extends Model
{
    public $name;
    public $email;
    public $telef;
    public $body;
    public $file;
    //public $verifyCode;


    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            // name, email, subject and body are required
            [['email', 'telef'], 'required', 'message' => 'Поле не может быть пустым'],
            ['name', 'string'],
            ['body', 'string'],
            // email has to be a valid email address
            ['email', 'email'],
            // [['file'], 'file'],
            [['file'], 'file','skipOnEmpty' => true, 'extensions' => 'txt, pdf, png, gif, doc, docx, xlsx, jpg']
            // verifyCode needs to be entered correctly
            //['verifyCode', 'captcha'],
        ];
    }

    /**
     * @return array customized attribute labels
     */
    public function attributeLabels()
    {
        return [
            'name' => 'Имя',
            'email' => 'Почта',
            'telef' => 'Телефон',
            'body' => 'Сообщение',
        ];
    }

        public function beforeValidate()
{

    $this->file = UploadedFile::getInstance($this, 'file');
    return parent::beforeValidate();
} 


    /**
     * Sends an email to the specified email address using the information collected by this model.
     * @param string $email the target email address
     * @return bool whether the model passes validation
     */
    public function contact($email)
    {
        if ($this->validate() && ($this->file = UploadedFile::getInstance($this, 'file'))) {
           $this->file->saveAs('files/' . $this->file->baseName . '.' . $this->file->extension);
            Yii::$app->mailer->compose()
                ->setTo([
                           '[email protected]'
                           
                        ])

                ->setFrom([$this->email => $this->name])
                ->setSubject('Заполнена форма на сайте Голден-Строй')
                //->setTextBody($this->telef,$this->body)
                ->setHtmlBody('
                    <p>ФИО Заказчика: '.$this->name.'</p>
                    <p>E-mail: '.$this->email.' </p>
                    <p>Телефон: '.$this->telef.' </p>
                    <p>Сообщение: '.$this->body.' </p>
                    <p>Ссылка на файл: <a download href="https://golden-stroy.com/web/files/' . $this->file->name .'">' . $this->file->name . '</a></p>
                        <hr/> 
                              ')
                ->send();
            return true;
        }
        elseif ($this->validate()) {
        Yii::$app->mailer->compose()
                ->setTo([
                           '[email protected]'
                           
                        ])
                ->setFrom([$this->email => $this->name])
                ->setSubject('Заполнена форма на сайте Голден-Строй')
                //->setTextBody($this->telef,$this->body)
                ->setHtmlBody('
                    <p>ФИО Заказчика: '.$this->name.'</p>
                    <p>E-mail: '.$this->email.' </p>
                    <p>Телефон: '.$this->telef.' </p>
                    <p>Сообщение: '.$this->body.' </p>
                        <hr/> 
                              ')
                ->send();  
                return true;
         }
        return false;
    }
}

Answer the question

In order to leave comments, you need to log in

[[+comments_count]] answer(s)
M
Maxim Timofeev, 2017-12-19
@webinar

1. beforeSubmit fires only after successful validation. Details about events in activeForm can be found here:
https://github.com/yiisoft/yii2/blob/master/framew...
2. check if the selector works, because, for example, if you already have a form with the same id or it is inserted into the body by a script, then the selector just does not work, not the event. In any case, it's better like this:

$js = <<<JS
 $('body').on('beforeSubmit','#contact-form',function(e){
 alert('Работает!');
 return false;
 });
JS;

3. there is also ajax validation out of the box, and therefore this is the ajax sending.
www.yiiframework.com/doc-2.0/yii-widgets-activefor...
4. possible via pjax, but I think option 3 is better

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question