[Solar-svn] Revision 2986

pmjones at solarphp.com pmjones at solarphp.com
Thu Mar 6 17:15:49 CST 2008


Allows nulti-select elements with no selected options to work properly.

Thanks to James Kilbride for the report, and for testing the fixes.


Solar_Form
----------

* [CHG] Method _populate() now checks the source value to see if it's a 
  sequential array.  If so, it assigns the sequential array directly to
  the element, instead of attempting to descend into the array to get
  more source values.

* [CHG] Method _populate() now checks the element type; if a multiple-select,
  and the source value is empty, it forces the element value to an empty
  array.  This is to allow for multiple-selects that have no options selected.

  
Solar_View_Helper_FormSelect
----------------------------

* [CHG] Now prefixes the multiple-select elements with a hidden element to
  represent "no options selected", much the same as with the checkbox helper.




Modified: trunk/Solar/Form.php
===================================================================
--- trunk/Solar/Form.php	2008-03-05 14:36:43 UTC (rev 2985)
+++ trunk/Solar/Form.php	2008-03-06 23:15:49 UTC (rev 2986)
@@ -844,28 +844,52 @@
      * @return void
      * 
      */
-    protected function _populate($src, $elem = null)
+    protected function _populate($src, $name = null)
     {
         // are we working with an array?
         if (is_array($src)) {
-            // yes, descend through each of the sub-elements.
-            foreach ($src as $key => $val) {
-                $sub = empty($elem) ? $key : $elem . "[$key]";
-                $this->_populate($val, $sub);
+            // is the array sequential?  check only the first key.
+            if (is_int(key($src))) {
+                // assign the sequential array to the element.
+                // this is for multiple-select options.
+                $this->elements[$name]['value'] = $src;
+            } else {
+                // not sequential. descend through each of the sub-elements.
+                foreach ($src as $key => $val) {
+                    $sub = empty($name) ? $key : $name . "[$key]";
+                    $this->_populate($val, $sub);
+                }
             }
         } else {
             // populate an element value, but only if it exists.
-            if (isset($this->elements[$elem])) {
+            if (isset($this->elements[$name])) {
                 
+                // convenient reference
+                $elem =& $this->elements[$name];
+                
                 // do not populate certain elements, as this will
                 // reset their value inappropriately.
-                $skip = $this->elements[$elem]['type'] == 'submit' ||
-                        $this->elements[$elem]['type'] == 'button' ||
-                        $this->elements[$elem]['type'] == 'reset';
+                $skip = $name['type'] == 'submit' ||
+                        $name['type'] == 'button' ||
+                        $name['type'] == 'reset';
                         
-                if (! $skip) {
-                    $this->elements[$elem]['value'] = $src;
+                if ($skip) {
+                    return;
                 }
+                
+                // is this a multiple select?
+                $multiple = $elem['type'] == 'select' &&
+                            ! empty($elem['attribs']['multiple']);
+                
+                // set the value appropriately
+                if ($multiple && ! $src) {
+                    // empty on a multiple.  force it to an empty array.
+                    // (merely casting to array gets us an array with one
+                    // empty-string value.)
+                    $elem['value'] = array();
+                } else {
+                    $elem['value'] = $src;
+                }
             }
         }
     }

Modified: trunk/Solar/View/Helper/FormSelect.php
===================================================================
--- trunk/Solar/View/Helper/FormSelect.php	2008-03-05 14:36:43 UTC (rev 2985)
+++ trunk/Solar/View/Helper/FormSelect.php	2008-03-06 23:15:49 UTC (rev 2986)
@@ -40,10 +40,21 @@
             $this->_name .= '[]';
         }
         
-        // check for multiple implied by the name, and set attrib if
-        // needed
+        // check for multiple implied by the name
         if (substr($this->_name, -2) == '[]') {
+            // set multiple attrib
             $this->_attribs['multiple'] = 'multiple';
+            // if no value is selected, the element won't be sent back to the
+            // server at all (like an unchecked checkbox).  add a default
+            // blank value under a non-array name so that if no values are
+            // selected, an empty value is sent back to the server.
+            $xhtml = $this->_view->formHidden(array(
+                'name'  => substr($this->_name, 0, -2),
+                'value' => null,
+            ));
+        } else {
+            // not multiple, start with blank xhtml
+            $xhtml = '';
         }
         
         // build the list of options
@@ -60,8 +71,9 @@
                     . '>' . $this->_view->escape($opt_label) . "</option>";
         }
         
-        // now build the XHTML
-        return '<select name="' . $this->_view->escape($this->_name) . '"'
+        // build and return the remaining xhtml
+        return $xhtml
+             . '<select name="' . $this->_view->escape($this->_name) . '"'
              . $this->_view->attribs($this->_attribs) . ">\n"
              . "    " . implode("\n    ", $list) . "\n"
              . "</select>";




More information about the Solar-svn mailing list