UNPKG

magix-components

Version:
446 lines 13.1 kB
/* ver:1.3.1 */ let $ = require('$'); let Magix = require('magix'); Magix.applyStyle('@index.less'); let ByteLen = (str) => { return str.replace(/[^\x00-\xff]/g, 'xl').length; }; let Rules = { required(val, rule) { if (rule) { return $.trim(val); } return true; }, number(val, rule) { val = $.trim(val); if (val && rule) { if (val.indexOf('.') != val.lastIndexOf('.')) { //多个. return false; } return /^-?[\d\.]+$/.test(val); } return true; }, length(val, rule) { if (val.length < rule[0] || val.length > rule[1]) { return false; } return true; }, blength(val, rule) { let len = ByteLen(val); if (len < rule[0] || len > rule[1]) { return false; } return true; }, minLength(val, rule) { val = $.trim(val); if (val && val.length < rule) { return false; } return true; }, maxLength(val, rule) { val = $.trim(val); if (val && val.length > rule) { return false; } return true; }, range(val, rule) { val = parseFloat(val); if (isNaN(val)) { return false; } if (val < rule[0] || val > rule[1]) { return false; } return true; }, equalto(val, rule) { let to = $(rule).val(); return to == val; }, pattern(val, rule) { val = $.trim(val); if (val) { let reg = new RegExp(rule); return reg.test(val); } return true; }, max(val, rule) { if (+val > +rule) { return false; } return true; }, min(val, rule) { if (+val < +rule) { return false; } return true; } }; let Msgs = { required() { return '必填'; }, number() { return '数字'; }, length(rule, value) { return rule[0] + '-' + rule[1] + '个字之间,当前:' + value.length; }, blength(rule, value) { return rule[0] + '-' + rule[1] + '个字符之间,当前:' + ByteLen(value); }, range(rule) { return rule[0] + '-' + rule[1] + '之间的数字'; }, equalto(rule) { return '与' + rule + '同样的内容'; }, pattern() { return '格式有误'; }, minLength(rule) { return '最小长度:' + rule; }, maxLength(rule) { return '最大长度:' + rule; }, max(rule) { return '不能大于 ' + rule; }, min(rule) { return '不能小于 ' + rule; } }; let isValid = (actions, val) => { let f = true, r, v; for (let a in actions) { if (Magix.has(actions, a)) { let rule = Rules[a]; if (rule) { f = rule(val, v = actions[a]); if (!f) { r = a; break; } } } } return { f, v, a: val, r }; }; let showError = (ssId, key, rule, value) => { let node = $('[mx-ssid="' + ssId + '"]'); if (!node.length) return; node.addClass('@index.less:fail'); node.each((i, n) => { n = $(n); let id = n.attr('id'); if (!id) { id = Magix.guid(); n.attr('id', id); } let msgId = id + '_msg'; let msgNode = $('#' + msgId); if (!msgNode.length) { let prt = n.parent(); let pos = prt.css('position'); if (pos == 'static') { prt.addClass('@scoped.style:pr'); } n.after('<div class="@index.less:msg" id="' + msgId + '"/>'); msgNode = $('#' + msgId); } msgNode.html(Msgs[key](rule, value)).show(); let width = n.outerWidth() - 3; let mWidth = msgNode.width(); let pos = n.position(); msgNode.css({ top: pos.top + 2, left: pos.left + width - mWidth }); }); return true; }; let hideError = ssId => { let node = $('[mx-ssid="' + ssId + '"]'); node.removeClass('@index.less:fail'); node.each((i, n) => { n = $(n); let msgId = n.attr('id') + '_msg'; $('#' + msgId).hide(); }); }; let callUserEvent = (e, view) => { let params = e.params; if (params.m) { let userEventName = params.m + '\x1e' + e.type; let userEventFN = view[userEventName]; if (userEventFN) { e.params = params.a; userEventFN.call(view, e); } } }; module.exports = { fromKeys(data, keys) { keys = (keys + '').split(','); var r = {}; for (var i = 0, key; i < keys.length; i++) { key = keys[i]; r[key] = Magix.has(data, key) ? data[key] : ''; } return r; }, isValid(ref) { let me = this; let result = true; let children = me.owner.children(); let topLevel = false; if (!ref) { ref = []; topLevel = true; } for (let i = 0; i < children.length; i++) { let vf = Magix.Vframe.get(children[i]); let r = vf.invoke('isValid', [ref]); if (r === false) { result = false; } } let elements = $('#' + me.id + ' [mx-ssid^="' + me.id + '"]'); elements.each((i, e) => { $(e).trigger({ type: 'change', from: 'faker' }); }); let form = me.updater.$form; if (form) { let keys = Magix.keys(form); if (keys.length) { ref.push(keys[0]); result = false; } } if (topLevel) { let minTop = 1e20, node; for (let i = ref.length, n, f; i--;) { n = $('[mx-ssid="' + ref[i] + '"]'); if (n.length) { f = n.offset(); if (f.top < minTop) { node = n[0]; minTop = f.top; } } } if (node) { if (node.scrollIntoViewIfNeeded) { node.scrollIntoViewIfNeeded(); } else if (node.scrollIntoView) { node.scrollIntoView(); } } } return result; }, triggerParent(values) { let rootNode = $('#' + this.id); rootNode.trigger({ type: 'change', from: 'subview', values }); }, '@{sync.value.from.ui}<focusin>'(e) { e.stopPropagation(); let node = $(e.eventTarget); hideError(node.attr('mx-ssid')); callUserEvent(e, this); }, '@{sync.value.from.ui}<focusout>'(e) { e.stopPropagation();//停掉冒泡,防止父view的监听 let node = $(e.eventTarget); node.trigger({ type: 'change', from: 'faker' }); callUserEvent(e, this); }, '@{sync.value.from.ui}<change>'(e) { let me = this, node = $(e.eventTarget); let last = node.prop('_lt'); let now = Date.now(); if (last && (now - last) < 10) return; node.prop('_lt', now); if (e.viewId) { if (e.viewId != me.id) return; } e.viewId = me.id; let faker = e.from == 'faker' || e.from == 'subview'; //if (faker) { e.stopPropagation(); //模拟的直接停掉 //} let params = e.params; let updater = me.updater; if (!updater.$form) { updater.$form = {}; } let form = updater.$form; let keys = updater.$keys; let ctrls = params.c ? params.c.slice() : [params]; let refresh = false; let valid = true; let rootNode = $('#' + me.id); rootNode.removeAttr('mx-ssid'); let notify = false; let addCheckbox = (name, src, actions) => { $('input[name="' + name + '"]:checked').each(function (idx, item) { let value = item.value; if (actions.number) { value = parseFloat(value); } idx = src.indexOf(value); if (idx === -1) { src.push(value); } }); }; while (ctrls.length) { let ctrl = ctrls.shift(); let ps = ctrl.p.split('.'); let actions = ctrl.f || {}; let key = ps.pop(), temp, value, rootKey; let object = updater.get(); while (object && ps.length) { temp = ps.shift(); if (!rootKey) rootKey = temp; //解决设置数据后,再调用updater.digest()不刷新的问题 object = object[temp]; } rootKey = rootKey || key; if (e.from == 'subview') { value = e.values[actions.from || key]; } else if (node.prop('type') == 'checkbox') { let src = object[key]; let checked = node.prop('checked'); if (src === true || src === false) { value = checked; } else { value = node.val(); if (actions.number) { value = parseFloat(value); } if ($.isArray(src)) { let checkboxName = node.prop('name'); if (checkboxName) { src = []; addCheckbox(checkboxName, src, actions); } else { value = node.val(); if (actions.number) { value = parseFloat(value); } let idx = src.indexOf(value); if (checked) { if (idx === -1) { src.push(value); } } else { if (idx > -1) { src.splice(idx, 1); } } } value = src; } else if ($.isPlainObject(src)) { if (checked) { src[value] = value; } else { delete src[value]; } value = src; } else { value = checked ? value : ''; } } } else { value = node.val(); if (actions.number) { value = parseFloat(value); } } if (object) { if (object[key] !== value) { object[key] = value; if (actions.refresh) { refresh = true; } if (refresh || !actions.silent) {//如果刷新或未标记沉默更新 keys[rootKey] = 1; //标记改变; } notify = true; } } else { console.warn('can not set by path:', ctrl.p); } if (valid) { let v = isValid(actions, value); let ssId = node.attr('mx-ssid'); if (v.f) { delete form[ssId]; hideError(ssId); } else { form[ssId] = v; valid = false; showError(ssId, v.r, v.v, v.a); } } } if (valid && refresh) { updater.digest(); } if (notify) { me.triggerParent(updater.get()); } if (!faker) { callUserEvent(e, me); } }, '$doc<htmlchanged>'(e) { let me = this; let form = me.updater.$form; if (e.vId == me.id) { clearTimeout(me['@{change.delay.timer}']); me['@{change.delay.timer}'] = setTimeout(me.wrapAsync(() => { if (form) { for (let f in form) { let v = form[f]; if (!showError(f, v.r, v.v, v.a)) { delete form[f]; } } } }), 0); } } };