Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 90 additions & 69 deletions jquery.chained.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,83 +18,104 @@

$.fn.chained = function(parent_selector, options) {

return this.each(function() {

/* Save this to child because this changes when scope changes. */
var child = this;
var backup = $(child).clone();
return this.each(
function( index, element ) {

/* Save this to child because this changes when scope changes. */
var child = element;
var backup = $(child).clone();

/* Handles maximum two parents now. */
$(parent_selector).each( function( index, element ) {
$(element).bind("change", function() {
updateChildren();
});

/* Force IE to see something selected on first page load, */
/* unless something is already selected */
if (!$("option:selected", element).length) {
$("option", element).first().attr("selected", "selected");
}

/* Handles maximum two parents now. */
$(parent_selector).each(function() {
$(this).bind("change", function() {
/* Force updating the children. */
updateChildren();
});

/* Force IE to see something selected on first page load, */
/* unless something is already selected */
if (!$("option:selected", this).length) {
$("option", this).first().attr("selected", "selected");
}

/* Force updating the children. */
updateChildren();
});

function updateChildren() {
var trigger_change = true;
var currently_selected_value = $("option:selected", child).val();

$(child).html(backup.html());

/* If multiple parents build classname like foo\bar. */
var selected = "";
$(parent_selector).each(function() {
var selectedClass = $("option:selected", this).val();
if (selectedClass) {
if (selected.length > 0) {
if (window.Zepto) {
/* Zepto class regexp dies with classes like foo\bar. */
selected += "\\\\";
} else {
selected += "\\";
} );

function updateChildren() {
var trigger_change = true;
var currently_selected_value = $("option:selected", child).val();

$(child).html(backup.html());

/* If multiple parents build classname like foo\bar. */
var selected = "";
$(parent_selector).each(function() {
var selectedClass = $("option:selected", this).val();
if (selectedClass) {
if (selected.length > 0) {
if (window.Zepto) {
/* Zepto class regexp dies with classes like foo\bar. */
selected += "\\\\";
} else {
selected += "\\";
}
}
selected += selectedClass;
}
selected += selectedClass;
}
});

/* Also check for first parent without subclassing. */
/* TODO: This should be dynamic and check for each parent */
/* without subclassing. */
var first;
if ($.isArray(parent_selector)) {
first = $(parent_selector[0]).first();
} else {
first = $(parent_selector).first();
}
var selected_first = $("option:selected", first).val();

$("option", child).each(function() {
/* Remove unneeded items but save the default value. */
if ($(this).hasClass(selected) && $(this).val() === currently_selected_value) {
$(this).prop("selected", true);
trigger_change = false;
} else if (!$(this).hasClass(selected) && !$(this).hasClass(selected_first) && $(this).val() !== "") {
$(this).remove();
});

/* Also check for first parent without subclassing. */
/* TODO: This should be dynamic and check for each parent */
/* without subclassing. */
var first;
if ($.isArray(parent_selector)) {
first = $(parent_selector[0]).first();
} else {
first = $(parent_selector).first();
}
});
var selected_first = $("option:selected", first).val();

$("option", child).each( function( index, element ) {
var hasprop = false;
var isselfirst = false;
var e = $(element);
if ( e.attr('data-chained') ) {
var d = e.data( 'chained' );
if ( d == selected ) {
hasprop = true;
}
if ( d == selected_first ) {
isselfirst = true;
}
} else {
if ( $(element).hasClass( selected ) ) {
hasprop = true;
}
if ( e.hasClass(selected_first) ) {
isselfirst = true;
}
}
/* Remove unneeded items but save the default value. */
if ( hasprop && e.val() === currently_selected_value) {
e.prop("selected", true);
trigger_change = false;
} else if (!hasprop && !isselfirst && e.val() !== "") {
e.remove();
}
} );

/* If we have only the default value disable select. */
if (1 === $("option", child).size() && $(child).val() === "") {
$(child).attr("disabled", "disabled");
} else {
$(child).removeAttr("disabled");
}
if (trigger_change) {
$(child).trigger("change");
/* If we have only the default value disable select. */
if (1 === $("option", child).size() && $(child).val() === "") {
$(child).attr("disabled", "disabled");
} else {
$(child).removeAttr("disabled");
}
if (trigger_change) {
$(child).trigger("change");
}
}
}
});
);
};

/* Alias for those who like to use more English like syntax. */
Expand Down
2 changes: 1 addition & 1 deletion jquery.chained.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.