2012-10-18 16 views
6

हमारे सिम्फनी 2 प्रोजेक्ट में हमारे पास एम्बेडेड रूपों के रूपों के लिए एक बहुत ही जटिल संरचना है .... अब हमें फ़ॉर्म के आउटपुट को एक विशिष्ट क्रम में लाने की आवश्यकता है।सिम्फनी 2 - फॉर्म फ़ील्ड को पुनर्व्यवस्थित करें

और यहां समस्या है: हम form_widget (फॉर्म) का उपयोग करते हैं और अब हम किसी विशेष फ़ील्ड को फ़ॉर्म के अंत में स्थानांतरित करने के लिए ऑब्जेक्ट (उदा। एनोटेशन के माध्यम से) या फॉर्मबिल्डर में समाधान ढूंढ रहे हैं। सिम्फोनी 1.4 में यह विजेट-movefield() फ़ंक्शन, मैं लगता है ...

Thx ... था

उत्तर

3

के क्षेत्रों "को पुन: व्यवस्थित" कोई ज़रूरत नहीं है। आपको बस प्रत्येक क्षेत्र के लिए form_label और/या form_widget पर कॉल करना है। आप का उपयोग मान लिया जाये कि Twig आप, उदाहरण के लिए, कर सकता है:

<div>{{ form_label(form.firstName) }}</div> 
<div>{{ form_widget(form.firstName) }}</div> 

<div>{{ form_label(form.lastName) }}</div> 
<div>{{ form_widget(form.lastName) }}</div> 
+0

धन्यवाद, लेकिन यह संभव नहीं है। हमारे पास एक बहुत जटिल संरचना है और form_widget (फॉर्म) फ़ंक्शन की आवश्यकता है, इसलिए हमें बैकएंड में ऐसा करना होगा! – snirgel

+0

क्या आपने वांछित क्रम में 'फॉर्मबिल्डर' उदाहरण में फ़ील्ड जोड़ने का प्रयास किया है? –

+0

Thats संभव नहीं है। हमारे पास निर्भरता, विरासत आदि के साथ लगभग 80 ऑब्जेक्ट-प्रकार हैं, इसलिए हम हाथ से ऐसी चीजों का उपयोग नहीं कर सकते हैं .... – snirgel

0

मैं समझता हूँ के रूप में, आप अंतिम टेम्पलेट में केवल form_widget (फार्म) उपयोग करना चाहते हैं।

Let मान हम दो विरासत में मिला मॉडल (ModelA, ModelB) और फार्म प्रकार उनके लिए (ModelAType, ModelBType)

class ModelA { 
    private $A; 
    private $B; 

    // Getters and setters 
} 

class ModelB extends ModelA { 
    private $C; 

    // Getters and setters 
} 

/** 
* @DI\Service(id = "form.type.modelA") 
* @DI\Tag("form.type", attributes={ "alias":"model_a_type" }) 
*/ 
class FormAType extends AbstractType { 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
    $builder 
     ->add('A') 
     ->add('B') 
    ; 
    } 

    // getName and so on 
} 

/** 
* @DI\Service(id = "form.type.modelA") 
* @DI\Tag("form.type", attributes={ "alias":"model_b_type" }) 
*/ 
class FormAType extends AbstractType { 
    public function getParent() { 
    return "model_a_type"; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
    $builder 
     ->add('C') 
    ; 
    } 

    // getName and so on 
} 

आप formB प्रस्तुत करना हैं, तो आप ए, बी, सी आदेश मिल जाएगा है, लेकिन आप ए, सी, बी चाहते हैं। इसे पूरा करने के लिए, फॉर्म टेम्पलेट बनाएं और ऐप में संदर्भ जोड़ें। कॉन्फ़िगरेशन फ़ाइल:

#app/config/config.yml 
twig: 
    .... 
    form: 
     resources: 
      - YourAppBundle:Form:fields.html.twig 


{# src/YourAppBundle/Resources/views/Form/fields.html.twig #} 
{% block model_a_type_widget %} 
    {{ form_widget(form.A) }} 
    {{ form_widget(form.B) }} 
{% endblock model_a_type_widget %} 

{% block model_b_type_widget %} 
    {{ form_widget(form.A) }} 
    {{ form_widget(form.C) }} 

    {{ block('model_a_type_widget') }} 
{% endblock model_b_type_widget %} 

अब, जब आप फॉर्म बी प्रस्तुत करते हैं, तो आपको वांछित क्रम दिखाई देगा और कोड संरचित रखा जाएगा। ऐसा इसलिए होता है क्योंकि प्रत्येक विजेट केवल एक बार प्रस्तुत किया जाता है, इसलिए यदि आप पैरेंट ब्लॉक को कॉल करने से पहले इसे प्रस्तुत करते हैं, तो आप उनका ऑर्डर बदल देंगे।

9

आप फिर से आदेश कर सकते हैं इस बंडल का उपयोग कर खेतों: https://github.com/egeloen/IvoryOrderedFormBundle

यह आप इस तरह काम करने के लिए अनुमति देता है: यह कोर में जा रहा था

$builder 
->add('g', 'text', array('position' => 'last')) 
->add('a', 'text', array('position' => 'first')) 
->add('c', 'text') 
->add('f', 'text') 
->add('e', 'text', array('position' => array('before' => 'f'))) 
->add('d', 'text', array('position' => array('after' => 'c'))) 
->add('b', 'text', array('position' => 'first')); 

, लेकिन अस्वीकार कर दिया था और बाहर निकाला एक बंडल में।

3

फॉर्म तत्वों के आदेश के साथ आज भी एक ही समस्या थी।

एक विशेषता है कि finishView विधि ओवरराइड और एक FormView के बच्चों संपत्ति में आइटम को पुन: व्यवस्थित होगा साथ समाप्त हुई:

trait OrderedTrait 
{ 
    abstract function getFieldsOrder(); 

    public function finishView(FormView $view, FormInterface $form, array $options) 
    { 
     /** @var FormView[] $fields */ 
     $fields = []; 
     foreach ($this->getFieldsOrder() as $field) { 
      if ($view->offsetExists($field)) { 
       $fields[$field] = $view->offsetGet($field); 
       $view->offsetUnset($field); 
      } 
     } 

     $view->children = $fields + $view->children; 

     parent::finishView($view, $form, $options); 
    } 
} 

फिर प्रकार में getFieldsOrder तरीका लागू:

use OrderedTrait; 

function getFieldsOrder() 
{ 
    return [ 
     'first', 
     'second', 
     'next', 
     'etc.', 
    ]; 
} 
+1

यह एक अच्छा, साफ समाधान है! धन्यवाद! – virtualize

+0

getFieldsOrder द्वारा लौटाई गई फ़ील्ड सूची में वजन जोड़ने के लिए कोड के इस टुकड़े को विस्तारित करना आसान है, अगर किसी को इसकी आवश्यकता है, तो मुझसे संपर्क करने में संकोच न करें। –

3
यहाँ

है समाधान मैं साथ आया था।

मैंने एक वर्ग बनाया जो मेरे प्रकार का विस्तार करता है।

namespace WF\CORE\CoreBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class WfBaseForm extends AbstractType 
{ 

    protected function useFields(FormBuilderInterface $builder, $fields) 
    { 
     foreach ($builder->all() as $field) { 

      if (!in_array($field->getName(), $fields)) 
       $builder->remove($field->getName()); 
     } 
    } 


    public function reorder(FormBuilderInterface $builder, $keys = array()) 
    { 
     $fields   = $builder->all(); 
     $ordered_fields = array_merge(array_flip($keys), $fields); 
     $this->useFields($builder, array()); 

     foreach($ordered_fields as $field) 
      $builder->add($field); 

    } 

    public function getName() 
    { 
     return 'base'; 
    } 
} 

फिर आप इसे अपने विरासत में कक्षाओं में उपयोग कर सकते हैं।

class AddressType extends WfBaseForm 
{ 
public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     // I add as many fields as I need 
     $builder->add('…'); 
} 

इस वर्ग के ऊपर

class ModifyAddressType extends BaseType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     parent::buildForm($builder, $options); 

     $builder->add('title', 'text', array('constraints' => array(new NotBlank()))); 

     $this->reorder($builder, array('title', 'firstname', 'lastname')); 
    } 
} 
0

एक फैली हुई है आप इसे अपने नियंत्रक में कर सकते हैं इससे पहले कि आप टेम्पलेट प्रस्तुत करना:

$form = ... 

$view = $form->createView(); 

// Perform standard array operations to reorder: `$view->children` 
// Here's a very simple example: 

$firstField = $view->children['firstField']; 
unset($view->children['firstField']); 
$view->children['firstField'] = $firstField; 

return array('form' => $view); 

रूप में अच्छी तरह uasort काम करता है, लेकिन usort एक बनाता है गैर-सहयोगी सरणी जो बाद में प्रस्तुत करने वाले फॉर्म को तोड़ देगी।

0
{{ form_start(form) }} 

    <div>{{ form_label(form.title) }}</div> 
    <div>{{ form_widget(form.title,{'id': 'blog_title'})}}</div> 

    <div>{{ form_label(form.tag) }}</div> 
    <div>{{ form_widget(form.tag,{'id': 'blog_tag'})}}</div> 

    <div>{{ form_label(form.category) }}</div> 
    <div>{{ form_widget(form.category,{'id': 'blog_category'})}}</div> 

    <div>{{ form_label(form.image) }}</div> 
    <div>{{ form_widget(form.image,{'id': 'blog_image'})}}</div> 

    <div>{{ form_label(form.body) }}</div> 
    <div>{{ form_widget(form.body,{'id': 'editor'})}}</div> 

    <input type="submit" class="btn btn-success" value="Create" /> 
{{ form_end(form) }} 
संबंधित मुद्दे