Symfony बॉक्स से बाहर इस संभालती है, बस अपने पैच-पेलोड तैयार ठीक से :)
Symfony CheckboxType, कम से कम वर्तमान संस्करण में 3.3 (2.3 के बाद से की तरह लगता है, नीचे अद्यतन देखें), एक इनपुट स्वीकार करता है null
का मान, जिसे "चेक नहीं किया गया" के रूप में व्याख्या किया गया है (जैसा कि आप Roubi's really helpful answer में स्निपेट के लाइन 3-5 में देख सकते हैं)।
तो अपने क्लाइंट साइड AJAX-PATCH नियंत्रक में आप null
करने के लिए अपने application/merge-patch+json
पेलोड में अपने (गंदा) अनियंत्रित चेकबॉक्स क्षेत्र की का मान सेट और सब कुछ ठीक है। कोई फॉर्म एक्सटेंशन ओवरराइटिंग चेकबॉक्स टाइप का व्यवहार बिल्कुल जरूरी नहीं है।
समस्या यह है: मुझे लगता है कि आप HTTP-POST-payload के मानों को null
पर सेट नहीं कर सकते हैं, इसलिए यह केवल अनुरोध निकाय के भीतर JSON (या अन्य संगत) पेलोड के साथ काम करता है।
एक साधारण डेमो
इस प्रदर्शन करने के लिए, तो आप इस सरलीकृत परीक्षण नियंत्रक का उपयोग कर सकते हैं:
/**
* @Route("/test/patch.json", name="test_patch")
* @Method({"PATCH"})
*/
public function patchAction(\Symfony\Component\HttpFoundation\Request $request)
{
$form = $this->createFormBuilder(['checkbox' => true, 'dummyfield' => 'presetvalue'], ['csrf_protection' => false])
->setAction($this->generateUrl($request->get('_route')))
->setMethod('PATCH')
->add('checkbox', \Symfony\Component\Form\Extension\Core\Type\CheckboxType::class)
->add('dummyfield', \Symfony\Component\Form\Extension\Core\Type\TextType::class)
->getForm()
;
$form->submit(json_decode($request->getContent(), true), false);
return new \Symfony\Component\HttpFoundation\JsonResponse($form->getData());
}
Content-Type: application/merge-patch+json
साथ या इस मामले को भी किसी भी मान्य JSON-पेलोड, निम्नलिखित वसीयत में PATCH-अनुरोधों के लिए होती हैं:
null
मूल्य के साथ चेकबॉक्स को जमा
{"checkbox": null}
गलत पर चेकबॉक्स के ऊपर लिख देगा:
{"checkbox": false, "dummyfield": "presetvalue"}
और अपने मूल मूल्य के साथ चेकबॉक्स प्रस्तुत करने
{"checkbox": "1"}
सच करने के लिए चेकबॉक्स सेट हो जाएगा (यह भी पहले सच था)
{"checkbox": true, "dummyfield": "presetvalue"}
और चेकबॉक्स
के लिए कोई सबमिट मूल्य नहीं
अपनी प्रारंभिक सच राज्य में चेकबॉक्स छोड़ देंगे और केवल dummyfield अधिलेखित कर देता है:
{"checkbox": true, "dummyfield": "requestvalue"}
यह कैसे एक पैच अनुरोध काम करना चाहिए, बिना किसी अतिरिक्त जरूरत छिपा आदानों है। बस अपने JSON-payload को क्लाइंट-साइड पर ठीक से तैयार करें और आप ठीक हैं।
ठीक है, लेकिन विस्तारित चॉइसटाइप/EntityType के बारे में क्या?
विस्तारित चॉइसटाइप (या इसके प्रकार के बच्चे प्रकार एंटिटीटाइप) के लिए, जो चेकबॉक्स या रेडियोबुटन प्रस्तुत करता है और सबमिट किए गए पेलोड के भीतर चेक किए गए चेकबॉक्स/रेडियोबुटन मानों की एक साधारण सूची की अपेक्षा करता है, यह सरल समाधान काम नहीं करता है। मैंने एक फॉर्म एक्सटेंशन लागू किया, जिसमें उन फ़ील्ड पर PRE_SUBMIT के लिए इवेंट श्रोता जोड़ा गया, गैर सबमिट किए गए चेकबॉक्स/रेडियोबुटन को शून्य पर सेट किया गया। चेकबॉक्स टाइप के बंद-श्रोता के बाद इस ईवेंट श्रोता को कॉल किया जाना चाहिए, सरल सूची ["1", "3"]
को हैश में चेकबॉक्स-मानों के साथ कुंजी और मान के रूप में स्थानांतरित करना। -1
की प्राथमिकता मेरे लिए काम करती है। इसलिए ["1" => "1", "3" => "3"]
बंद होने से बाहर आने से मेरे श्रोता के बाद ["1" => "1", "2" => null, "3" => "3"]
हो जाता है। मेरी PatchableChoiceTypeExtension
के श्रोता इस तरह मूल रूप से दिखता है:
$builder->addEventListener(
\Symfony\Component\Form\FormEvents::PRE_SUBMIT,
function (\Symfony\Component\Form\FormEvent $event) {
if ('PATCH' === $event->getForm()->getRoot()->getConfig()->getMethod()
&& $event->getForm()->getConfig()->getOption('expanded', false)
) {
$data = $event->getData();
foreach ($event->getForm()->all() as $type) {
if (!array_key_exists($type->getName(), $data)) {
$data[$type->getName()] = null;
}
}
ksort($data);
$event->setData($data);
}
}, -1
);
अद्यतन: /Symfony/Component/Form/Form.php (यह Symfony 2.3 के बाद से वहाँ है) में प्रस्तुत-विधि के भीतर इस टिप्पणी पर एक नजर है:
// Treat false as NULL to support binding false to checkboxes.
// Don't convert NULL to a string here in order to determine later
// whether an empty value has been submitted or whether no value has
// been submitted at all. This is important for processing checkboxes
// and radio buttons with empty values.
अद्यतन 2017/09/12: Radiogroups Checkboxgroups के रूप में एक ही तरह से नियंत्रित किया जाना चाहिए, इसलिए मेरे श्रोता दोनों संभालती है। चयन और बहु चयन बॉक्स के ठीक से काम करते हैं।
आप डेटा ट्रांसफॉर्मर को $ builder-> resetViewTransformers() के साथ रीसेट कर सकते हैं। फिर अपना खुद का डेटा ट्रांसफॉर्मर जोड़ें। – Falc
@Falc उत्कृष्ट! वास्तव में मुझे क्या चाहिए! – Roubi
अच्छा समाधान! मैंने इस 'व्यवहार को' accept_null_on_patch' फ़ॉर्म फ़ील्ड विकल्प के माध्यम से आसानी से कॉन्फ़िगर करने योग्य बनाने के लिए 'चेकबॉक्स टाइप' को विस्तारित करने के लिए 'पैच करने योग्य चेकबॉक्स टाइप प्रकार' के भीतर कार्यान्वित किया। यदि यह सत्य पर सेट किया गया है, तो यह सभी व्यूट्रांसफॉर्मर्स को हटा देता है और इसके बजाय 'पैचेबल चेकबॉक्सबोलियन टॉस्ट्रिंग ट्रान्सफॉर्मर' जोड़ता है। – spackmat