Проверка jquery не работает для загруженного ajax содержимого модального диалогового окна начальной загрузки

Я использую начальную загрузку с Zend 2. Содержимое модального окна извлекается через вызов ajax. Но проверка вообще не работает, она отправляется без проверки какого-либо поля:

Вот где модальная загрузка:

<div class="modal fade" id="themesModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">

        </div>
    </div>
</div>

Вот модальное содержимое:

<div class="modal-body">
    <div id="themesbox">
        <div class="panel panel-info">

            <div class="panel-heading">
                <div class="panel-title">title</div>
            </div>

            <div style="padding-top: 30px" class="panel-body">
                           <?php
                                $form = $this->form;
                                $form->setAttribute('action', $this->url('user/default', array('controller' => 'users', 'action' => 'create')));
                                $form->prepare();
                                echo $this->form()->openTag($form);
                                ?>

                                <div id="mydiv"
                    style="display: none" class="alert alert-danger">
                    <p>Error:</p>
                    <span></span>
                </div>


                <div class="form-group">
                    <label for="name" class="col-md-3 control-label">user</label>
                    <div class="col-md-9">
                                        <?php echo $this->formElement($form->get('name'));?>
                                    </div>
                </div>

                <div class="form-group">
                    <label for="description" class="col-md-3 control-label">password</label>
                    <div class="col-md-9">

                                        <?php echo $this->formElement($form->get('password'));?>
                                    </div>
                </div>


                <div style="margin-top: 10px" class="form-group">
                    <!-- Button -->
                    <div class="col-sm-12 controls">
                    <?php echo $this->formSubmit($form->get('submit'));?>
                    <button id="cancel" class="btn btn-success" data-dismiss="modal">Cancel</button>
                    </div>
                </div>
                    <?php echo $this->form()->closeTag();?>  
            </div>
            <!-- /.panel-body -->
        </div>
        <!-- /. panel panel-info -->
    </div>
</div>

Вот код проверки jquery:

 $('.form-validation').each(function () {
     $(this).validate({


    errorElement: "span",
    errorClass: "help-block",   

    highlight: function(element) {
        $(element).closest('.control-group').removeClass('success').addClass('error');
        $(element).attr('style', "border-radius: 5px; border:#FF0000 1px solid;");
    },
    unhighlight: function(element) {
        $(element).addClass('valid').closest('.control-group').removeClass('error').addClass('success');
        $(element).attr('style', "border-radius: 4px; border:1px solid #ccc;");
    },
    errorPlacement: function (error, element) {
        $(error).attr('style', "color: #FF0000;");
        if ( element.prop('type') === 'checkbox') {
            error.insertAfter(element.parent());
        } else {
            error.insertAfter(element);
        }
    }

  });
 });

А вот и код формы:

 $this->add(array(
            'name' => 'name',

            'attributes' => array(
                'type'  => 'text',
                'id' => 'username',
                'class'  => 'form-control',
                'required'  => 'true',
                'minlength'  => '8',
                'maxlength'  => '20',
            ),
            'options' => array(
                'label' => 'name',
            ),
        ));

        $this->add(array(
            'name' => 'description',

            'attributes' => array(
                'type'  => 'password',
                'id' => 'password',
                'class'  => 'form-control',
                'required'  => 'true',
                'minlength'  => '8',
                'maxlength'  => '20',
            ),
            'options' => array(
                'label' => 'Password',
            ),
        ));

person GingerHead    schedule 21.04.2014    source источник
comment
Вместо того, чтобы показывать код Zend, покажите соответствующую HTML-разметку, как ее видит браузер.   -  person Sparky    schedule 21.04.2014
comment
@Sparky Я могу js-скрипт, который содержит приведенный выше js-код, включенный в html   -  person GingerHead    schedule 21.04.2014
comment
Отображение соответствующего HTML доказывает, что разметка подходит для JavaScript. Как еще мы должны определить, почему ваш скрипт jQuery Validate не работает?   -  person Sparky    schedule 21.04.2014
comment
@Спарки, пожалуйста, посмотри на мой ответ   -  person GingerHead    schedule 23.04.2014


Ответы (2)


У меня это работает, используя другой метод.

Вместо того, чтобы пытаться выполнить собственную проверку на стороне клиента (добавляя HTML-код ошибки и т. д.), вы должны отправить форму через AJAX и позволить ZF2 вернуть JsonModel с разметкой формы.

Если вы используете правильные помощники представления (в частности, FormRow), он будет правильно отображать ошибки формы.

Например

class FooController extends AbstractActionController
{

   public function createAction()
   {
     $request = $this->getRequest();
     $service = $this->getServiceLocator()->get('FooService'); 
     $form    = $service->getFooCreateForm(); // Zend\Form

     if ($request->isPost()) {
        $form->setData($request->getPost());

        if ($form->isValid()) {

            $foo = $service->create($form->getData());

            if ($foo instanceof Foo)
                // redirect to success page
            } else {
                $this->flashMessenger()->addErrorMessage('Error!');
            }
            return $this->redirect()->toRoute('foo', array('action' => 'index'));

        } else if ($request->isXmlHttpRequest()) {

            $renderer = $this->getServiceLocator()->get('viewrenderer');
            $formView = new ViewModel(compact('form')); // add the form to the view
            $formView->setTemplate('foo-module/foo/form');

            return new JsonModel(array(
                'success' => false, // Flag to keep modal open
                'content' => $renderer->render($formView), // The "content" being the form HTML
                'message' => 'Please check all form fields have been completed successfully',
            ));
        }
     }
     return new ViewModel(compact('form'));
   }

}

form.phtml

<?php
  echo $this->form($this->form);

create.phtml

//...modal html
<div class="modal-body">
    <?php echo $this->partial('form.phtml', compact('form')); ?>
</div>
//... modal html

И вы также хотели бы:

  • Удалите все кнопки из форм ZF2 (поскольку модальное уже имеет две)
  • Добавьте прослушиватель событий JS к модальной кнопке отправки, и AJAX отправит содержимое формы в createAction
  • Если результат вызова success == true, закройте модальное окно.
  • Если результат равен success == false, у вас будет переменная content, которая затем может заменить существующий модальный контент с помощью $('.modal-content').html(result.content). Это будет включать проверенный HTML-код формы (включая все сгенерированные ошибки, просмотренные помощниками вида формы).
person AlexP    schedule 21.04.2014
comment
Хотя хорошая идея всегда иметь проверку на стороне сервера, в этом случае OP спрашивает о проверке на стороне клиента. Обычно используются оба; на стороне клиента для лучшего взаимодействия с пользователем и на стороне сервера в случае сбоя первого. - person Sparky; 21.04.2014
comment
@Sparky Лучший опыт, о котором вы говорите, - это избегать обновления страницы, верно? Этот подход отправляет форму через AJAX и создает HTML с помощью помощников представления формы; Нет перезагрузки страницы; все, что вам нужно сделать, это заменить содержимое формы ответом на вызов AJAX. На мой взгляд, это лучше, чем дублирование, возможно, сложной серверной части проверки (где вам нужно добавить HTML-контент через javascript). Это было бы трудно поддерживать и расширять, например, если бы вы добавили поле в форму. - person AlexP; 21.04.2014
comment
Моя главная мысль заключается в том, что ваше решение не касается конкретно вопроса ОП. - person Sparky; 21.04.2014

На самом деле все механизмы проверки на стороне сервера были на месте и работали отлично.

Мне требовалась проверка на стороне клиента через jquery.

Поскольку содержимое модального диалогового окна Bootstrap загружается из ajax, оно не учитывало окружающий контекст, как обычно, мне нужно было вставить код jquery в ajax-контенте.

ZF2 не позволяет вставлять код js в свои файлы представления.

Поэтому я сделал следующее, вставив следующую строку в содержимое ajax:

 <?php echo $this->inlineScript()->appendFile($this->basePath() . '/js/custom.js')?>
person GingerHead    schedule 21.04.2014