-
Notifications
You must be signed in to change notification settings - Fork 0
/
jquery.neatList.js
executable file
·123 lines (103 loc) · 4.72 KB
/
jquery.neatList.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
(function ($) {
function toggleListDisplay($list) {
if ($list.children().length)
$list.show();
else
$list.hide();
}
function initBackingSelect($select) {
$select.hide();
}
function initAddSelect($select, $backingSelect) {
$select
.children().remove().end() //delete existing <option>s
.append($backingSelect.children().clone().removeAttr("selected")) //copy the backing options, remove any selection
.prepend("<option>(select to add)</option>") // default caption
.prop("selectedIndex", 0);
}
function initSelectedList($list, $backingSelect, deleteSrc) {
$list.children().remove(); //clear existing items
//create a new list item for each selected backing list item
$backingSelect.children(":selected").each(function () {
addListItemFromOption($list, $(this), false, deleteSrc);
});
toggleListDisplay($list);
}
function addListItemFromOption($list, $option, animate, deleteSrc) {
//check to see if the item already exist
if ($list.children().is("[data-value=" + $option.val() + "]"))
return;
// create a new <li>, bind according to the <option>, and add it to the list
var $item = $("<li><span></span><input type='image' /></li>")
.hide()
.attr("data-value", $option.val())
.find("span").text($option.text()).end()
.find("input").val($option.val()).attr("src", deleteSrc).end()
.appendTo($list);
toggleListDisplay($list);
animate ? $item.slideDown() : $item.show();
}
function selectOption($option, $selectedList, $backingSelect, animate, deleteSource) {
addListItemFromOption($selectedList, $option, animate, deleteSource);
$backingSelect.children("[value=" + $option.val() + "]").attr("selected", "selected")
}
function deselectListItem($listItem, $backingSelect, animate) {
var removeListWork = function () {
var $list = $listItem.parents("ul");
$listItem.remove();
toggleListDisplay($list);
};
animate ? $listItem.slideUp(function () { removeListWork(); }) : removeListWork();
$backingSelect.children("[value=" + $listItem.attr("data-value") + "]").removeAttr("selected");
}
$.fn.neatList = function (options) {
//call a public method if a string is passed
if (typeof (options) === "string")
return $(this).data("methods")[options]();
var options = $.extend({
animate: true,
deleteButtonSrc: ""
}, options);
return $(this).each(function () {
//create supporting dom elements
var $backingSelect = $(this),
$containerDiv = $("<div />").addClass("neatList").insertBefore($backingSelect).append($backingSelect),
$selectedList = $("<ul />").appendTo($containerDiv),
$addSelect = $("<select />").appendTo($containerDiv);
$addSelect.change(function () {
selectOption($(this).children("option:selected"), $selectedList, $backingSelect, options.animate, options.deleteButtonSrc);
$(this).prop("selectedIndex", 0);
$backingSelect.trigger("change");
});
$selectedList.delegate("li > input", "click", function (e) {
e.preventDefault();
deselectListItem($(this).parents("li"), $backingSelect, options.animate);
$backingSelect.trigger("change");
});
var init = false;
//public methods
var methods = {
refresh: function () {
if (options.animate && init) {
$containerDiv.fadeOut(function () {
methods.refreshWithoutAnimation();
$containerDiv.fadeIn();
});
}
else
methods.refreshWithoutAnimation();
},
refreshWithoutAnimation: function() {
init = true;
initBackingSelect($backingSelect);
initAddSelect($addSelect, $backingSelect);
initSelectedList($selectedList, $backingSelect, options.deleteButtonSrc);
}
};
//store the public methods for later use
$backingSelect.data("methods", methods);
//get everything started
methods.refresh();
});
};
})(jQuery);