Spacemans
@Spacemans
web мастер

Yii2 как сделать отправку формы с использованием ajax?

Здравствуйте!
Никак не получается сделать отправку формы без перезагрузки страницы. Подскажите пожалуйста в чём может быть проблема:
Пытался делать по https://webformyself.com/yii2-ajax/ Но не работает даже $('form').on('beforeSubmit', function()
Всё равно происходит перезагрузка страницы. Наверное неправильно написан контроллер?

Сама форма:

<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([
                           'info@gs.ru'
                           
                        ])

                ->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([
                           'info@gs.ru'
                           
                        ])
                ->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;
    }
}
  • Вопрос задан
  • 2904 просмотра
Пригласить эксперта
Ответы на вопрос 2
Justique
@Justique
Используйте Pjax
Ответ написан
webinar
@webinar Куратор тега Yii
Учим yii: https://youtu.be/-WRMlGHLgRg
1. beforeSubmit срабатывает только после успешной валидации. Подробно про events в activeForm можно посмотреть тут:
https://github.com/yiisoft/yii2/blob/master/framew...
2. проверяйте срабатывает ли селектор, так как, например, если у Вас уже есть форма с таким id или она вставлена в body скриптом, то просто не работает селектор, а не событие. В любом случае лучше так:
$js = <<<JS
 $('body').on('beforeSubmit','#contact-form',function(e){
 alert('Работает!');
 return false;
 });
JS;

3. есть же из коробки ajax валидация, а следовательно это и есть отправка ajax.
www.yiiframework.com/doc-2.0/yii-widgets-activefor...
4. можно через pjax, но мне кажется вариант 3 лучше
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы