Symfony: изменить ответ после добавления записи - PullRequest
0 голосов
/ 07 января 2012

Я открываю форму через ajax (используя jquery), и я хочу сохранить ее без перезагрузки всей страницы. Где мне нужно изменить код, чтобы получить текстовый ответ (например, «ок!») Вместо перенаправления на страницу редактирования?

это мой JS:

$("#newcatlink").click(function() {
    $.ajax({
    'url': "category/new",
    'success': function(data, textStatus, jqXHR) {
            $("#mdialog").html(data);
            $("#_form_jqhide").hide();
            $("#mdialog").dialog({
                modal: true,
                width: 500,
                resizable: false,
                buttons: {
                    Save: function() {
                        $.ajax({
                            'type': 'POST', 
                            'url': 'category/create', 
                            'data': $("#categoryform").serialize(),
                            'success': function(data, textStatus, jqXHR) {
                                alert(data);
                            }
                        });
                    },
                    Cancel: function() {
                        $(this).dialog("close");
                    }
                }
            });
        }
    });
});

Я изменил действие processForm в actions.class.php следующим образом:

...
if ($form->isValid())
{
  $Category = $form->save();

        if($request->isXmlHttpRequest()) {
            return $this->renderText("ok!");
        } else {
            $this->redirect('category/edit?id='.$Category->getId());
        }
}

но это ничего не изменило. Как это сделать?

редактировать 01.08.12:

Я внес изменения в свой код в соответствии с ответами blowski и sakfa, но у меня возникает другая проблема: как отследить ошибки формы? Я добавил в processForm еще, если и он работает, как ожидалось, но я не могу получить сообщение об ошибке / код / ​​что-либо обратно, только факт, что ошибка существует.

Вот код: http://pastebin.com/ppbPM88G и это ответ сервера после отправки формы с одним пустым обязательным полем:

{ "haserrors": истинная "ошибка": []} * * одна тысяча двадцать два

Ответы [ 2 ]

2 голосов
/ 08 января 2012

Основано на разговорах здесь:

вы поместили return $this->renderText("ok!") в метод processForm, но не в действие (например, executeCreate). Переместите строку возврата и проверку состояния в метод executeXXX.

редактировать 2012-01-08

Я удалил свои старые фрагменты кода, потому что они больше не нужны, поскольку вы отредактировали свой оригинальный код, эффективно включив в него мои изменения.

относительно вашего нового вопроса:

в основном symfony1 api отстой при работе с формами, поэтому у вас так много проблем.

Прежде всего, вам нужно знать, что этот API не предназначен для работы с отправкой формы AJAX, когда дело доходит до проверки - это потому, что sfForm может проверять себя, может хранить свои ошибки внутри и может отображать их как HTML - но есть нет подпрограммы (насколько я знаю) для возврата ошибок в некотором сериализуемом формате (например, массив пар fieldname => errorMessage, которые хорошо кодируются json_encodes).

Начну с вашего кода, что бы я сделал на вашем месте:

Во-первых: создайте отдельное действие только для обработки представления ajax, при условии, что вы выполняете POST-запрос

public function exucuteAjaxFormSubmission(sfWebRequest $request)
{
    //this action handles ONLY ajax so we can safely set appropriate headers
    $this->getResponse()->setContentType('text/json');

    $form = new form();
    $form->bind($request->getPostParameters());

    if ($form->isValid()) {
        //do your logic for positive form submission, i.e. create or update record in db
        return json_encode('ok'); //notify client that everything went ok
    } else {
        return $this->doSomeMagicToGetFormErrorsAsAnJsonEncodedArray();
    }
}

Теперь перейдем к части doSomeMagicToGetFormErrorsAsAnJsonEncodedArray: вы хотите получить ошибки формы в формате json. Для этого мы добавим простой метод в ваш класс формы (так как это ваш «интерфейс» к логике валидации).

Немного теории: внутренне sfForm хранит ошибки проверки в структуре, называемой sfValidatorErrorSchema. sfValidatorErrorSchema хранит ошибки в двух списках - namedErrors и globalErrors. Именованные ошибки - это те, которые вызываются для «валидаторов поля» (т. Е. Обязательный валидатор строки в поле name. Глобальные ошибки - это те, которые генерируются для всей формы (т. Е. Глобальные postValidators). Каждая ошибка - это объект sfValidatorError, выданный ошибочным валидатором.

предупреждение: на самом деле эта структура является рекурсивной, но вы увидите ее, только если будете использовать встроенные формы , в этом случае необходимо изменить следующую функцию, чтобы включить ситуацию, в которой sfValidatorErrorSchema может содержать другую sfValidatorErrorSchema, а не sfValidatorError. Надеюсь, вы не используете встроенные формы, потому что это в Symfony отстой даже больше, чем API простых форм.

Но достаточно разговоров, если вам нужен код, скопируйте и вставьте эти методы в класс формы:

class myForm extends sfForm { 
    (...)

    /** a helper method to convert error schema to an array */
    public function getSerializableErrors()
    {
        $result = array();
        foreach ($this->getErrorSchema()->getNamedErrors() as $fieldName => $error) {
            $result[$fieldName] = $error->getMessage();
        }
        foreach ($this->getErrorSchema()->getGlobalErrors() as $error) {
            $result['_globals'][] = $error->getMessage();
        }

        return $result;
    }

    /** screw array, just give me ready to send json! */
    public function getJsonEncodedErrors()
    {
        return json_encode($this->getSerializableErrors());
    }
}

Теперь просто измените doSomeMagicToGetFormErrorsAsAnJsonEncodedArray на getJsonEncodedErros, и вы закончили с отправкой базовой формы ajax с проверкой - у вас должно быть достаточно знаний для правильной реализации вашей логики. Я проверил это на текущей версии Symfony 1.4, поэтому, если что-то пойдет не так, это может быть проблемой старой версии sf (вы не сказали мне, какую версию вы используете)

1 голос
/ 08 января 2012

Основываясь на нашем разговоре, я вижу, что происходит. Если я понял ваши комментарии, это не перенаправление всей страницы, это просто повторная визуализация исходной формы внутри диалогового окна?

После того, как пользователь отправит форму, если она действительна, то она перенаправляет. Однако, поскольку вы обходите перенаправление, он вместо этого достигает бита кода $this->setTemplate('new'), поэтому снова отображается форма new, заполненная данными только что заполненной формы.

Чтобы обойти это, используйте что-то вроде этого в действии создания:

if($request->isXmlHttpRequest()) {
  $this->renderText(json_encode(array('valid' => $form->isValid())));
} else {
  $this->setTemplate('new');
}

Вы также захотите изменить свой Ajax-запрос, указав, что он ожидает ответа JSON. Затем, если форма была действительной, закройте диалоговое окно (или все, что вы хотите сделать после сохранения).

...