}
});
+/**
+ * Namespace for category related classes.
+ */
+WCF.Category = { };
+
+/**
+ * Handles selection of categories.
+ */
+WCF.Category.NestedList = Class.extend({
+ /**
+ * list of categories
+ * @var object
+ */
+ _categories: { },
+
+ /**
+ * Initializes the WCF.Category.NestedList object.
+ */
+ init: function() {
+ var self = this;
+ $('.jsCategory').each(function(index, category) {
+ var $category = $(category).data('parentCategoryID', null).change($.proxy(self._updateSelection, self));
+ self._categories[$category.val()] = $category;
+
+ // find child categories
+ var $childCategoryIDs = [ ];
+ $category.parents('li').find('.jsChildCategory').each(function(innerIndex, childCategory) {
+ var $childCategory = $(childCategory).data('parentCategoryID', $category.val()).change($.proxy(self._updateSelection, self));
+ self._categories[$childCategory.val()] = $childCategory;
+ $childCategoryIDs.push($childCategory.val());
+
+ if ($childCategory.is(':checked')) {
+ $category.prop('checked', 'checked');
+ }
+ });
+
+ $category.data('childCategoryIDs', $childCategoryIDs);
+ });
+ },
+
+ /**
+ * Updates selection of categories.
+ *
+ * @param object event
+ */
+ _updateSelection: function(event) {
+ var $category = $(event.currentTarget);
+ var $parentCategoryID = $category.data('parentCategoryID');
+
+ if ($category.is(':checked')) {
+ // child category
+ if ($parentCategoryID !== null) {
+ // mark parent category as checked
+ this._categories[$parentCategoryID].prop('checked', 'checked');
+ }
+ }
+ else {
+ // top-level category
+ if ($parentCategoryID === null) {
+ // unmark all child categories
+ var $childCategoryIDs = $category.data('childCategoryIDs');
+ for (var $i = 0, $length = $childCategoryIDs.length; $i < $length; $i++) {
+ this._categories[$childCategoryIDs[$i]].prop('checked', false);
+ }
+ }
+ }
+ }
+});
+
/**
* Encapsulate eval() within an own function to prevent problems
* with optimizing and minifiny JS.