Fixed boolean user group option type
authorAlexander Ebert <ebert@woltlab.com>
Thu, 18 Jun 2015 11:35:30 +0000 (13:35 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 18 Jun 2015 11:35:30 +0000 (13:35 +0200)
wcfsetup/install/files/acp/templates/userGroupOption.tpl
wcfsetup/install/files/lib/system/option/user/group/BooleanUserGroupOptionType.class.php

index ab6cd929d9e1293dcd88b7604eff26fbe614e06a..94017fec831c2ded2b24d238f77c3dbef0a83346 100644 (file)
@@ -1,26 +1,50 @@
 {include file='header'}
 
 <script data-relocate="true">
-       $(function() {
-               $('#optionValueContainer label').each(function(index, label) {
-                       var $label = $(label);
-                       var $id = $label.prop('for');
-                       if ($id && $id.match(/^userGroupOption/)) {
-                               var $groupID = $id.replace(/^userGroupOption/, '');
-                               $label.parents('dl').children('dd').find('input, select, textarea').each(function(index, element) {
-                                       var $element = $(element);
-                                       var $oldName = $element.attr('name');
-                                       
-                                       var $newName = 'values[' + $groupID + ']';
-                                       if ($oldName.substr(-2) == '[]') {
-                                               $newName += '[]';
+console.time('option');
+       (function() {
+               var container = document.getElementById('optionValueContainer');
+               var parent = container.parentNode;
+               
+               // using a fragment is inefficient, but prevents strange transitions for booleans caused by checked state lost when changing the name
+               var fragment = document.createDocumentFragment();
+               fragment.appendChild(container);
+               
+               var dd, groupId, id, inputElements, isBoolean, label, labels = container.getElementsByTagName('label');
+               for (var i = 0, length = labels.length; i < length; i++) {
+                       label = labels[i];
+                       id = label.getAttribute('for') || '';
+                       if (id.match(/^userGroupOption(\d+)$/)) {
+                               groupId = RegExp.$1;
+                               dd = label.parentNode.nextElementSibling;
+                               if (dd !== null && dd.nodeName === 'DD') {
+                                       inputElements = dd.querySelectorAll('input, select, textarea');
+                                       isBoolean = (dd.childElementCount === 1 && dd.children[0].classList.contains('optionTypeBoolean'));
+                                       for (var j = 0, innerLength = inputElements.length; j < innerLength; j++) {
+                                               inputElement = inputElements[j];
+                                               inputElement.name = 'values[' + groupId + ']' + (inputElement.name.slice(-2) === '[]' ? '[]' : '');
+                                               
+                                               if (isBoolean) {
+                                                       inputElement.checked = (inputElement.getAttribute('checked') === 'checked');
+                                                       id += '_' + groupId;
+                                                       label.removeAttribute('for');
+                                                       inputElement.nextElementSibling.setAttribute('for', id);
+                                               }
+                                               
+                                               inputElement.id = id;
                                        }
-                                       
-                                       $element.attr('id', $id).attr('name', $newName);
-                               });
+                               }
                        }
-               });
-       });
+               }
+               
+               if (parent.childElementCount) {
+                       parent.insertBefore(fragment, parent.children[0]);
+               }
+               else {
+                       parent.appendChild(fragment);
+               }
+       })();
+console.timeEnd('option');
 </script>
 
 <header class="boxHeadline">
index 3c72f3273176944fcff6af831d709ce0720cd36b..99b647baaa03ef0f845ef285626809decd8b1fc7 100644 (file)
@@ -36,6 +36,14 @@ class BooleanUserGroupOptionType extends BooleanOptionType implements IUserGroup
                return WCF::getTPL()->fetch('userGroupBooleanOptionType');
        }
        
+       /**
+        * @see \wcf\system\option\IOptionType::getData()
+        */
+       public function getData(Option $option, $newValue) {
+               if ($newValue == -1 || $newValue == 1) return $newValue;
+               return 0;
+       }
+       
        /**
         * @see \wcf\system\option\IOptionType::getCSSClassName()
         */