Не работает JS в Yii2 - как поправить?
Есть код в _form.php вместе с целевой кнопкой 'submitButton' которую необходимо сделать неактивной, пока пусты поля формы. JS пока написан для одного поля 'first_name':
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model app\models\Contact */
/* @var $form yii\widgets\ActiveForm */
$myJs = <<<JS
$('#first_name').change(function() {
$('#my_button').removeAttr('disabled');
})
JS;
$this->registerJs($myJs);
?>
<div class="contact-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'first_name')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Имя <span class="note">* поле обязательно к заполнению</span>') ?>
<?= $form->field($model, 'last_name')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Фамилия <span class="note">* поле обязательно к заполнению</span>') ?>
<?= $form->field($model, 'middle_name')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Отчество') ?>
<?= $form->field($model, 'internal_phone')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Вн.телефон <span class="note">* поле обязательно к заполнению</span>') ?>
<?= $form->field($model, 'mobile_phone')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Моб.телефон <span class="note">* поле обязательно к заполнению</span>') ?>
<?= $form->field($model, 'email_address')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Email адрес <span class="note">* поле обязательно к заполнению</span>') ?>
<div class="form-group">
<?= Html::submitButton('Добавить', ['class' => 'btn btn-success', 'name' => 'test-button',
'id' => 'my_button', 'disabled' => 'disabled', /*'onclick' => '$("#my_button").attr("disabled", "disabled")'*/]) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
assets/AppAsset.php:
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace app\assets;
use yii\web\AssetBundle;
/**
* Main application asset bundle.
*
* @author Qiang Xue <[email protected]>
* @since 2.0
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap4\BootstrapAsset',
];
// public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
}
- Как всегда - кто виноват и что делать (в приложении к коду)?
- Почему при варианте написания, указанном ниже, не опознается jQuery:
Ошибка: syntax error, unexpected token "(", expecting variable or "{" or "$"
$this->registerJs(
$('#first_name').change(function() {
$('#my_button').removeAttr('disabled');
})
);
Ответы (3 шт):
Всё, что написано в registerJs должно быть в виде строки!
https://www.yiiframework.com/doc/api/2.0/yii-web-view#registerJs()-detail
public void registerJs ( $js, $position = self::POS_READY, $key = null )
$js - string - The JS code block to be registered
^---------
Потому что туда НЕ принимается какой-то callback.
Как следствие можно написать примерно так:
$js = <<<JS
$('#first_name').change(function() {
$('#my_button').removeAttr('disabled');
});
JS;
$this->registerJs($js);
а вообще, не проще ли испльзовать сразу теги <script> или ассеты?
кто виноват ?
Виноваты вы, потому что не читаете доки! :))
Почему при таком подходе всё равно не работает JS
Потому что на страницы нет элемента с id first_name
Если разработчик не указывает свой id, то ActiveForm генерирует его автоматически по формуле strtolower(имя модели)-strtolower(имя атрибута)
Например имя модели TestLogicAction а имя атрибута func_type, то будет сгенерирован идентификатор testlogicaction-func_type. Имя модели всё слитно.
в html-коде браузера нашел id элемента, сформированный Yii2 (в моем случае 'contact-first_name' - где 'contact', очевидно, название модели yii-проекта) и вставил его в код JS. все заработало:
$myJs = <<<JS
$('#contact-first_name').change(function() {
$('#my_button').removeAttr('disabled');
})
JS;
за подсказку в выявлении ошибки спасибо @Алексей Шиманский
На сколько помню тебе нужно было на несколько полей сделать проверку.
- Выбираешь поля устанавливая класс inputNotNull:
<?= $form->field($model, 'first_name')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Имя <span class="note">* поле обязательно к заполнению</span>') ?>
<?= $form->field($model, 'last_name')->textInput(['maxlength' => true, 'class' => 'form-control inputNotNull'])->label('Фамилия <span class="note">* поле обязательно к заполнению</span>') ?>
- регистрируешь скрипт (лучше отдельным файлом, что бы можно было использовать в других местах. Но просто текстом тоже нормально:
function verifyNotNull() //функция проверки на пустоту
{
if ($(this).val().trim()){
$("#disabledBtn").prop('disabled', false);
}else{
$("#disabledBtn").prop('disabled', true);
}
}
$(".posts-form").on("change", "input.inputNotNull", function (){ //накидываем обработчик событий на класс inputNotNull
$('.inputNotNull').each(
verifyNotNull
); // проверяем все инпуты в posts-form с классом inputNotNull на пустоту
});
Проверен. Работает.