2012-04-26 3 views
4

У меня есть базовая форма ajax на моем сайте, использующая Js-помощник, она отлично работает, но когда есть ошибки проверки, обратный вызов обновления дублирует всю страницу внутри моего div.CakePHP ajax form update duplicating page

Успех ДИВ:

<div id="success"></div> 

кнопку Отправить:

echo $this->Js->submit('Send', array(
    'before'=>$this->Js->get('#sending')->effect('fadeIn'), 
    'success'=>$this->Js->get('#sending')->effect('fadeOut'), 
    'update'=>'#success', 
    'class'=>'btn btn-primary' 
)); 

Javascript:

$(document).ready(function(){ 

    $('#postkey, #gender, #hair, #location, #message').blur(function(){ 
     $.post(
      '/Cake_ajax/Posts/validate_form', 
      { field: $(this).attr('id'), value: $(this).val() } 
      //handleNameValidation 
     ); 
    }); 

}); 

Validate функция формы в мой контроллер:

public function validate_form(){ 
    if($this->RequestHandler->isAjax()){ 
     $this->request->data['Post'][$this->request['data']['field']] = $this->request['data']['value']; 
     $this->Post->set($this->request->data); 
     if($this->Post->validates()){ 
      $this->autorender = FALSE; // don't render a view 
      $this->set('error',''); 
     }else{ 
      $this->layout ="ajax"; 
      $this->autoRender = FALSE; 
      $error = $this->validateErrors($this->Post); 
      $this->set('error',$this->Post->validationErrors[$this->request['data']['field']][0]); 
     } 
    } 
} 

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

спасибо.

+0

Если это прямая копия, вы пытались изменить строку на '$ this-> autoRender = false' (с капиталом R)? Кроме того, какой макет используется по умолчанию? –

+0

Приветствия! Я искал решение той же проблемы, и ваш принятый ответ решил мою проблему. – Fr0zenFyr

+0

Такое большое чувство, когда у вас проблема с Google, и у кого-то была одна и она была решена :) Удачи вам в вашем проекте. –

ответ

4

Я только что протестировал ваше приложение, используя ваш zip-файл.

Что я наблюдал, так это то, что это не вся страница, которая помещается внутри вашего #success div, а только содержимое изображения Posts/add.ctp. Итак, в основном это означает, что RequestHandler выполняет свою работу правильно, то есть используемый макет - это макет 'ajax'. Чтобы избавиться от всего остального, что на странице add.ctp не должно содержаться ничего, кроме формы. В вашем случае Posts/add.ctp содержит ссылки для навигации, и поэтому они дублируются.

Сказали, что кнопка отправки в настоящее время получает содержимое Posts/add.ctp и вставляет его в ваш пустой #success div. Но вы никогда не удаляете форму, которая уже была на странице. Что вы можете сделать, это обновить содержимое div, которое содержит вашу первую форму или даже содержимое всего изображения Posts/add.ctp.

В вашем случае, просто обновляя #content вместо из #success DIV может быть может удовлетворить ваши потребности:

echo $this->Js->submit('Send', array(
    'before'=>$this->Js->get('#sending')->effect('fadeIn'), 
    'success'=>$this->Js->get('#sending')->effect('fadeOut'), 
    'update'=>'#content', 
    'class'=>'btn btn-primary', 
    'controller'=>'posts', 
    'action'=>'add' 
)); 
+0

Это отлично работает, спасибо. Как только я могу сделать успешное сообщение без его замены всей страницы add.ctp с помощью success.ctp? –

+0

Я сам не использую JsHelper, но предпочитаю писать свои собственные сценарии jQuery, чтобы иметь больше контроля над тем, что делает скрипт. Но в вашем случае, я думаю, что отличное представление от контроллера, как вы, это то, что нужно сделать. Если вопрос состоит в том, чтобы понять, как заставить меню не исчезать, ну, вы можете обновить форму (а не #content), но визуализировать в представлении только ту часть, которая вам нужна (форма, если у вас есть ошибка, или сообщение об успешном завершении). Но в этом случае не отображать меню, если запрос является вызовом Ajax. – nIcO

+0

Обратите внимание, что если вам нужно иметь меню действий или что-то еще в add.ctp, вы также можете добиться этого, отправив запрос Ajax другому действию, которое будет отображать форму в случае ошибки или сообщения об успешном завершении. – nIcO

0

в обработке запроса Ajax задает макет для ajax. Таким образом, сообщение об ошибке будет отображаться с помощью макета ajax, а не с макетом по умолчанию.

ОБНОВЛЕНО

public function validate_form(){ 
if($this->RequestHandler->isAjax()){ 
    $this->request->data['Post'][$this->request['data']['field']] = $this->request['data']['value']; 
    $this->Post->set($this->request->data); 
    if($this->Post->validates()){    
     $this->autoRender = FALSE; // don't render a view 
     $this->set('error',''); 
    }else{ 
     $this->layout ="ajax"; 
     $this->autoRender = FALSE; 
     $error = $this->validateErrors($this->Post); 
     $this->set('error',$this->Post->validationErrors[$this->request['data']['field']][0]); 
    } 
} 

}

+0

Эй, спасибо за ответ. К сожалению, это не устранило проблему. Это действительно начинает измельчать мои шестерни, ха-ха. –

+0

@Drawrdesign: Была ошибка, я должен был добавить настройки макета в части else. Обновленный код теперь попробуйте сейчас. – Saanch

+0

По-прежнему нет :(Могу ли я застегнуть все приложение, чтобы вы могли его посмотреть? Или замаскировать его или что-то еще? –

0

Убедитесь, что вы либо:

Использование компонента RequestHandler (предпочтительный):

class AppController { 

    var $compontents = array('RequestHandler'); 

} 

или вручную установить макет «ajax» в вашем действии:

$this->layout = "ajax" 

Обработчик запроса автоматически установит макет в ajax, когда он обнаружит запрос Ajax.

Макет ajax не возвращает ничего, кроме визуализированного представления.

+0

У меня уже был обработчик запроса в контроллере, и я попытался использовать макет ajax, но не кубик. –

0

Здравствуйте, во-первых, кажется, вы используете торт 2 LIB и используя 1.3 код, вероятно, будет работать, но является в устаревших деталях может быть проверка работы migration guide. Инструмент консоли также может обновить ваш код до 2.0/2.1.

Во-вторых, вы действительно хотите визуализировать представление и пустой макет? $ errors определяется в Views/Posts/validate_form.ctp. Вы устанавливаете $ errors, а затем не показываете представление. Удалите настройку автоматического рендеринга на false и поместите вверху вашего действия контроллера.

$this->layout = 'ajax'; 
Configure::write("debug",0); 

Какой-нибудь хороший?

1

Я столкнулся с той же проблемой. Хотя nIcO, кажется, дает решение, в моем случае это не помогло, потому что сообщение о достижении успеха Drawrdesign хочет, все еще не отображается.

Итак, я посмотрел ваш zip-файл и нашел решение. Существует два вызова ajax: 1) .blur и 2) .bind. 1) используется для проверки полей и передает данные через AJAX в функцию validate_form() PostsController. И 2) используется для наблюдения за событием клика кнопки отправки и отправки данных в функцию add() PostsController.

Эта проблема возникает при 2), поскольку вы нажимаете кнопку «Отправить». Итак, вы должны смотреть на функцию add() PostsController. В функции validate_form() 1) вы добавили строку:

$this->autoRender = FALSE; 

И это решение. Поскольку CakePHP автоматически отображает представление, вы не хотите, чтобы это произошло из-за AJAX. Таким образом, в случае 1) это сделано, следует добавить к функции Add() в случае 2), как это:

public function add() { 
// Ajax post 
if(!empty($this->request->data)) { 
    // ... 
    $this->autoRender = FALSE; // ** NEW LINE ** 
     if($this->Post->save($this->request->data)) { 
      // ...  
     } 
     // ... 
    } 
    // ... 
} 

Таким образом, это остановка (авто) оказание add.ctp в DIV = "# success", а ваши другие сообщения «отправка ..» и «succes.ctp» все еще отображаются.

PS. @Drawrdesign, неужели вы случайно следовали инструктивному видео andrewperk?

0
public function admin_edit_comment() { 
    $this->layout = 'ajax'; 
    $this->autoRender = false; 
    if ($this->request->is('ajax')) { 
     if ($this->FaComment->save($this->request->data, false)) { 
      $response['status'] = 'success'; 
      $response['action'] = 'edit_comment'; 
      $response['data'] = $this->request->data['FaComment']; 
      $response['message'] = __d('vanderdeals', 'Comment saved successfully'); 


    } else { 
      $response['status'] = 'error'; 
      $response['model'] = 'FaComment'; 
      $response['message'] = __d('vanderdeals', 'Internal server error occurred. Please try again later.'); 
     } 

     echo json_encode($response); 
    } 
}