Files
BACHIR SOULDI 2794e62571 first commit
2025-09-28 08:49:37 +01:00

152 lines
4.1 KiB
JavaScript

/**
* ngModelOptions v1.0.1: ngModelOptions for AngularJS 1.2
*
* @author Fergal Doyle
* @url https://github.com/fergaldoyle/modelOptions
* @license MIT
*/
angular.module("modelOptions", []).directive("ngModelOptions", function () {
return {
priority: 1,
restrict: "A",
//require: "ngModel",
require: ['ngModel'/*, '^?select'*/],
link: function (scope, elm, attr, ctrls) {
function apply() {
var value;
switch (tagType) {
case "inputradio":
if (attr.ngValue) {
value = scope.$eval(attr.ngValue);
} else {
value = elm.val();
}
break;
case "inputcheckbox":
value = elm.prop("checked");
break;
case "select":
value = getSelectOption();
break;
default:
value = elm.val();
if (!attr.ngTrim || attr.ngTrim.toLowerCase() !== "false") {
value = value.replace(/^\s+|\s+$/g, "");
}
}
scope.$apply(function () {
ctrls[0].$setViewValue(value);
});
}
function getSelectOption() {
if (!attr.ngOptions) {
throw "Must have ng-options";
}
var match = attr.ngOptions.match(NG_OPTIONS_REGEXP),
track = match[8],
valuesName = match[7],
values = scope.$eval(valuesName),
index,
val = elm.val();
// if track by is specified
// use the track by value as
// a key to find the index
if (track) {
angular.forEach(values, function (item, i) {
if (item[track.replace(/^.*?\./, "")] == val) {
index = i;
}
});
} else {
index = val;
}
// value is a property of an object
if (/.*\..*/.test(match[1])) {
return scope.$eval(match[1].replace(/^.*?\./, valuesName + "[" + index + "]."));
} else { // value is an object
return values[index];
}
}
var timer,
NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/,
tagType = elm[0].nodeName.toLowerCase() + (attr.type || ""),
defaultEvents = [],
defaults = {
debounce: 0,
updateOn: "default"
},
options = angular.extend(defaults, scope.$eval(attr.ngModelOptions)),
multiDebounce = typeof options.debounce === "object",
updateOnSplit = options.updateOn.split(" ");
if (tagType === "inputtext" || tagType === "textarea") {
defaultEvents = ["keydown", "input", "change"];
} else if (tagType === "inputradio" || tagType === "inputcheckbox") {
defaultEvents = ["click"];
} else if (tagType === "select") {
defaultEvents = ["change"];
} else {
defaultEvents = ["keydown", "input", "change"];
}
// unbind default events to prevent automatic model updates
angular.forEach(defaultEvents, function (event) {
// ie8 does not support some events
// use try catch to mask this
try { elm.off(event); } catch (e) { }
});
// default events
if (options.updateOn.match(/default/i)) {
elm.on(defaultEvents.join(" "), function (e) {
var delay = options.debounce["default"] || options.debounce || 0;
clearTimeout(timer);
timer = setTimeout(function () {
apply();
}, delay);
});
}
// the other events if specified
angular.forEach(updateOnSplit, function (event) {
if (event === "default") {
return;
}
// debounce option can be number or object
var deb;
if (multiDebounce) {
deb = options.debounce[event];
} else {
deb = options.debounce;
}
var delay = deb;
if (typeof delay === "undefined") {
delay = options.debounce["default"] || 0;
}
elm.on(event, function (e) {
clearTimeout(timer);
timer = setTimeout(function () {
apply();
}, delay);
});
});
}
};
});