Author: boutell
Date: 2010-01-13 23:23:29 +0100 (Wed, 13 Jan 2010)
New Revision: 26592

Modified:
   plugins/pkToolkitPlugin/trunk/lib/widget/sfWidgetFormJQueryDate.class.php
   plugins/pkToolkitPlugin/trunk/web/js/pkControls.js
Log:
Date widget now has a wrapper div with the id of the control for efficient 
jQuery selectors
pkCheckboxEnables now supports disabling and hiding some items, as well as 
enabling and showing others, and has been refactored a bit
pkCheckboxEnables supports nesting



Modified: 
plugins/pkToolkitPlugin/trunk/lib/widget/sfWidgetFormJQueryDate.class.php
===================================================================
--- plugins/pkToolkitPlugin/trunk/lib/widget/sfWidgetFormJQueryDate.class.php   
2010-01-13 22:13:47 UTC (rev 26591)
+++ plugins/pkToolkitPlugin/trunk/lib/widget/sfWidgetFormJQueryDate.class.php   
2010-01-13 22:23:29 UTC (rev 26592)
@@ -71,6 +71,10 @@
       $image = sprintf(', buttonImage: "%s", buttonImageOnly: true', 
$this->getOption('image'));
     }
     return 
+      // Outer div with the prefix ID allows efficient jQuery - Firefox can 
delay for
+      // as much as two full seconds trying to process the :has selectors that 
are otherwise
+      // necessary to locate all of the controls in here
+      '<div class="pk-date-wrapper" id="' . $prefix . '">' .
       // Parent class select controls, our interface to Symfony
       '<span style="display: none">' . parent::render($name, $value, 
$attributes, $errors) . '</span>' .
       // Autopopulated by jQuery.Datepicker, we also allow direct editing and 
have hooks relating to that
@@ -156,6 +160,8 @@
       $id,
       min($this->getOption('years')), max($this->getOption('years')),
       $prefix, $prefix, $image, $this->getOption('culture'), 
$this->getOption('config')
-    );
+    ) . 
+    // Close wrapper div
+    '</div>';
   }
 }

Modified: plugins/pkToolkitPlugin/trunk/web/js/pkControls.js
===================================================================
--- plugins/pkToolkitPlugin/trunk/web/js/pkControls.js  2010-01-13 22:13:47 UTC 
(rev 26591)
+++ plugins/pkToolkitPlugin/trunk/web/js/pkControls.js  2010-01-13 22:23:29 UTC 
(rev 26592)
@@ -520,54 +520,106 @@
 }
 
 // Got a checkbox and a set of related controls that should only be enabled
-// when the checkbox is checked? Here's your answer
+// when the checkbox is checked? Here's your answer.
 
-// The optional hideItemsSelector contains items that should be hidden rather 
than disabled.
-// You can pass undefined for itemsSelector if you are only interested in 
hiding items. This
-// combination is useful if you want to fully disable a datepicker with an 
input field
-// (disable-able) and a calendar icon (not disable-able, but hide-able).
+// You can specify four different selectors. pass undefined (not null) to skip 
a selector.
 
-// Both selector arguments are optional. To skip itemsSelector, pass undefined 
(not null)
-// for that argument.
+// When the box is checked, enablesItemsSelector is enabled, and 
showsItemsSelector is shown.
+// When the box is unchecked, enablesItemsSelector is disabled, and 
showsItemsSelector is hidden.
 
-// ACHTUNG: don't forget about hidden form elements you might be disabling 
(Symfony adds them to the last row
-// in a form). Write your selectors carefully, check for over-generous 
selectors when forms seem broken.
+// For the opposite effect (disable or hide when the box IS checked), use
+// disablesItemsSelector and hidesItemsSelector.
 
-function pkCheckboxEnables(boxSelector, itemsSelector, hideItemsSelector)
+// ACHTUNG: don't forget about hidden form elements you might be disabling 
+// (Symfony adds them to the last row in a form). Write your selectors 
carefully,
+// check for over-generous selectors when forms seem broken.
+
+// Nesting is permitted. If an outer checkbox would enable a child of an inner 
checkbox, 
+// it first checks a nesting counter to ensure it is not also disabled due to 
the inner 
+// checkbox. This only works if you call pkCheckboxEnables for the OUTER 
checkbox FIRST.
+// That is due to the order in which onReady() calls are made by jQuery.
+
+function pkCheckboxEnables(boxSelector, enablesItemsSelector, 
showsItemsSelector, disablesItemsSelector, hidesItemsSelector)
 {
-       $(boxSelector).data('pkCheckboxEnablesItemsSelector', itemsSelector);
-       $(boxSelector).data('pkCheckboxEnablesHideItemsSelector', 
hideItemsSelector);
-       $(boxSelector).click(function() {
+       $(boxSelector).data('pkCheckboxEnablesSelectors',
+               [ enablesItemsSelector, showsItemsSelector, 
disablesItemsSelector, hidesItemsSelector ]);
+       
+       $(boxSelector).click(function() 
+       {
                update(this);
        });
 
-       function update(checkbox)
+       function bumpEnabled(selector, show)
        {
-               var itemsSelector = 
$(checkbox).data('pkCheckboxEnablesItemsSelector');
-               var hideItemsSelector = 
$(checkbox).data('pkCheckboxEnablesHideItemsSelector');
-               if ($(checkbox).attr('checked'))
+               if (selector === undefined)
                {
-                       if (itemsSelector !== undefined)
+                       return;
+               }
+               $(selector).each(function() { 
+                       var counter = 
$(this).data('pkCheckboxEnablesEnableCounter');
+                       if (counter < 0)
                        {
-                               $(itemsSelector).removeAttr('disabled');
+                               counter++;
+                               $(this).data('pkCheckboxEnablesEnableCounter', 
counter);
                        }
-                       if (hideItemsSelector !== undefined)
+                       if (counter >= 0)
                        {
-                               $(hideItemsSelector).show();
+                               if (show)
+                               {
+                                       $(this).show();
+                               }
+                               else
+                               {
+                                       $(this).removeAttr('disabled');
+                               }
                        }
+               });
+       }
+
+       function bumpDisabled(selector, hide)
+       {
+               if (selector === undefined)
+               {
+                       return;
                }
-               else
-               {
-                       if (itemsSelector !== undefined)
+               $(selector).each(function() { 
+                       var counter = 
$(this).data('pkCheckboxEnablesEnableCounter');
+                       if (counter === undefined)
                        {
-                               $(itemsSelector).attr('disabled', 'disabled');
+                               counter = 0;
+                       }       
+                       counter--;
+                       $(this).data('pkCheckboxEnablesEnableCounter', counter);
+                       if (hide)
+                       {
+                               $(this).hide();
                        }
-                       if (hideItemsSelector !== undefined)
+                       else
                        {
-                               $(hideItemsSelector).hide();
+                               $(this).attr('disabled', 'disabled');
                        }
-               } 
+               });
        }
+       
+       function update(checkbox)
+       {
+               var selectors = $(checkbox).data('pkCheckboxEnablesSelectors');
+               var checked = $(checkbox).attr('checked');
+               if (checked)
+               {
+                       bumpEnabled(selectors[0], false);
+                       bumpEnabled(selectors[1], true);
+                       bumpDisabled(selectors[2], false);
+                       bumpDisabled(selectors[3], true);
+               }
+               else
+               {
+                       bumpDisabled(selectors[0], false);
+                       bumpDisabled(selectors[1], true);
+                       bumpEnabled(selectors[2], false);
+                       bumpEnabled(selectors[3], true);
+               }
+       }
        // At DOMready so we can affect controls created by js widgets in the 
form
        $(function() {
                $(boxSelector).each(function() { update(this) });

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.


Reply via email to