/*!
* jQuery CheckboxTree
*
* @author Valerio Galano ' : '';
this.options.expandAnchor = (this.options.expandImage.length > 0) ? '
' : '';
this.options.leafAnchor = (this.options.leafImage.length > 0) ? '
' : '';
// initialize leafs
this.element.find("li:not(:has(ul))").each(function() {
$(this).prepend($(''));
t._markAsLeaf($(this));
});
// initialize checked nodes
this.element.find("li:has(ul):has(input:checkbox:checked)").each(function() {
$(this).prepend($(''));
t.options.initializeChecked == 'collapsed' ? t.collapse($(this)) : t.expand($(this));
});
// initialize unchecked nodes
this.element.find("li:has(ul):not(:has(input:checkbox:checked))").each(function() {
$(this).prepend($(''));
t.options.initializeUnchecked == 'collapsed' ? t.collapse($(this)) : t.expand($(this));
});
// bind collapse/expand event
this.element.find('li span').live("click", function() {
var li = $(this).parents("li:first");
if (li.hasClass('collapsed')) {
t.expand(li);
} else
if (li.hasClass('expanded')) {
t.collapse(li);
}
});
// bind collapse all element event
$(this.options.collapseAllElement).bind("click", function() {
t.collapseAll();
});
// bind expand all element event
$(this.options.expandAllElement).bind("click", function() {
t.expandAll();
});
// bind collapse on uncheck event
if (this.options.onUncheck.node == 'collapse') {
this.element.find('input:checkbox:not(:checked)').live("click", function() {
t.collapse($(this).parents("li:first"));
});
} else
// bind expand on uncheck event
if (this.options.onUncheck.node == 'expand') {
this.element.find('input:checkbox:not(:checked)').live("click", function() {
t.expand($(this).parents("li:first"));
});
}
// bind collapse on check event
if (this.options.onCheck.node == 'collapse') {
this.element.find('input:checkbox:checked').live("click", function() {
t.collapse($(this).parents("li:first"));
});
} else
// bind expand on check event
if (this.options.onCheck.node == 'expand') {
this.element.find('input:checkbox:checked').live("click", function() {
t.expand($(this).parents("li:first"));
});
}
}
// bind node uncheck event
this.element.find('input:checkbox:not(:checked)').live('click', function() {
var li = $(this).parents('li:first');
t.uncheck(li);
});
// bind node check event
this.element.find('input:checkbox:checked').live('click', function() {
var li = $(this).parents('li:first');
t.check(li);
});
// add essential css class
this.element.addClass('ui-widget-daredevel-checkboxTree');
// add jQueryUI css widget class
this.element.addClass('ui-widget ui-widget-content');
},
/**
* Check ancestors on passed node
*
* Don't use check() method because we won't trigger onCheck events
*
* @private
*
* @param li node
*/
_checkAncestors: function(li) {
li.parentsUntil(".ui-widget").filter('li').find('input:checkbox:first:not(:checked)').attr('checked', true).change();
},
/**
* Check descendants on passed node
*
* Don't use check() method because we won't trigger onCheck events
*
* @private
*
* @param li node
*/
_checkDescendants: function(li) {
li.find('li input:checkbox:not(:checked)').attr('checked', true).change();
},
/**
* Check nodes that are neither ancestors or descendants of passed node
*
* Don't use check() method because we won't trigger onCheck events
*
* @private
*
* @param li node
*/
_checkOthers: function(li) {
li.addClass('exclude');
li.parents('li').addClass('exclude');
li.find('li').addClass('exclude');
$(this.element).find('li').each(function() {
if (!$(this).hasClass('exclude')) {
$(this).find('input:checkbox:first:not(:checked)').attr('checked', true).change();
}
});
$(this.element).find('li').removeClass('exclude');
},
/**
* Destroy plugin
*
* @private
*/
_destroy: function() {
this.element.removeClass(this.options.cssClass);
$.Widget.prototype.destroy.call(this);
},
/**
* Check if passed node is a root
*
* @private
*
* @param li node to check
*/
_isRoot: function(li) {
var parents = li.parentsUntil('.ui-widget-daredevel-checkboxTree');
return 0 == parents.length;
},
/**
* Mark node as collapsed
*
* @private
*
* @param li node to mark
*/
_markAsCollapsed: function(li) {
if (this.options.expandAnchor.length > 0) {
li.children("span").html(this.options.expandAnchor);
} else
if (this.options.collapseUiIcon.length > 0) {
li.children("span").removeClass(this.options.expandUiIcon).addClass('ui-icon ' + this.options.collapseUiIcon);
}
li.removeClass("expanded").addClass("collapsed");
},
/**
* Mark node as expanded
*
* @private
*
* @param li node to mark
*/
_markAsExpanded: function(li) {
if (this.options.collapseAnchor.length > 0) {
li.children("span").html(this.options.collapseAnchor);
} else
if (this.options.expandUiIcon.length > 0) {
li.children("span").removeClass(this.options.collapseUiIcon).addClass('ui-icon ' + this.options.expandUiIcon);
}
li.removeClass("collapsed").addClass("expanded");
},
/**
* Mark node as leaf
*
* @private
*
* @param li node to mark
*/
_markAsLeaf: function(li) {
if (this.options.leafAnchor.length > 0) {
li.children("span").html(this.options.leafAnchor);
} else
if (this.options.leafUiIcon.length > 0) {
li.children("span").addClass('ui-icon ' + this.options.leafUiIcon);
}
li.addClass("leaf");
},
/**
* Return parent li of the passed li
*
* @private
*
* @param li node
*
* @return parent li
*/
_parentNode: function(li) {
return li.parents('li:first');
},
/**
* Uncheck ancestors of passed node
*
* Don't use uncheck() method because we won't trigger onUncheck events
*
* @private
*
* @param li node
*/
_uncheckAncestors: function(li) {
li.parentsUntil(".ui-widget").filter('li').find('input:checkbox:first:checked').attr('checked', false).change();
},
/**
* Uncheck descendants of passed node
*
* Don't use uncheck() method because we won't trigger onUncheck events
*
* @private
*
* @param li node
*/
_uncheckDescendants: function(li) {
li.find('li input:checkbox:checked').attr('checked', false).change();
},
/**
* Uncheck nodes that are neither ancestors or descendants of passed node
*
* Don't use uncheck() method because we won't trigger onUncheck events
*
* @private
*
* @param li node
*/
_uncheckOthers: function(li) {
li.addClass('exclude');
li.parents('li').addClass('exclude');
li.find('li').addClass('exclude');
$(this.element).find('li').each(function() {
if (!$(this).hasClass('exclude')) {
$(this).find('input:checkbox:first:checked').attr('checked', false).change();
}
});
$(this.element).find('li').removeClass('exclude');
},
/**
* Check node
*
* @public
*
* @param li node to check
*/
check: function(li) {
li.find('input:checkbox:first:not(:checked)').attr('checked', true).change();
// handle others
if (this.options.onCheck.others == 'check') {
this._checkOthers(li);
} else
if (this.options.onCheck.others == 'uncheck') {
this._uncheckOthers(li);
}
// handle descendants
if (this.options.onCheck.descendants == 'check') {
this._checkDescendants(li);
} else
if (this.options.onCheck.descendants == 'uncheck') {
this._uncheckDescendants(li);
}
// handle ancestors
if (this.options.onCheck.ancestors == 'check') {
this._checkAncestors(li);
} else
if (this.options.onCheck.ancestors == 'uncheck') {
this._uncheckAncestors(li);
} else
if (this.options.onCheck.ancestors == 'checkIfFull') {
if (!this._isRoot(li) && this._allDescendantChecked(this._parentNode(li))) {
this.check(this._parentNode(li));
}
}
},
/**
* Check all tree elements
*
* Don't use check() method so it won't trigger onCheck events
*
* @public
*/
checkAll: function() {
$(this.element).find('input:checkbox:not(:checked)').attr('checked', true).change();
},
/**
* Collapse node
*
* @public
*
* @param li node to collapse
*/
collapse: function(li) {
if (li.hasClass('collapsed') || (li.hasClass('leaf'))) {
return;
}
var t = this;
li.children("ul").hide(this.options.collapseEffect, {}, this.options.collapseDuration);
setTimeout(function() {
t._markAsCollapsed(li, t.options);
}, t.options.collapseDuration);
t._trigger('collapse', li);
},
/**
* Collapse all nodes of the tree
*
* @private
*/
collapseAll: function() {
var t = this;
$(this.element).find('li.expanded').each(function() {
t.collapse($(this));
});
},
/**
* Expand node
*
* @public
*
* @param li node to expand
*/
expand: function(li) {
if (li.hasClass('expanded') || (li.hasClass('leaf'))) {
return;
}
var t = this;
li.children("ul").show(t.options.expandEffect, {}, t.options.expandDuration);
setTimeout(function() {
t._markAsExpanded(li, t.options);
}, t.options.expandDuration);
t._trigger('expand', li);
},
/**
* Expand all nodes of the tree
*
* @public
*/
expandAll: function() {
var t = this;
$(this.element).find('li.collapsed').each(function() {
t.expand($(this));
});
},
/**
* Uncheck node
*
* @public
*
* @param li node to uncheck
*/
uncheck: function(li) {
li.find('input:checkbox:first:checked').attr('checked', false).change();
// handle others
if (this.options.onUncheck.others == 'check') {
this._checkOthers(li);
} else
if (this.options.onUncheck.others == 'uncheck') {
this._uncheckOthers(li);
}
// handle descendants
if (this.options.onUncheck.descendants == 'check') {
this._checkDescendants(li);
} else
if (this.options.onUncheck.descendants == 'uncheck') {
this._uncheckDescendants(li);
}
// handle ancestors
if (this.options.onUncheck.ancestors == 'check') {
this._checkAncestors(li);
} else
if (this.options.onUncheck.ancestors == 'uncheck') {
this._uncheckAncestors(li);
}
},
/**
* Uncheck all tree elements
*
* Don't use uncheck() method so it won't trigger onUncheck events
*
* @public
*/
uncheckAll: function() {
$(this.element).find('input:checkbox:checked').attr('checked', false).change();
},
/**
* Default options values
*/
options: {
/**
* Defines if tree has collapse capability.
*/
collapsable: true,
/**
* Defines an element of DOM that, if clicked, trigger collapseAll() method.
* Value can be either a jQuery object or a selector string.
* @deprecated will be removed in jquery 0.6.
*/
collapseAllElement: '',
/**
* Defines duration of collapse effect in ms.
* Works only if collapseEffect is not null.
*/
collapseDuration: 500,
/**
* Defines the effect used for collapse node.
*/
collapseEffect: 'blind',
/**
* Defines URL of image used for collapse anchor.
* @deprecated will be removed in jquery 0.6.
*/
collapseImage: '',
/**
* Defines jQueryUI icon class used for collapse anchor.
*/
collapseUiIcon: 'ui-icon-triangle-1-e',
// dataSourceType: '',
// dataSourceUrl: '',
/**
* Defines an element of DOM that, if clicked, trigger expandAll() method.
* Value can be either a jQuery object or a selector string.
* @deprecated will be removed in jquery 0.6.
*/
expandAllElement: '',
/**
* Defines duration of expand effect in ms.
* Works only if expandEffect is not null.
*/
expandDuration: 500,
/**
* Defines the effect used for expand node.
*/
expandEffect: 'blind',
/**
* Defines URL of image used for expand anchor.
* @deprecated will be removed in jquery 0.6.
*/
expandImage: '',
/**
* Defines jQueryUI icon class used for expand anchor.
*/
expandUiIcon: 'ui-icon-triangle-1-se',
/**
* Defines if checked node are collapsed or not at tree initializing.
*/
initializeChecked: 'expanded', // or 'collapsed'
/**
* Defines if unchecked node are collapsed or not at tree initializing.
*/
initializeUnchecked: 'expanded', // or 'collapsed'
/**
* Defines URL of image used for leaf anchor.
* @deprecated will be removed in jquery 0.6.
*/
leafImage: '',
/**
* Defines jQueryUI icon class used for leaf anchor.
*/
leafUiIcon: '',
/**
* Defines which actions trigger when a node is checked.
* Actions are triggered in the following order:
* 1) node
* 2) others
* 3) descendants
* 4) ancestors
*/
onCheck: {
/**
* Defines action to perform on ancestors of the checked node.
* Available values: null, 'check', 'uncheck', 'checkIfFull'.
*/
ancestors: 'check',
/**
* Defines action to perform on descendants of the checked node.
* Available values: null, 'check', 'uncheck'.
*/
descendants: 'check',
/**
* Defines action to perform on checked node.
* Available values: null, 'collapse', 'expand'.
*/
node: '',
/**
* Defines action to perform on each other node (checked one excluded).
* Available values: null, 'check', 'uncheck'.
*/
others: ''
},
/**
* Defines which actions trigger when a node is unchecked.
* Actions are triggered in the following order:
* 1) node
* 2) others
* 3) descendants
* 4) ancestors
*/
onUncheck: {
/**
* Defines action to perform on ancestors of the unchecked node.
* Available values: null, 'check', 'uncheck'.
*/
ancestors: '',
/**
* Defines action to perform on descendants of the unchecked node.
* Available values: null, 'check', 'uncheck'.
*/
descendants: 'uncheck',
/**
* Defines action to perform on unchecked node.
* Available values: null, 'collapse', 'expand'.
*/
node: '',
/**
* Defines action to perform on each other node (unchecked one excluded).
* Available values: null, 'check', 'uncheck'.
*/
others: ''
}
}
});