2017-02-14 18 views
0

Я новичок в Symfony, PHP и Javascript. Я борюсь с формой дерева Javascript на основе Fancytree. Благодаря форуму я сделал все, чтобы работать с POSTing обратно данные формы в контроллер, обрабатывая запрос и перенаправляя страницу успеха. Проблема в том, что страница успеха никогда не отображается. Ни IE, ни Firefox отладчики не показывают ошибок. Я больше не продвигаюсь, я застрял.Javascript создает POST, контроллер Symfony обрабатывает его и перенаправляет, но новая страница не отображается

Вот мой контроллер:

namespace Solar\DataBundle\Controller; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Config\Definition\Exception\Exception; 

class DefaultController extends Controller 
{ 

    /** 
    * Test data sent to Twig and javascript tree 
    * 
    * @Route("/form_tree_demo", name="form_tree_demo") 
    * @Method({"GET", "POST"}) 
    */ 
    public function formTreeDemoAction(Request $request) 
    { 
     $test = 'Test string'; 
     $testArray = 
     array(
      array(
       'name'=> '1', 
       'title' => '1', 
       'children' => 
       array(
        array('name' => '1.1', 
         'title' => '1.1' 
        ), 
        array('name' => '1.2', 
         'title' => '1.2' 
        ) 
       ) 
      ), 
      array(
       'name'=> '2', 
       'title' => '2', 
       'children' => 
       array(
        array('name' => '2.1', 
         'title' => '2.1' 
        ), 
        array('name' => '2.2', 
         'title' => '2.2' 
        ) 
       ) 
      ) 
     ); 
     $form = $this->createFormBuilder() 
      ->add('save', SubmitType::class, array('label' => 'Post to the controller')) 
      ->getForm(); 

     $form->handleRequest($request); 

     if ($form->isSubmitted() && $form->isValid()) { 

      //for debug 
      //throw new Exception(var_dump($form->getData())); 

      return $this->redirectToRoute('success', array('message' => 'Post handled')); 
     } 

     return $this->render('formtreedemo.html.twig', 
      array(
       'tree_form' => $form->createView(), 
       'test_array' => json_encode($testArray) 
      ) 
     ); 
    } 

    /** 
    * @Route("/success", name="success") 
    */ 
    public function successAction() 
    { 
     return $this->render('success.html.twig'); 
    } 
} 

Вот Twig форма:

{% extends 'base.html.twig' %} 

{% block body %} 
    <h1>A demo form with Fancytree</h1> 
    {{ form_start(tree_form) }} 
     <div id="tree" name="selNodes"> 
     </div> 
     Additional data: <input type="text" name="otherFormData" /><br><br> 
    {{ form_end(tree_form) }} 
{% endblock %} 

{% block javascripts %} 
    <script type="text/javascript" src="{{asset('assets/vendor/jquery/dist/jquery.js')}}"></script> 
    <script type="text/javascript" src="{{asset('assets/vendor/jquery-ui/jquery-ui.js')}}"></script> 
    <script type="text/javascript" src="{{asset('assets/vendor/bootstrap/dist/js/bootstrap.js')}}"></script> 
    <link rel="stylesheet" type="text/css" id="skinSheet" href="{{asset('assets/vendor/fancytree/src/skin-lion/ui.fancytree.css')}}" /> 
    <script type="text/javascript" src="{{asset('assets/vendor/fancytree/src/jquery.fancytree.js')}}"></script> 

    <script type="text/javascript"> 
     $(function(){ 
      $("#tree").fancytree({ 
       checkbox: true, 
       selectMode: 2, 
       source:$.parseJSON('{{test_array}}'.replace(/&quot;/ig,'"')) 
      }); 
      $("form").submit(function() { 
       $("#tree").fancytree("getTree").generateFormElements(); 
       jQuery.ajax({ 
        type: "POST", 
        url: "{{path("form_tree_demo")}}", 
        data: formData 
       }); 
       return false; 
      }); 
     }); 
    </script> 
{% endblock %} 

И, наконец, вот IE консоль дамп:

URL               Method Result Type      Initiateur 
/web/app_dev.php/form_tree_demo        GET 200 text/html     actualiser 
/web/assets/vendor/bootstrap/dist/css/bootstrap.css   GET 200 text/css     <link rel="stylesheet"> 
/web/assets/vendor/bootstrap/dist/css/bootstrap-theme.css  GET 200 text/css     <link rel="stylesheet"> 
/web/assets/vendor/jquery/dist/jquery.js      GET 200 application/javascript <script> 
/web/assets/vendor/jquery-ui/jquery-ui.js      GET 200 application/javascript <script> 
/web/assets/vendor/bootstrap/dist/js/bootstrap.js    GET 200 application/javascript <script> 
/web/assets/vendor/fancytree/src/skin-lion/ui.fancytree.css GET 200 text/css     <link rel="stylesheet"> 
/web/assets/vendor/fancytree/src/jquery.fancytree.js   GET 200 application/javascript <script> 
/web/app_dev.php/_wdt/115370         GET 200 text/html     XMLHttpRequest 
/web/assets/vendor/fancytree/src/skin-lion/icons.gif   GET 200 image/gif     background-image 
/web/app_dev.php/form_tree_demo        POST 302 text/html     XMLHttpRequest 
/web/app_dev.php/success?message=Post%20handled    GET 200 text/html     XMLHttpRequest 

Дополнительная информация: Я запустить Symfony 3.2 под серверами Windows 8, OpenSuse и Ubuntu VM. Те же результаты повсюду. Те же результаты с устаревшим Dynatree.

Добрая помощь будет оценена.

Jean-Michel

ответ

0

Вы должны обрабатывать успех/провал Аякса и загрузить новую страницу оттуда. В настоящее время вы возвращаете html вызова перенаправления в ваш контроллер, и ваша функция javascript никак не обрабатывает возврат и просто возвращает false.

Если форма в вашем контроллере реагирует только на ajax, то при успешном прохождении обратно перенаправить URL-адрес, а затем получить javascript для выполнения перенаправления.

Если форма предназначена только для обработки вызова ajax, я лично создам маршрут/функцию для обработки именно этого.
Вот почему вы можете выполнить некоторые проверки (например, $request->isXmlHttpRequest()), чтобы гарантировать, что вызов происходит только от ajax.

E.g.

public function ajaxAction(Request $request) 
{ 
    if ($request->isXmlHttpRequest()) { 
     $form_element1 = $request->request->get('form_element1'); 
     $form_element2 = $request->request->get('form_element2'); 
     // do whatever 

     $data['success'] = true; 
     $data['url'] = $this->generateUrl('new_route');; 
     return new \Symfony\Component\HttpFoundation\JsonResponse($data); 
    } 
} 

Тогда ваш Javascript

<script type="text/javascript"> 
     $(function(){ 
      $("#tree").fancytree({ 
       checkbox: true, 
       selectMode: 2, 
       source:$.parseJSON('{{test_array}}'.replace(/&quot;/ig,'"')) 
      }); 
      $("form").submit(function(e) { 
       e.preventDefault(); 
       var formData = $("#tree").fancytree("getTree").generateFormElements(); 
       var jqxhr = $.ajax({ 
        type: "POST", 
        url: "{{path('ajax_action')}}", 
        data: formData 
       }) 
       .done(function(data) { 
        if (data.success === true) { 
         window.location.href = data.url; 
        } 
       }) 
       .fail(function(data) { 
        alert('error'); 
       }) 
       .always(function(data) { 

       }); 
       return false; 
      }); 
     }); 
</script> 
+0

Спасибо за помощь. Я попытался в контроллере: if ($ request-> isXmlHttpRequest()) { echo "isXmlHttpRequest"; } Он не возвращает. Предупреждение JS (ошибка) запускается. Браузер возвращает белую страницу с: {"success": true, "url": "\/solar \/web \ /app_dev.php \/success"}. –

+0

Кроме того, в PHP '$ form' пуст (data = null). –

+0

@jmichel_ как вы создаете свою формуДата в своем javascript? Кроме того, поскольку вы отправляете ajax, запускаются события формы symfony, поэтому форма пуста. Отделите сообщение ajax на свой собственный маршрут – Rooneyl