2015-08-17 4 views
5

सिम्फनी 2.7 से पहले, attrchoice फ़ील्ड के लिए मान केवल फ़ील्ड पर ही लागू होता है, यानी <select> तत्व प्रदान किया गया था। मैंने इस तत्व को कक्षाओं को स्टाइल करने के लिए इसे लागू करने के लिए इसका इस्तेमाल किया।मैं अपने पसंद क्षेत्र के सभी विकल्पों में एटीआर लगाने से कैसे बच सकता हूं?

सिम्फनी 2.7 में यह व्यवहार बदल दिया गया था। अब, <option><select> तत्व के बच्चों को भी वही गुण (commit of the change) और इसलिए कक्षाएं मिलती हैं।


कुछ स्पष्टीकरण के लिए, इस कोड रहने दो:

<?php echo $view['form']->widget($form['myField'], ['attr' => ['class' => "text ui-widget-content ui-corner-all"]]); ?> 

फिर इस Symfony < के उत्पादन = 2.6 है:

<select class="text ui-widget-content ui-corner-all" name="myField"> 
    <option value="1">Option 1</option> 
    <option value="2">Option 2</option> 
</select> 

और यह Symfony का उत्पादन होता है> = 2.7:

<select class="text ui-widget-content ui-corner-all" name="myField"> 
    <option value="1" class="text ui-widget-content ui-corner-all">Option 1</option> 
    <option value="2" class="text ui-widget-content ui-corner-all">Option 2</option> 
</select> 

मेरे द्वारा लागू कक्षाएं <option> तत्वों के लिए उपयुक्त नहीं हैं क्योंकि वे सीमाओं को परिभाषित करते हैं और वास्तविक क्षेत्र की तरह हैं। ध्यान दें कि ये jQuery UI द्वारा परिभाषित कक्षाएं हैं इसलिए मैं उनकी परिभाषा को आसानी से बदल नहीं सकता।

सबसे आसान तरीका है, जबकि अभी भी <select> तत्व को लागू करने से एक choice क्षेत्र के सभी <option> तत्वों को इन कक्षाओं में लागू करने से बचने के लिए क्या है?

+0

शायद यह एक बग है। क्योंकि मुझे इसके लिए UPGRADE-2.7 में कुछ भी नहीं मिला, और यह कार्यक्षमता वह है जो 'choice_attr' विकल्प को करना है। – user2268997

+0

@ user2268997 हां, मुझे कुछ भी नहीं मिला लेकिन मुझे जो कोड मिला वह देखकर मुझे बहुत जानबूझकर लगता है। – Chris

+0

मुझे php टेम्पलेट्स के बारे में बहुत कुछ पता नहीं है, लेकिन ऐसा लगता है कि 'attr' को '$ पसंद' से हल किया गया है जो 'ChoiceView' उदाहरण है, जिसे' DefaultChoiceListFactory' द्वारा बनाया गया है, और 'choice_attr' विकल्प पास हो गया है 'चॉइसटाइप' परिभाषा में उस कारखाने के लिए। (यदि आप अपनी 'चॉइसलिस्ट' की आपूर्ति नहीं करते हैं) – user2268997

उत्तर

4

टिप्पणी के लिए धन्यवाद के बारे में choice_attr @ user2268997 से मैं संबंधित ब्लॉग पोस्ट New in Symfony 2.7: Choice form type refactorization जो के उपयोग का विवरण (के रूप में अब undocumented) choice_attr विकल्प मिल गया।

ऐसा लगता है कि क्षेत्र को प्रतिपादित करते समय attr में सिम्फनी choice_attr में विशेषताओं को विलीन करता है। इसका मतलब है कि हमें choice_attr में class विशेषता को ओवरराइट करने की आवश्यकता है।

मैंने attr को परिभाषित करने के बाद कोड में ऐसा करने का प्रयास किया लेकिन कोई भाग्य नहीं था। ऐसा लगता है कि आपको इसे अपनी फॉर्म टाइप परिभाषा में करने की ज़रूरत है। यहाँ choice_attr विकल्प जोड़ने के बाद मेरा रूप से एक अंश है: के रूप में मैं आशा व्यक्त की थी

namespace MyBundle\Form; 

public function buildForm(FormBuilderInterface $builder, array $options) { 
    $builder 
     ->add('roles', 
      'entity', 
      [ 
       'class' => 'MyBundle:Role', 
       'choice_label' => 'name', 
       'multiple' => true, 
       'choice_attr' => function() { return ["class" => ""]; } 
      ]); 
} 

परिणाम है। मैं शायद इसे अपने स्वयं के कस्टम फॉर्म प्रकार में भी दोबारा कर दूंगा, इसलिए मुझे अपने बंडल पर इसे दोहराने की ज़रूरत नहीं है।


मैं अब ऊपर वर्णित वांछित व्यवहार के साथ एक कस्टम choice प्रकार बना सकते हैं और अपने आवेदन में उपयोग है कि एक का फैसला किया है।

use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

class ChoiceNoOptAttrType extends ChoiceType { 
    public function configureOptions(OptionsResolver $resolver) { 
     parent::configureOptions($resolver); 

     $resolver->setDefault("choice_attr", function() { return ["class" => ""]; }); 
    } 
} 

मैं अपने सभी मौजूदा रूपों पुनर्रचना इस नए प्रकार का उपयोग करने का मन नहीं था, इसलिए बजाय मैं मेरा साथ Symfony-प्रदान की पसंद प्रकार बदलने के लिए चुना:

यहाँ मेरी पसंद प्रकार है। यह choice फ़ॉर्म प्रकार के लिए सेवा कॉन्फ़िगरेशन को संशोधित करके हासिल किया जा सकता है। ऐसा करने के लिए, मैंने अपने बंडल के लिए एक कंपाइलर पास बनाया।

अतिरिक्त पठन: Creating a Compiler Pass

namespace MyBundle\DependencyInjection\Compiler; 

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

class MyCompilerPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $definition = $container->getDefinition("form.type.choice"); 
     $definition->setClass('MyBundle\Form\ChoiceNoOptAttrType'); 
    } 
} 

अब वह सब करने के लिए छोड़ दिया जाता है रजिस्टर बंडल में संकलक पास होना जरूरी है।

अतिरिक्त पठन: How to Work with Compiler Passes in Bundles

namespace MyBundle; 

use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\HttpKernel\Bundle\Bundle; 
use MyBundle\DependencyInjection\Compiler\MyCompilerPass; 

class MyBundle extends Bundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     parent::build($container); 

     $container->addCompilerPass(new MyCompilerPass()); 
    } 
} 

और यह बात है। अब मेरे सभी choice फ़ील्ड्स मेरी कस्टम क्लास का उपयोग कर रहे हैं जो सुनिश्चित करता है कि attr में सेट सीएसएस क्लास मेरे <option> तत्वों के लिए प्रचारित नहीं है।

1

एक आसान समाधान हो सकता है, लेकिन आप Form Themes पर एक नज़र डालना चाहेंगे। Choice_widget_options के लिए टेम्पलेट को ओवरराइड करें ताकि कक्षा विकल्प विकल्प पर कक्षाएं लागू न हों।

{%- block choice_widget_options -%} 
    {% for group_label, choice in options %} 
     {%- if choice is iterable -%} 
      <optgroup label="{{ choice_translation_domain is sameas(false) ? group_label : group_label|trans({}, choice_translation_domain) }}"> 
       {% set options = choice %} 
       {{- block('choice_widget_options') -}} 
      </optgroup> 
     {%- else -%} 
      {% set attr = choice.attr %} 
      <option value="{{ choice.value }}" {# DELETE THIS PART: {{ block('attributes') }}#}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is sameas(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option> 
     {%- endif -%} 
    {% endfor %} 
{%- endblock choice_widget_options -%} 
+0

ओपी टिग टेम्पलेट्स का उपयोग नहीं करता है। – user2268997

+0

फिर आप सोचते हैं कि PHP टेम्पलेट को ओवरराइड कर सकते हैं। – LorenzSchaef

+0

धन्यवाद, यह भी मेरे दिमाग में आया। हालांकि, मुझे उम्मीद थी कि मैं इस (बल्कि जटिल) टेम्पलेट को ओवरराइट कर सकता हूं क्योंकि मुझे इसे भविष्य के संस्करणों के लिए बनाए रखना होगा। – Chris

संबंधित मुद्दे