Skip to content

Commit 55827b9

Browse files
committed
introduce support for separate readonly and disabled modes. closes select2#1253. fixes select2#778. closes select2#1183
1 parent c02ea3a commit 55827b9

1 file changed

Lines changed: 72 additions & 67 deletions

File tree

select2.js

Lines changed: 72 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ the specific language governing permissions and limitations under the Apache Lic
609609

610610
// abstract
611611
init: function (opts) {
612-
var results, search, resultsSelector = ".select2-results", mask;
612+
var results, search, resultsSelector = ".select2-results", disabled, readonly;
613613

614614
// prepare options
615615
this.opts = opts = this.prepareOpts(opts);
@@ -622,7 +622,6 @@ the specific language governing permissions and limitations under the Apache Lic
622622
this.destroy();
623623
}
624624

625-
this.enabled=true;
626625
this.container = this.createContainer();
627626

628627
this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
@@ -710,7 +709,13 @@ the specific language governing permissions and limitations under the Apache Lic
710709
this.monitorSource();
711710
}
712711

713-
if (opts.element.is(":disabled") || opts.element.is("[readonly='readonly']")) this.disable();
712+
var disabled = opts.element.prop("disabled");
713+
if (disabled === undefined) disabled = false;
714+
this.enable(!disabled);
715+
716+
var readonly = opts.element.prop("readonly");
717+
if (readonly === undefined) readonly = false;
718+
this.readonly(readonly);
714719

715720
// Calculate size of scrollbar
716721
scrollBarDimensions = scrollBarDimensions || measureScrollbar();
@@ -937,19 +942,15 @@ the specific language governing permissions and limitations under the Apache Lic
937942

938943
// sync enabled state
939944

940-
enabled = this.opts.element.attr("disabled") !== "disabled";
941-
readonly = this.opts.element.attr("readonly") === "readonly";
942-
943-
enabled = enabled && !readonly;
945+
//console.log("sync enabled: ", this._enabled, "readonly: ", this._readonly);
944946

945-
if (this.enabled !== enabled) {
946-
if (enabled) {
947-
this.enable();
948-
} else {
949-
this.disable();
950-
}
951-
}
947+
var disabled = el.prop("disabled");
948+
if (disabled === undefined) disabled = false;
949+
this.enable(!disabled);
952950

951+
var readonly = el.prop("readonly");
952+
if (readonly === undefined) readonly = false;
953+
this.readonly(readonly);
953954

954955
syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
955956
this.container.addClass(evaluate(this.opts.containerCssClass));
@@ -1008,24 +1009,46 @@ the specific language governing permissions and limitations under the Apache Lic
10081009
this.opts.element.blur();
10091010
},
10101011

1012+
//abstract
1013+
isInterfaceEnabled: function()
1014+
{
1015+
return this.enabledInterface === true;
1016+
},
1017+
10111018
// abstract
1012-
enable: function() {
1013-
if (this.enabled) return;
1019+
enableInterface: function() {
1020+
var enabled = this._enabled && !this._readonly,
1021+
disabled = !enabled;
10141022

1015-
this.enabled=true;
1016-
this.container.removeClass("select2-container-disabled");
1017-
this.opts.element.removeAttr("disabled");
1023+
if (enabled === this.enabledInterface) return false;
1024+
1025+
this.container.toggleClass("select2-container-disabled", disabled);
1026+
this.close();
1027+
this.enabledInterface = enabled;
1028+
1029+
return true;
10181030
},
10191031

10201032
// abstract
1021-
disable: function() {
1022-
if (!this.enabled) return;
1033+
enable: function(enabled) {
1034+
if (enabled === undefined) enabled = true;
1035+
if (this._enabled === enabled) return false;
1036+
this._enabled = enabled;
10231037

1024-
this.close();
1038+
this.opts.element.prop("disabled", !enabled);
1039+
this.enableInterface();
1040+
return true;
1041+
},
10251042

1026-
this.enabled=false;
1027-
this.container.addClass("select2-container-disabled");
1028-
this.opts.element.attr("disabled", "disabled");
1043+
// abstract
1044+
readonly: function(enabled) {
1045+
if (enabled === undefined) enabled = false;
1046+
if (this._readonly === enabled) return false;
1047+
this._readonly = enabled;
1048+
1049+
this.opts.element.prop("readonly", enabled);
1050+
this.enableInterface();
1051+
return true;
10291052
},
10301053

10311054
// abstract
@@ -1659,21 +1682,10 @@ the specific language governing permissions and limitations under the Apache Lic
16591682
},
16601683

16611684
// single
1662-
disable: function() {
1663-
if (!this.enabled) return;
1664-
1665-
this.parent.disable.apply(this, arguments);
1666-
1667-
this.focusser.attr("disabled", "disabled");
1668-
},
1669-
1670-
// single
1671-
enable: function() {
1672-
if (this.enabled) return;
1673-
1674-
this.parent.enable.apply(this, arguments);
1675-
1676-
this.focusser.removeAttr("disabled");
1685+
enableInterface: function() {
1686+
if (this.parent.enableInterface.apply(this, arguments)) {
1687+
this.focusser.prop("disabled", !this.isInterfaceEnabled());
1688+
}
16771689
},
16781690

16791691
// single
@@ -1741,7 +1753,7 @@ the specific language governing permissions and limitations under the Apache Lic
17411753
this.focusser.attr("tabindex", this.elementTabIndex);
17421754

17431755
this.search.bind("keydown", this.bind(function (e) {
1744-
if (!this.enabled) return;
1756+
if (!this.isInterfaceEnabled()) return;
17451757

17461758
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
17471759
// prevent the page from scrolling
@@ -1778,7 +1790,7 @@ the specific language governing permissions and limitations under the Apache Lic
17781790
}));
17791791

17801792
this.focusser.bind("keydown", this.bind(function (e) {
1781-
if (!this.enabled) return;
1793+
if (!this.isInterfaceEnabled()) return;
17821794

17831795
if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
17841796
return;
@@ -1814,7 +1826,7 @@ the specific language governing permissions and limitations under the Apache Lic
18141826
}));
18151827

18161828
selection.delegate("abbr", "mousedown", this.bind(function (e) {
1817-
if (!this.enabled) return;
1829+
if (!this.isInterfaceEnabled()) return;
18181830
this.clear();
18191831
killEventImmediately(e);
18201832
this.close();
@@ -1826,7 +1838,7 @@ the specific language governing permissions and limitations under the Apache Lic
18261838

18271839
if (this.opened()) {
18281840
this.close();
1829-
} else if (this.enabled) {
1841+
} else if (this.isInterfaceEnabled()) {
18301842
this.open();
18311843
}
18321844

@@ -2198,7 +2210,7 @@ the specific language governing permissions and limitations under the Apache Lic
21982210
.attr('for', this.search.attr('id'));
21992211

22002212
this.search.bind("input paste", this.bind(function() {
2201-
if (!this.enabled) return;
2213+
if (!this.isInterfaceEnabled()) return;
22022214
if (!this.opened()) {
22032215
this.open();
22042216
}
@@ -2207,7 +2219,7 @@ the specific language governing permissions and limitations under the Apache Lic
22072219
this.search.attr("tabindex", this.elementTabIndex);
22082220

22092221
this.search.bind("keydown", this.bind(function (e) {
2210-
if (!this.enabled) return;
2222+
if (!this.isInterfaceEnabled()) return;
22112223

22122224
if (e.which === KEY.BACKSPACE && this.search.val() === "") {
22132225
this.close();
@@ -2286,7 +2298,7 @@ the specific language governing permissions and limitations under the Apache Lic
22862298
}));
22872299

22882300
this.container.delegate(selector, "mousedown", this.bind(function (e) {
2289-
if (!this.enabled) return;
2301+
if (!this.isInterfaceEnabled()) return;
22902302
if ($(e.target).closest(".select2-search-choice").length > 0) {
22912303
// clicked inside a select2 search choice, do not open
22922304
return;
@@ -2298,7 +2310,7 @@ the specific language governing permissions and limitations under the Apache Lic
22982310
}));
22992311

23002312
this.container.delegate(selector, "focus", this.bind(function () {
2301-
if (!this.enabled) return;
2313+
if (!this.isInterfaceEnabled()) return;
23022314
this.container.addClass("select2-container-active");
23032315
this.dropdown.addClass("select2-drop-active");
23042316
this.clearPlaceholder();
@@ -2312,21 +2324,10 @@ the specific language governing permissions and limitations under the Apache Lic
23122324
},
23132325

23142326
// multi
2315-
enable: function() {
2316-
if (this.enabled) return;
2317-
2318-
this.parent.enable.apply(this, arguments);
2319-
2320-
this.search.removeAttr("disabled");
2321-
},
2322-
2323-
// multi
2324-
disable: function() {
2325-
if (!this.enabled) return;
2326-
2327-
this.parent.disable.apply(this, arguments);
2328-
2329-
this.search.attr("disabled", true);
2327+
enableInterface: function() {
2328+
if (this.parent.enableInterface.apply(this, arguments)) {
2329+
this.search.prop("disabled", !this.isInterfaceEnabled());
2330+
}
23302331
},
23312332

23322333
// multi
@@ -2508,7 +2509,7 @@ the specific language governing permissions and limitations under the Apache Lic
25082509
choice.find(".select2-search-choice-close")
25092510
.bind("mousedown", killEvent)
25102511
.bind("click dblclick", this.bind(function (e) {
2511-
if (!this.enabled) return;
2512+
if (!this.isInterfaceEnabled()) return;
25122513

25132514
$(e.target).closest(".select2-search-choice").fadeOut('fast', this.bind(function(){
25142515
this.unselect($(e.target));
@@ -2518,7 +2519,7 @@ the specific language governing permissions and limitations under the Apache Lic
25182519
})).dequeue();
25192520
killEvent(e);
25202521
})).bind("focus", this.bind(function () {
2521-
if (!this.enabled) return;
2522+
if (!this.isInterfaceEnabled()) return;
25222523
this.container.addClass("select2-container-active");
25232524
this.dropdown.addClass("select2-drop-active");
25242525
}));
@@ -2784,7 +2785,9 @@ the specific language governing permissions and limitations under the Apache Lic
27842785
var args = Array.prototype.slice.call(arguments, 0),
27852786
opts,
27862787
select2,
2787-
value, multiple, allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "disable", "positionDropdown", "data"];
2788+
value, multiple,
2789+
allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "readonly", "positionDropdown", "data"],
2790+
valueMethods = ["val", "opened", "isFocused", "container", "data"];
27882791

27892792
this.each(function () {
27902793
if (args.length === 0 || typeof(args[0]) === "object") {
@@ -2814,7 +2817,9 @@ the specific language governing permissions and limitations under the Apache Lic
28142817
} else {
28152818
value = select2[args[0]].apply(select2, args.slice(1));
28162819
}
2817-
if (value !== undefined) {return false;}
2820+
if (indexOf(args[0], valueMethods) >= 0) {
2821+
return false;
2822+
}
28182823
} else {
28192824
throw "Invalid arguments to select2 plugin: " + args;
28202825
}

0 commit comments

Comments
 (0)