Development

#7831 (sfWidgetFormSelectDoubleList default value not working with sfWidgetFormDoctrineChoiceGrouped)

You must first sign up to be able to contribute.

Ticket #7831 (assigned defect)

Opened 3 years ago

Last modified 1 year ago

sfWidgetFormSelectDoubleList default value not working with sfWidgetFormDoctrineChoiceGrouped

Reported by: userz Assigned to: ludo.fleury (accepted)
Priority: minor Milestone:
Component: sfFormExtraPlugin Version: 1.4.0
Keywords: sfWidgetFormSelectDoubleList, sfWidgetFormDoctrineChoiceGrouped Cc:
Qualification: Unreviewed

Description

default values not sets when sfWidgetFormSelectDoubleList using with sfWidgetFormDoctrineChoiceGrouped widgets. If use sfWidgetFormDoctrineChoice all work.

public function configure() {
    $this->setWidget('prices_on_page', new sfWidgetFormDoctrineChoiceGrouped(array(
           'model' => 'Price',
           'multiple' => true,
           'order_by' => array('Position', 'asc'),
           'group_by' => 'PriceFolder',
           'renderer_class' => 'sfWidgetFormSelectDoubleList',
       )));
        
    $this->validatorSchema['prices_on_page'] = new sfValidatorDoctrineChoice(array(
           'model' => 'Price',
           'required' => false,
           'multiple' => true,
       ));
}

public function updateDefaultsFromObject() {
        if (isset($this->widgetSchema['prices_on_page'])) {
            $values = array();
            foreach ($this->object->getPricesOnPage() as $obj) {
                $values[] = $obj->getPriceId();
            }
            $this->setDefault('prices_on_page', $values);
        }
}

Change History

(in reply to: ↑ description ) 01/17/10 18:26:58 changed by ludo.fleury

It's because the double list rendering use only one level of array association. You can easily fix the problem by applying this / or extending the sfWidgetFormSelectDoubleList and replace the line 112 :

    foreach ($choices as $group => $options)
    {
	foreach ($options as $key => $option)
	{
	  if (in_array(strval($key), $value))
	  {
	    $associated[$group][$key] = $option;
	  }
	  else
	  {
	    $unassociated[$group][$key] = $option;
	  }
	}
    }

It will display the defaults values for the "associated select list". Next, you could improve the user experience by adding default category even if they are empty with this :

    foreach ($choices as $group => $options)
    {
        $associated = array();
        $unassociated = array();
	foreach ($options as $key => $option)
	{
	  if (in_array(strval($key), $value))
	  {
	    $associated[$group][$key] = $option;
	  }
	  else
	  {
	    $unassociated[$group][$key] = $option;
	  }
	}
    }

And then, you could patch also the javascript if needed...

01/22/10 16:31:15 changed by ludo.fleury

  • owner changed from fabien to ludo.fleury.
  • status changed from new to assigned.
  • qualification changed from Unreviewed to Accepted.

(follow-up: ↓ 4 ) 01/22/10 17:13:28 changed by ludo.fleury

  • qualification changed from Accepted to Unreviewed.

foreach ($choices as $options) {

foreach ($options as $key => $option) {

if (in_array(strval($key), $value)) {

$associated[$group][$key] = $option;

} else {

$unassociated[$group][$key] = $option;

}

}

}

(in reply to: ↑ 3 ) 03/22/11 12:05:21 changed by apulmca2k4

Replying to ludo.fleury:

foreach ($choices as $options) { foreach ($options as $key => $option) { if (in_array(strval($key), $value)) { $associated[$group][$key] = $option; } else { $unassociated[$group][$key] = $option; } } }

Above mentioned solution is not working for me. Please suggest something else.

05/11/12 12:25:09 changed by peter.taylor

Here's a patch which handles the choices being grouped or not both in the PHP and in the JavaScript:

Index: plugins/sfFormExtraPlugin/lib/widget/sfWidgetFormSelectDoubleList.class.php
===================================================================
--- plugins/sfFormExtraPlugin/lib/widget/sfWidgetFormSelectDoubleList.class.php	(revision 155)
+++ plugins/sfFormExtraPlugin/lib/widget/sfWidgetFormSelectDoubleList.class.php	(working copy)
@@ -132,13 +132,32 @@
     $unassociated = array();
     foreach ($choices as $key => $option)
     {
-      if (in_array(strval($key), $value))
+      if (is_array($option))
       {
-        $associated[$key] = $option;
+        $associated[$key] = array();
+        $unassociated[$key] = array();
+        foreach ($option as $innerKey => $innerOption)
+        {
+          if (in_array(strval($innerKey), $value))
+          {
+            $associated[$key][$innerKey] = $innerOption;
+          }
+          else
+          {
+            $unassociated[$key][$innerKey] = $innerOption;
+          }
+        }
       }
       else
       {
-        $unassociated[$key] = $option;
+        if (in_array(strval($key), $value))
+        {
+          $associated[$key] = $option;
+        }
+        else
+        {
+          $unassociated[$key] = $option;
+        }
       }
     }
 
Index: plugins/sfFormExtraPlugin/web/js/double_list.js
===================================================================
--- plugins/sfFormExtraPlugin/web/js/double_list.js	(revision 155)
+++ plugins/sfFormExtraPlugin/web/js/double_list.js	(working copy)
@@ -20,11 +20,35 @@
   {
     var src = document.getElementById(srcId);
     var dest = document.getElementById(destId);
+    var destGroups = {};
+    for (var i = 0; i < dest.childNodes.length; i++)
+    {
+      if (dest.childNodes[i].nodeName.toLowerCase() == "optgroup")
+      {
+        destGroups[dest.childNodes[i].getAttribute("label")] = dest.childNodes[i];
+      }
+    }
     for (var i = 0; i < src.options.length; i++)
     {
       if (src.options[i].selected)
       {
-        dest.options[dest.length] = new Option(src.options[i].text, src.options[i].value);
+        var newChild = new Option(src.options[i].text, src.options[i].value);
+        if (src.options[i].parentNode.nodeName.toLowerCase() == "optgroup")
+        {
+          var groupLabel = src.options[i].parentNode.getAttribute("label");
+          if (!destGroups.hasOwnProperty(groupLabel))
+          {
+            destGroups[groupLabel] = document.createElement("optgroup");
+            destGroups[groupLabel].setAttribute("label", groupLabel);
+            dest.appendChild(destGroups[groupLabel]);
+          }
+          destGroups[groupLabel].appendChild(newChild);
+        }
+        else
+        {
+          dest.options[dest.length] = newChild;
+        }
+
         src.options[i] = null;
         --i;
       }