/** * @name numberInput * @author HuangJunjie * @description layui 数值输入框扩展 * @version 2.0.3.20220623 */ layui.define(["jquery"], function (exports) { var $ = layui.jquery; var prefix = "number-input"; /** * 链接外部样式文件 * 由 码云 @hulangfy 同学建议 */ layui.link(layui.cache.base + 'numberInput/css/theme.css'); /** * 创建样式列表 * @param names * @returns {string} */ function createClassList(flag, names) { if (typeof names == "string") names = [names]; var classList = []; names.forEach(function (name) { classList.push([prefix, flag].join("-")); classList.push([name, flag].join("-")); }); return classList.join(" "); } /** * 精度数字 * @param value * @param precision */ function ratioNumber(value, precision) { if (precision === undefined) precision = 0; var floatVal = parseFloat(value) || 0; var ratio = Math.pow(10, precision); return ((floatVal * ratio) / ratio).toFixed(precision); } /** * 检查是否包含特定属性 * @param {*} $el * @param {*} attr * @returns */ function hasAttr($el, attr) { var attrs = $el[0].attributes; for (var i = 0; i < attrs.length; i++) { if (attrs[i].name === attr) { return attrs[i].value !== "false"; } } return false; } /** * 初始化操作 * @param id * @param opts */ function render(id, opts) { if (!opts) opts = {}; // 绑定Dom $(id).each(function () { (function ($input) { var $target = $input.parent(); // 取出配置 var max = parseFloat(opts.max || $input.data("max")) || 999999999; var min = parseFloat(opts.min || $input.data("min")) || 0; var precision = parseInt(opts.precision || $input.data("precision")) || 0; var ratio = Math.pow(10, precision); var step = opts.step ? parseFloat(opts.step || $input.date("step")) : ((parseFloat(opts.step) || 1) / ratio); var skin = opts.skin || "auto"; var iconAdd = opts.iconAdd || $input.data("icon-add") || "layui-icon layui-icon-addition"; var iconSubtract = opts.iconSubtract || $input.data("icon-subtract") || "layui-icon layui-icon-subtraction"; var width = opts.width || $input.data("width") || 100; var allowEmpty = opts.allowEmpty || hasAttr($input, "data-allow-empty") || false; var autoSelect = opts.autoSelect || hasAttr($input, "data-auto-select") || false; var setDefaultValue = opts.defaultValue || $input.val() || (hasAttr($input, "data-default-value") ? $input.attr("data-default-value") : ""); var defaultEmptyValue = opts.defaultEmptyValue || false; var defaultValue = ratioNumber(parseFloat(setDefaultValue) || 0, precision); if (defaultEmptyValue && setDefaultValue.length === 0) defaultValue = ""; var readonly = opts.readonly || $input.attr("readonly") || false; var disabled = opts.disabled || $input.attr("disabled") || false; var handleEvent = opts.handleEvent || "input"; // 激活指定事件 function activeEvent(name, event, dom, value, tree) { if (opts.event && typeof opts.event[name] == "function") { return opts.event[name](event, dom, value, tree); } else { return false; } } // 开始组装DOM activeEvent("beforeCreated"); // 绑定元素 var $container = $('
'); var $subtract = $('').append($('')); var $add = $('').append($('')); $input.addClass(createClassList("input", skin)); // DOM集合 var $dom = { input: $input, subtract: $subtract, add: $add, container: $container, }; // 自动全选 $input.on("focus", function (event) { activeEvent("focus", event, $input, $input.val(), $dom); if (autoSelect) $input.select() }); $input.on("select", function (event) { activeEvent("select", event, $input, $input.val(), $dom); }); // 处理逻辑 $input .val(defaultValue) .css({ width: width, }) .attr({ readonly: readonly, disabled: disabled }) .on(handleEvent, function (event) { var val = $(this).val(); var newVal = val; // 如果精度大于0 if (precision > 0) { newVal = val.replace(/[^\d\-\.]/g, ""); newVal = newVal.replace(/^\./, ""); newVal = newVal.replace(/\.{2,}$/g, "."); newVal = newVal.replace(/\-\./, "-"); newVal = newVal.replace(new RegExp("\\.(\\d{" + precision + "})\\d+", "g"), ".$1"); } else { newVal = newVal.replace(/[^\d\-]/g, ""); if (min >= 0) { newVal = newVal.replace(/^0([0-9])/, "$1"); } else { newVal = newVal.replace(/\-0{2}/, "-0"); newVal = newVal.replace(/\-0([0-9])/, "-$1"); } } // 不允许输入以0开头的整数 newVal = newVal.replace(/^0+/g, "0"); $(this).val(newVal); // 如果最小值小于零则不允许输入负数 if (min >= 0) { newVal = newVal.replace(/\-/g, ""); } // 只允许头部出现负号 var values = newVal.split(""); values.forEach(function (val, i) { if (val === "-" && i !== 0) { values.splice(i, 1); } }); newVal = values.join(""); if (newVal) { var floatVal = parseFloat(newVal); if (floatVal > max) { var maxVal = ratioNumber(max, precision); $(this).val(maxVal); activeEvent("change", event, $input, maxVal, $dom); activeEvent("input", event, $input, maxVal, $dom); return; } if (floatVal < min) { var minVal = ratioNumber(min, precision); $(this).val(minVal); activeEvent("change", event, $input, minVal, $dom); activeEvent("input", event, $input, minVal, $dom); return; } } $(this).val(newVal); activeEvent("change", event, $input, val, $dom); activeEvent("input", event, $input, val, $dom); }) .on("blur", function (event) { var val = $(this).val(); var newVal = 0; if (val.length === 0) { if (allowEmpty) { activeEvent("change", event, $input, val, $dom); activeEvent("blur", event, $input, val, $dom); } else { newVal = ratioNumber(defaultValue, precision); $(this).val(newVal); activeEvent("change", event, $input, newVal, $dom); activeEvent("blur", event, $input, newVal, $dom); } } else { newVal = ratioNumber(val, precision); $(this).val(newVal); activeEvent("change", event, $input, newVal, $dom); activeEvent("blur", event, $input, newVal, $dom); } }) .on("keypress", function (event) { activeEvent("keypress", event, $input, $input.val(), $dom); }).on("mousewheel", function (event) { activeEvent("mousewheel", event, $input, $input.val(), $dom); }); $subtract.on("click", function (event) { if (readonly || disabled) return; var val = $input.val(); var floatVal = parseFloat(val); var newVal = 0; if (floatVal - step >= min) { newVal = ratioNumber(floatVal - step, precision); $input.val(newVal); if (floatVal !== min) { activeEvent("change", event, $subtract, newVal, $dom); } else { activeEvent("toMin", event, $subtract, newVal, $dom); } } else { newVal = ratioNumber(min, precision); $input.val(newVal); if (floatVal === min) { activeEvent("toMin", event, $subtract, newVal, $dom); } else { activeEvent("change", event, $subtract, newVal, $dom); } } }); $add.on("click", function (event) { if (readonly || disabled) return; var val = $input.val(); var floatVal = parseFloat(val); var newVal = 0; if (floatVal + step <= max) { newVal = ratioNumber(floatVal + step, precision); $input.val(newVal); activeEvent("change", event, $add, newVal, $dom); } else { newVal = ratioNumber(max, precision); $input.val(newVal); if (floatVal === max) { activeEvent("toMax", event, $add, newVal, $dom); } else { activeEvent("change", event, $add, newVal, $dom); } } }); $container.append($subtract).append($input).append($add); activeEvent("created", $dom); $target.empty().append($container); activeEvent("mounted", $dom); })($(this)) }) } exports("numberInput", { render: render }); });