// 這個 BaRaBaRa 是以 jQuery 當作基礎的,所以記得 在此之前務必 引入 jQuery. // // we need something like sprintf // (function(window) { var re = { not_string: /[^s]/, number: /[def]/, text: /^[^\x25]+/, modulo: /^\x25{2}/, placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/, key: /^([a-z_][a-z_\d]*)/i, key_access: /^\.([a-z_][a-z_\d]*)/i, index_access: /^\[(\d+)\]/, sign: /^[\+\-]/ } function sprintf() { var key = arguments[0], cache = sprintf.cache if (!(cache[key] && cache.hasOwnProperty(key))) { cache[key] = sprintf.parse(key) } return sprintf.format.call(null, cache[key], arguments) } sprintf.format = function(parse_tree, argv) { var cursor = 1, tree_length = parse_tree.length, node_type = "", arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = "" for (i = 0; i < tree_length; i++) { node_type = get_type(parse_tree[i]) if (node_type === "string") { output[output.length] = parse_tree[i] } else if (node_type === "array") { match = parse_tree[i] // convenience purposes only if (match[2]) { // keyword argument arg = argv[cursor] for (k = 0; k < match[2].length; k++) { if (!arg.hasOwnProperty(match[2][k])) { throw new Error(sprintf("[sprintf] property '%s' does not exist", match[2][k])) } arg = arg[match[2][k]] } } else if (match[1]) { // positional argument (explicit) arg = argv[match[1]] } else { // positional argument (implicit) arg = argv[cursor++] } if (get_type(arg) == "function") { arg = arg() } if (re.not_string.test(match[8]) && (get_type(arg) != "number" && isNaN(arg))) { throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg))) } if (re.number.test(match[8])) { is_positive = arg >= 0 } switch (match[8]) { case "b": arg = arg.toString(2) break case "c": arg = String.fromCharCode(arg) break case "d": arg = parseInt(arg, 10) break case "e": arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential() break case "f": arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg) break case "o": arg = arg.toString(8) break case "s": arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg) break case "u": arg = arg >>> 0 break case "x": arg = arg.toString(16) break case "X": arg = arg.toString(16).toUpperCase() break } if (!is_positive || (re.number.test(match[8]) && match[3])) { sign = is_positive ? "+" : "-" arg = arg.toString().replace(re.sign, "") } pad_character = match[4] ? match[4] == "0" ? "0" : match[4].charAt(1) : " " pad_length = match[6] - (sign + arg).length pad = match[6] ? str_repeat(pad_character, pad_length) : "" output[output.length] = match[5] ? sign + arg + pad : (pad_character == 0 ? sign + pad + arg : pad + sign + arg) } } return output.join("") } sprintf.cache = {} sprintf.parse = function(fmt) { var _fmt = fmt, match = [], parse_tree = [], arg_names = 0 while (_fmt) { if ((match = re.text.exec(_fmt)) !== null) { parse_tree[parse_tree.length] = match[0] } else if ((match = re.modulo.exec(_fmt)) !== null) { parse_tree[parse_tree.length] = "%" } else if ((match = re.placeholder.exec(_fmt)) !== null) { if (match[2]) { arg_names |= 1 var field_list = [], replacement_field = match[2], field_match = [] if ((field_match = re.key.exec(replacement_field)) !== null) { field_list[field_list.length] = field_match[1] while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") { if ((field_match = re.key_access.exec(replacement_field)) !== null) { field_list[field_list.length] = field_match[1] } else if ((field_match = re.index_access.exec(replacement_field)) !== null) { field_list[field_list.length] = field_match[1] } else { throw new SyntaxError("[sprintf] failed to parse named argument key") } } } else { throw new SyntaxError("[sprintf] failed to parse named argument key") } match[2] = field_list } else { arg_names |= 2 } if (arg_names === 3) { throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported") } parse_tree[parse_tree.length] = match } else { throw new SyntaxError("[sprintf] unexpected placeholder") } _fmt = _fmt.substring(match[0].length) } return parse_tree } var vsprintf = function(fmt, argv, _argv) { _argv = (argv || []).slice(0) _argv.splice(0, 0, fmt) return sprintf.apply(null, _argv) } /** * helpers */ function get_type(variable) { return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase() } function str_repeat(input, multiplier) { return Array(multiplier + 1).join(input) } /** * export to either browser or node.js */ if (typeof exports !== "undefined") { exports.sprintf = sprintf exports.vsprintf = vsprintf } else { window.sprintf = sprintf window.vsprintf = vsprintf if (typeof define === "function" && define.amd) { define(function() { return { sprintf: sprintf, vsprintf: vsprintf } }) } } })(typeof window === "undefined" ? this : window) // // somthing attached to jQuery // jQuery.fn.outerHTML = function() { return jQuery('
').append(this.eq(0).clone()).html(); }; jQuery.fn.disabled = function(status) { jQuery(this).each(function(){ jQuery(this)[0].disabled=status; }) return; }; jQuery.fn.isDisabled = function(status) { return jQuery(this)[0].disabled; }; jQuery.fn.tagName = function() { return this.prop("tagName").toLowerCase(); }; var _wx_datsrc = {}; jQuery.fn.valByDatSrcSlef = function(){ if ($.isNothing($(this).wx("datsrc"))==false){ var out2html = ($(this).prop("tagName").toLowerCase()=="div" || $(this).prop("tagName").toLowerCase()=="span" || $(this).prop("tagName").toLowerCase()=="td" || $(this).prop("tagName").toLowerCase()=="a" || $(this).prop("tagName").toLowerCase()=="li"); if (out2html){ if ($.isNothing($(this).wx("value"))) jQuery(this).attr("wx-value",jQuery(this).html()); }else{ if ($.isNothing($(this).wx("value"))) jQuery(this).attr("wx-value",jQuery(this).val()); } if (jQuery(this).attr("wx-display")!=null){ //$.clog(jQuery(this).attr("wx-display")) var tmp = jQuery(this).attr("wx-display").split(','); var out = Array(); var match = jQuery(this).attr("wx-match"); //$.clog(match) if (match==null) match = "sn"; for(var i=0; i"+jQuery(this).attr("wx-datsrc")+"<"+jQuery(this).attr("wx-value")); if (jQuery.isNothing(_wx_datsrc[jQuery(this).attr("wx-datsrc")])===true){ // $.clog(typeof(_wx_datsrc[jQuery(this).attr("wx-datsrc")])); // $.clog(_wx_datsrc[jQuery(this).attr("wx-datsrc")]); // $.clog("bye"); return true; } // $.clog(_wx_datsrc[jQuery(this).attr("wx-datsrc")][jQuery(this).attr("wx-value")+""]); //jQuery(this).xval(_wx_datsrc[jQuery(this).attr("wx-datsrc")][jQuery(this).attr("wx-value")+""]); jQuery(this).val(_wx_datsrc[jQuery(this).attr("wx-datsrc")][jQuery(this).attr("wx-value")+""]); } } } return jQuery(this); } jQuery.fn.valByDatSrc = function(){ jQuery(this).find("[wx-datsrc]").each(function(){ jQuery(this).valByDatSrcSlef(); }); return jQuery(this); } jQuery.fn.xval =function(data,isori){ if (typeof(jQuery(this).prop("tagName"))=="undefined") return false; if (data==null){ // 取得 if (jQuery(this).prop("tagName").toLowerCase()=="span" || jQuery(this).prop("tagName").toLowerCase()=="div"){ if ($.isNothing(jQuery(this).attr("wx-value"))==true || isori==true){ return jQuery(this).html(); }else{ return jQuery(this).attr("wx-value"); } }else{ if ($.isNothing(jQuery(this).attr("wx-value"))==true || isori==true){ return jQuery(this).val(); }else{ return jQuery(this).attr("wx-value"); } } }else{ // 設定 if ($.isNothing(jQuery(this).prop("tagName"))) return false; if ($.isNothing(isori)) isori = true; if (jQuery(this).prop("tagName").toLowerCase()=="span" || jQuery(this).prop("tagName").toLowerCase()=="div"){ jQuery(this).html(data); }else{ if (jQuery(this).prop("tagName").toLowerCase()=="input" || jQuery(this).prop("tagName").toLowerCase()=="text"){ jQuery(this).prop("value",data); jQuery(this).attr("value",data); jQuery(this).val(data); }else if (jQuery(this).prop("tagName").toLowerCase()=="textarea"){ jQuery(this).html(data); jQuery(this).text(data); jQuery(this).val(data); }else if(jQuery(this).prop("tagName").toLowerCase()=="select"){ jQuery(this).children().each(function(){ if (jQuery(this).val()==data){ jQuery(this).attr("selected", "selected"); jQuery(this).prop("selected", true); } }).trigger("change"); } } if (isori==true) jQuery(this).wx("orival",data); jQuery(this).wx("value",data); } } jQuery.fn.valByDat = function(data,role){ var root = jQuery(this).wx("role"); var selector = "[wx-field]"; // 亦可指定 role if ($.isNothing(role)==false){ var roles = role.split(/,/g); var selTemp = []; for(var idx in roles){ selTemp.push(selector+"[wx-role='"+roles[idx]+"']"); //$.clog(selector+"[wx-role='"+roles[idx]+"']"); } selector = selTemp.join(","); } jQuery(this).find(selector).each(function(){ var field = jQuery(this).wx("field"); //$.clog(selector+" : "+field+"="+data[field]+" > "+$.isNothing(data[field])); // 目前循攬到的物件 在 data 中有相對應的資料 if ($.isNothing(data[field])==false || data[field]==""){ var tsData = data[field]; var tsTag = jQuery(this).prop("tagName").toLowerCase(); // 沒有特別標註此物件類型的就直接給 value 跟 wx-value if (tsTag=="p" || tsTag=="span" || tsTag=="div" || tsTag=="b" || tsTag=="a" || tsTag=="h1" || tsTag=="h2" || tsTag=="h3" || tsTag=="label" || tsTag=="td" || tsTag=="li" ){ jQuery(this).html(tsData); }else if (tsTag=="img"){ jQuery(this).attr("src",tsData); }else if (tsTag=="input" && jQuery(this).prop("type")=="checkbox"){ //$.clog("CheckBox Value "+field+">"+tsData); if ((tsData*1)<=0){ $("[wx-role='"+root+"'] input[type='checkbox'][wx-field='"+field+"']").prop('checked', false); }else{ $("[wx-role='"+root+"'] input[type='checkbox'][wx-field='"+field+"']").prop('checked', true); } }else{ jQuery(this).xval(tsData); //$.clog(field+">"+jQuery(this).wx("type")); switch(jQuery(this).wx("type")){ case "radio": //$.clog("In"); // prop 才能有效改變顯示,所以取得是否有的時候就要 用 prop $("[wx-role='"+root+"'] [wx-role='rdoItem'][wx-field='"+field+"']").prop('checked', false); $("[wx-role='"+root+"'] [wx-role='rdoItem'][wx-field='"+field+"'][wx-value='"+tsData+"']").prop('checked', true); break; } } jQuery(this).wx("orival",tsData); jQuery(this).wx("value",tsData); } }); } jQuery.fn.wx = function(attr,value) { if ($.isNothing(value,true)){ return $(this).attr("wx-"+attr); }else{ // 注意 attr = setAttribute , value 會被轉為字串 return $(this).attr("wx-"+attr,value); } }; jQuery.setHint = function(selector,content,delay){ var oriHint = $(selector).attr("placeholder"); if ($.isNothing(delay)){ delay = 1000; } if (!$.isNothing(content,true)){ $(selector).attr("placeholder",content); setTimeout(function(){ $(selector).attr("placeholder",oriHint); },delay); } }; jQuery.setFocus = function(selector,msecs){ setTimeout(function(){ $(selector).trigger("focus"); },msecs); } jQuery.clog = function(obj){ var err = new Error(); var caller_line = err.stack.split("\n")[2]; if ($.isNothing(caller_line)) return; // Add above for IOS not know caller_line var index = caller_line.indexOf("at "); var clean = caller_line.slice(index+2, caller_line.length); console.log(clean+" :> "+obj); } var _wx_reusable_pool = {}; jQuery.reuse = function(name,parm) { var optObject = true; if (_wx_reusable_pool[name]==null){ if ($.isNothing(name,true)==false){ var tmpnode = name; optObject = false; }else{ return false; } }else{ var tmpnode = _wx_reusable_pool[name]; } if (parm!=null){ jQuery.each(parm,function(key,value){ var re = new RegExp('##'+key+'##', "g"); tmpnode = tmpnode.replace(re,value); }) } return optObject==true?jQuery(tmpnode):tmpnode; }; jQuery.collectReusable = function(){ $("[wx-reusename] [wx-reusename] [wx-reusename]").each(function(){ _wx_reusable_pool[$(this).attr("wx-reusename")]=$(this).outerHTML(); $(this).remove(); }); $("[wx-reusename] [wx-reusename]").each(function(){ _wx_reusable_pool[$(this).attr("wx-reusename")]=$(this).outerHTML(); $(this).remove(); }); $("[wx-reusename]").each(function(){ _wx_reusable_pool[$(this).attr("wx-reusename")]=$(this).outerHTML(); $(this).remove(); }); } jQuery.isNothing = function(obj,escstr){ if (escstr==null) escstr = false; if (obj==null) return true; var rtnval = false; switch(typeof obj){ case "object": return false; break; case "string": if (escstr==true){ return false; }else{ if (obj === ""){ return true; } return false; } break; case "undefined": return false; break; } if (typeof obj !== "string" && isNaN(obj)) return true; return false; } jQuery.numFormat = function(str) { return (str+"").replace(/.(?=(?:[0-9]{3})+\b)/g, '$&,'); }; jQuery.stringify = function (obj) { var t = typeof (obj); if (t != "object" || obj === null) { // simple data type if (t == "string") obj = '"'+obj+'"'; return String(obj); } else { // recurse array or object var n, v, json = [], arr = (obj && obj.constructor == Array); for (n in obj) { v = obj[n]; t = typeof(v); if (t == "string") v = '"'+v+'"'; else if (t == "object" && v !== null) v = JSON.stringify(v); json.push((arr ? "" : '"' + n + '":') + String(v)); } return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}"); } }; jQuery.jsonEncode = function(obj){ return encodeURIComponent(jQuery.stringify(obj)); } jQuery.jsonDecode = function(jsonstring){ return $.parseJSON(decodeURIComponent(jsonstring).replace(/\n/g,'\\n').replace(/\r/g,'\\r')); } jQuery.padLeft = function(str, len) { str = '' + str; return str.length >= len ? str : new Array(len - str.length + 1).join("0") + str; } jQuery.padRight = function(str, len) { str = '' + str; return str.length >= len ? str : str + new Array(len - str.length + 1).join("0"); } jQuery.strTotime = function (text, now) { // discuss at: http://locutus.io/php/strtotime/ // original by: Caio Ariede (http://caioariede.com) // improved by: Kevin van Zonneveld (http://kvz.io) // improved by: Caio Ariede (http://caioariede.com) // improved by: A. Matías Quezada (http://amatiasq.com) // improved by: preuter // improved by: Brett Zamir (http://brett-zamir.me) // improved by: Mirko Faber // input by: David // bugfixed by: Wagner B. Soares // bugfixed by: Artur Tchernychev // bugfixed by: Stephan Bösch-Plepelits (http://github.com/plepe) // note 1: Examples all have a fixed timestamp to prevent // note 1: tests to fail because of variable time(zones) // example 1: strtotime('+1 day', 1129633200) // returns 1: 1129719600 // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200) // returns 2: 1130425202 // example 3: strtotime('last month', 1129633200) // returns 3: 1127041200 // example 4: strtotime('2009-05-04 08:30:00 GMT') // returns 4: 1241425800 // example 5: strtotime('2009-05-04 08:30:00+00') // returns 5: 1241425800 // example 6: strtotime('2009-05-04 08:30:00+02:00') // returns 6: 1241418600 // example 7: strtotime('2009-05-04T08:30:00Z') // returns 7: 1241425800 var parsed var match var today var year var date var days var ranges var len var times var regex var i var fail = false if (!text) { return fail } // Unecessary spaces text = text.replace(/^\s+|\s+$/g, '') .replace(/\s{2,}/g, ' ') .replace(/[\t\r\n]/g, '') .toLowerCase() // in contrast to php, js Date.parse function interprets: // dates given as yyyy-mm-dd as in timezone: UTC, // dates with "." or "-" as MDY instead of DMY // dates with two-digit years differently // etc...etc... // ...therefore we manually parse lots of common date formats var pattern = new RegExp([ '^(\\d{1,4})', '([\\-\\.\\/:])', '(\\d{1,2})', '([\\-\\.\\/:])', '(\\d{1,4})', '(?:\\s(\\d{1,2}):(\\d{2})?:?(\\d{2})?)?', '(?:\\s([A-Z]+)?)?$' ].join('')) match = text.match(pattern) if (match && match[2] === match[4]) { if (match[1] > 1901) { switch (match[2]) { case '-': // YYYY-M-D if (match[3] > 12 || match[5] > 31) { return fail } return new Date(match[1], parseInt(match[3], 10) - 1, match[5], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 case '.': // YYYY.M.D is not parsed by strtotime() return fail case '/': // YYYY/M/D if (match[3] > 12 || match[5] > 31) { return fail } return new Date(match[1], parseInt(match[3], 10) - 1, match[5], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 } } else if (match[5] > 1901) { switch (match[2]) { case '-': // D-M-YYYY if (match[3] > 12 || match[1] > 31) { return fail } return new Date(match[5], parseInt(match[3], 10) - 1, match[1], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 case '.': // D.M.YYYY if (match[3] > 12 || match[1] > 31) { return fail } return new Date(match[5], parseInt(match[3], 10) - 1, match[1], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 case '/': // M/D/YYYY if (match[1] > 12 || match[3] > 31) { return fail } return new Date(match[5], parseInt(match[1], 10) - 1, match[3], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 } } else { switch (match[2]) { case '-': // YY-M-D if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) { return fail } year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1] return new Date(year, parseInt(match[3], 10) - 1, match[5], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 case '.': // D.M.YY or H.MM.SS if (match[5] >= 70) { // D.M.YY if (match[3] > 12 || match[1] > 31) { return fail } return new Date(match[5], parseInt(match[3], 10) - 1, match[1], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 } if (match[5] < 60 && !match[6]) { // H.MM.SS if (match[1] > 23 || match[3] > 59) { return fail } today = new Date() return new Date(today.getFullYear(), today.getMonth(), today.getDate(), match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000 } // invalid format, cannot be parsed return fail case '/': // M/D/YY if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) { return fail } year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5] return new Date(year, parseInt(match[1], 10) - 1, match[3], match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 case ':': // HH:MM:SS if (match[1] > 23 || match[3] > 59 || match[5] > 59) { return fail } today = new Date() return new Date(today.getFullYear(), today.getMonth(), today.getDate(), match[1] || 0, match[3] || 0, match[5] || 0) / 1000 } } } // other formats and "now" should be parsed by Date.parse() if (text === 'now') { return now === null || isNaN(now) ? new Date().getTime() / 1000 | 0 : now | 0 } if (!isNaN(parsed = Date.parse(text))) { return parsed / 1000 | 0 } // Browsers !== Chrome have problems parsing ISO 8601 date strings, as they do // not accept lower case characters, space, or shortened time zones. // Therefore, fix these problems and try again. // Examples: // 2015-04-15 20:33:59+02 // 2015-04-15 20:33:59z // 2015-04-15t20:33:59+02:00 pattern = new RegExp([ '^([0-9]{4}-[0-9]{2}-[0-9]{2})', '[ t]', '([0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?)', '([\\+-][0-9]{2}(:[0-9]{2})?|z)' ].join('')) match = text.match(pattern) if (match) { // @todo: time zone information if (match[4] === 'z') { match[4] = 'Z' } else if (match[4].match(/^([+-][0-9]{2})$/)) { match[4] = match[4] + ':00' } if (!isNaN(parsed = Date.parse(match[1] + 'T' + match[2] + match[4]))) { return parsed / 1000 | 0 } } date = now ? new Date(now * 1000) : new Date() days = { 'sun': 0, 'mon': 1, 'tue': 2, 'wed': 3, 'thu': 4, 'fri': 5, 'sat': 6 } ranges = { 'yea': 'FullYear', 'mon': 'Month', 'day': 'Date', 'hou': 'Hours', 'min': 'Minutes', 'sec': 'Seconds' } function lastNext (type, range, modifier) { var diff var day = days[range] if (typeof day !== 'undefined') { diff = day - date.getDay() if (diff === 0) { diff = 7 * modifier } else if (diff > 0 && type === 'last') { diff -= 7 } else if (diff < 0 && type === 'next') { diff += 7 } date.setDate(date.getDate() + diff) } } function process (val) { // @todo: Reconcile this with regex using \s, taking into account // browser issues with split and regexes var splt = val.split(' ') var type = splt[0] var range = splt[1].substring(0, 3) var typeIsNumber = /\d+/.test(type) var ago = splt[2] === 'ago' var num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1) if (typeIsNumber) { num *= parseInt(type, 10) } if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) { return date['set' + ranges[range]](date['get' + ranges[range]]() + num) } if (range === 'wee') { return date.setDate(date.getDate() + (num * 7)) } if (type === 'next' || type === 'last') { lastNext(type, range, num) } else if (!typeIsNumber) { return false } return true } times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' + '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' + '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)' regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?' match = text.match(new RegExp(regex, 'gi')) if (!match) { return fail } for (i = 0, len = match.length; i < len; i++) { if (!process(match[i])) { return fail } } return (date.getTime() / 1000) } jQuery.dateTimeStr = function(type,timestamp,istw){ if (timestamp==null) timestamp = jQuery.now(); if (istw==null) istw = false; var dd = new Date(timestamp); var ddyear = dd.getFullYear(); if (istw) ddyear -= 1911; switch(type){ case "Y/m/d": return ddyear+'/'+jQuery.padLeft(dd.getMonth()+1,2)+'/'+jQuery.padLeft(dd.getDate(),2); break; case "Y/m/d H:i:s": return ddyear+'/'+jQuery.padLeft(dd.getMonth()+1,2)+'/'+jQuery.padLeft(dd.getDate(),2)+' '+jQuery.padLeft(dd.getHours(),2)+':'+jQuery.padLeft(dd.getMinutes(),2)+':'+jQuery.padLeft(dd.getSeconds(),2); break; case "Y-m-d": return ddyear+'-'+jQuery.padLeft(dd.getMonth()+1,2)+'-'+jQuery.padLeft(dd.getDate(),2); break; case "H:i:s": return jQuery.padLeft(dd.getHours(),2)+':'+jQuery.padLeft(dd.getMinutes(),2)+':'+jQuery.padLeft(dd.getSeconds(),2); break; case "YmdHis": return ddyear+jQuery.padLeft(dd.getMonth()+1,2)+jQuery.padLeft(dd.getDate(),2)+jQuery.padLeft(dd.getHours(),2)+jQuery.padLeft(dd.getMinutes(),2)+jQuery.padLeft(dd.getSeconds(),2); break; case "Y-m-d H:i:s": default: return ddyear+'-'+jQuery.padLeft(dd.getMonth()+1,2)+'-'+jQuery.padLeft(dd.getDate(),2)+' '+jQuery.padLeft(dd.getHours(),2)+':'+jQuery.padLeft(dd.getMinutes(),2)+':'+jQuery.padLeft(dd.getSeconds(),2); break; } } jQuery.parseSecret = function (secret,isStaff,isZip){ if (isStaff==null) isStaff = false; if (isZip==null) isZip = true; var tmpBase = Array(); tmpBase[0] = '221309'; tmpBase[1] = '681229'; tmpBase[2] = '978978'; var tmpChar = Array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'); var tmpLv1Key = secret.substr(0,1); var tmpLv2Key = (tmpLv1Key%3); if (isNaN(parseInt(tmpLv2Key,10))) return false; var tmpKey = tmpBase[tmpLv2Key]; var tmpBody = secret.substr(1,secret.length-2); var tmpCheckSum = 0//secret.substr(secret.length-2,1); var tmpSN = ''; for(var j=0;j var _cntQuery = {}; var _cntPageName = null; var _cntSubPageName = null; var _cntPageNo = 1; var _cntPageOrderBy = "sn"; var _cntPageOrderDir = "ASC"; var _cntPageSize = 10; var _cntPageTotal = 1; // 系統預設-切換頁面方法實作 var _SYSNAME = "POINTer"; // 頁數提示方法實作 function _pageHint(res,scope){ if ($.isNothing(scope)==true){ if ($.isNothing(_funcPage["funcname"])==false){ if ($.isNothing(_funcPage["gosub"])!==true && _funcPage["gosub"].toUpperCase()=="YES"){ scope = "[wx-role='funPage'][wx-for='"+_funcPage["funcname"]+"'][wx-to='detail'] "; }else{ scope = "[wx-role='funPage'][wx-for='"+_funcPage["funcname"]+"'] "; } }else{ scope = ""; } }else{ scope = scope+" "; } $.clog("In Page Hint Scope = "+scope); if (res!=null){ _cntPageNo = res.jin.view.pagenum; _cntPageTotal = Math.ceil(res.trecs/res.jin.view.pagesize); $(scope+"[wx-role='hint-rows']").html(res.trecs); $(scope+"[wx-role='hint-page']").val(res.jin.view.pagenum); $(scope+"[wx-role='hint-pages']").html(_cntPageTotal); }else{ $(scope+"[wx-role='hint-rows']").html("0"); $(scope+"[wx-role='hint-page']").val("0"); $(scope+"[wx-role='hint-pages']").html("0"); } $(scope+"[wx-role='hint-prepage']").html(_cntPageSize); $(scope+"[wx-role='hint-prepage']").val(_cntPageSize); $(scope+"[wx-role='hint-prepages-set']").unbind("click"); $(scope+"[wx-role='hint-prepages-set']").on("click",function(){ $(scope+"[wx-role='hint-prepage']").html($(this).wx("value")); $(scope+"[wx-role='hint-prepage']").val($(this).wx("value")); }); $(scope+"[wx-role='hint-prepages-set']").on("click",function(){ _cntPageSize = $(this).wx("for"); _cntPageNo = 1; goSearch(_funcPage["funcname"]); }); var pStart = _cntPageNo - 2; if (pStart<=0) pStart = 1; var pEnd = pStart+4; if (pEnd>_cntPageTotal) pEnd = _cntPageTotal; $(scope+"[wx-role='nav-pages'] [wx-role='nav-page-func']").unbind("click"); $(scope+"[wx-role='nav-pages'] [wx-role='nav-page-func']").on("click",function(){ switch($(this).wx("for")){ case "first": _cntPageNo = 1; break; case "previous": _cntPageNo -= 1; break; case "next": _cntPageNo += 1; break; case "last": _cntPageNo = _cntPageTotal; break; } if (_cntPageNo<1) _cntPageNo = 1; if (_cntPageNo>_cntPageTotal) _cntPageNo = _cntPageTotal; goSearch(_funcPage["funcname"]); }); $(scope+"[wx-role='nav-pages'] [wx-role='nav-page']").remove(); for(var p=pStart; p<=pEnd; p++){ $(scope+"[wx-role='nav-pages'] [wx-role='nav-page-func'][wx-for='next']").before($.reuse("navPage",{"page":p})); } $(scope+"[wx-role='nav-pages'] [wx-role='nav-page'][wx-for='"+_cntPageNo+"']").addClass("active"); $(scope+"[wx-role='nav-pages'] [wx-role='nav-page']").on("click",function(){ _cntPageNo = $(this).wx("for"); goSearch(_funcPage["funcname"]); }); } // 自動焦點方法實作 function _autoFocus(){ $("[autofocus]:visible").focus(); } // 填入內容使用 function _fillOptions(target,data,valuefield,displayfield,defval,isremove,displaycondition){ var selector = target; // 要給予多層指定時,由呼叫者指定所以從 [ 開始 if (selector.substr(0,1)!="["){ // 只針對一項/層 時可以用 $ / wx- / # if (selector.substr(0,1)=="$"){ selector = "select[wx-"+selector.substr(1)+"]"; }else if(selector.substr(0,3)=="wx-"){ selector = "select["+selector+"]"; }else if(selector.substr(0,1)=="#"){ selector = ""+selector+""; }else{ selector = "#"+selector; } } if (isremove==null || isremove==true) $(selector+" option").remove(); jQuery.each(data,function(key,value){ if ($.isNothing(displaycondition)==false){ var tsValue = value[displaycondition.key]; if ($.isNothing(tsValue)==false){ switch(displaycondition.optr){ case "=": if (tsValue==displaycondition.val){ //沒事繼續 }else{ // 跳下一個 return true; } break; case "!=": if (tsValue!=displaycondition.val){ //沒事繼續 }else{ // 跳下一個 return true; } break; case ">": if (tsValue>displaycondition.val){ //沒事繼續 }else{ // 跳下一個 return true; } break; case "<": if (tsValue=": if (tsValue>=displaycondition.val){ //沒事繼續 }else{ // 跳下一個 return true; } break; case "<=": if (tsValue<=displaycondition.val){ //沒事繼續 }else{ // 跳下一個 return true; } break; } } } if (valuefield==null && displayfield==null){ $(selector).append($("").attr("value",key).text(value)); }else{ $(selector).append($("").attr("value",value[valuefield]).text(value[displayfield])); } }); if (defval!=null){ $(selector).xval(defval); } } // 定義本系統的常用項目 var _wx_docroot = "/op/"; // 文件根相對站台網域的相對位置 // 預設 ajax.fail 的執行。 function _defGoFailFunc(res,st,jx){ alert($.stringify(arguments)); var errHint = "相關資訊:\n"+res.status+" "+res.statusText; _popWin({ "title":"服務異常", "content":"您目前執行的操作,無法被服務端執行,若您確認網路連線正常,可以嘗試重新整理 Ctrl+F5 您的瀏覽器後再執行所需的服務!!
"+errHint+"
", "noCaption":"了解", "noAction":function(){ window.location.href=_wx_docroot; } }); } function _defNotice(code,text){ switch(code){ case 400: var msg = ""; switch(text){ case "Info Required Not Specified": msg = "進行查閱所需的資料缺乏,建議您 Ctrl+F5 重新整理後再嘗試操作。"; break; default: mag = "無法到達您所需要的服務。"; break; } _popWin({ "title":"缺乏關鍵資料!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 401: var msg = ""; switch(text){ default: msg = "未標示/授權的資訊或地點,你可能處於無法使用此服務的網路,或者你必須要標示你所處的位置。"; break; } _popWin({ "title":"未標示/授權定位!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 403: var msg = ""; switch(text){ default: msg = "您目前的登入身份/網路位置,無法提供你欲前往的服務權限。"; break; } _popWin({ "title":"沒有服務的權限!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 404: var msg = ""; switch(text){ default: msg = "找不到相關資料或者服務。"; break; } _popWin({ "title":"沒有相應的資訊!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 405: var msg = ""; switch(text){ default: msg = "您抵達服務的方式並不正常,以致無法進入該服務,請依 系統介面 的操作執行相關功能。"; break; } _popWin({ "title":"不支援的輸入方式!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 406: var msg = ""; switch(text){ default: msg = "進入查詢功能,但所需的基本條件未明確標示。
(或者你輸入的條件不足)"; break; } _popWin({ "title":"不支援的輸入方式!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 422: var msg = ""; switch(text){ case "Unprocessable Entity - Fail": msg = "進行資料驗證無法通過查核,建議您 Ctrl+F5 重新整理後再嘗試操作。"; break; case "Unprocessable Entity - Empty": msg = "進行資料驗證時發現空值,建議您 Ctrl+F5 重新整理後再嘗試操作。"; break; default: msg = "輸入資料驗證發生了問題,建議您 Ctrl+F5 重新整理後再嘗試操作。"; break; } _popWin({ "title":"發生資料驗證問題!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 500: var msg = ""; switch(text){ case "Server Internal Error - Database": msg = "無法連線資料庫,這可能是一個短時間內無法排除除的問題,建議您稍後再嘗試連結。"; break; default: msg = "目前伺服主機無法提供正常的服務,這可能是一個短時間內無法排除除的問題,建議您稍後再嘗試連結。"; break; } _popWin({ "title":"發生伺服器上的問題!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break case 501: var msg = ""; switch(text){ default: msg = "嘗試要執行的功能,尚未開始提供服務,請選取介面上標示為可進行的操作。"; break; } _popWin({ "title":"尚未提供的服務!", "content":msg+"
"+code+":"+text+"
", "noCaption":"回到主畫面", "noAction":function(){ window.location.href=_wx_docroot; } }); break } } // 清除輸入欄位數值 function _cleanField(target){ if (typeof(target)=="string") target = $(target); target.find(" input[type='checkbox']").prop("checked", false); target.find(" [wx-default]").each(function(){ switch($(this).tagName().toLocaleLowerCase()){ case "div": $(this).html($(this).attr("wx-default")); break; default: if ($(this).attr("type")=="checkbox"){ if ($.isNothing($(this).attr("wx-default")) && $(this).attr("wx-default")!="1" && $(this).attr("wx-default")!="true" && $(this).attr("wx-default")!="Yes" && $(this).attr("wx-default")!="On"){ $(this).prop("checked", false); }else{ $(this).prop("checked", true); } }else{ $(this).val($(this).attr("wx-default")); $(this).attr("wx-value",$(this).attr("wx-default")); } break; } }); } function _initFields(role){ if (role==null) role=""; $(role+"[wx-field]").each(function(){ if ($(this).attr("type")=="checkbox") return true; var theVal = ""; if ($.isNothing($(this).val())==false){ theVal = $(this).val() } if ($.isNothing($(this).wx("default"))==true){ $(this).wx("default",theVal); $(this).xval(theVal); } if ($.isNothing($(this).wx("value"))==true){ $(this).wx("value",theVal); $(this).xval(theVal); } if ($.isNothing($(this).wx("orival"))==true){ $(this).wx("orival",theVal); $(this).xval(theVal); } }); $(role+"[wx-role='rdoItem']").on("click",function(){ $("["+$(this).wx("for").replace(/\$/,"wx-")+"][wx-field='"+$(this).wx("field")+"']").val($(this).val()); }); $("[wx-type='number']").each(function(){ var tsVal = $("[wx-type='number']").val(); if ($.isNothing(tsVal)) tsVal = 0; tsVal = tsVal*1; if (tsVal<0) tsVal = 0; $(this).xval(tsVal); }); $("[wx-type='number']").on("change",function(){ $("[wx-type='number']").val(_rtnNumQty($("[wx-type='number']").val())); }); } function _rtnNumQty(tsVal){ if ($.isNothing(tsVal)) tsVal = 0; tsVal = tsVal*1; if (tsVal<0) tsVal = 0; return(tsVal); } function _autoPager(ctnRole,shrBtn,tRecs,view,action){ if (view.pagenum==view.pagecount){ $(ctnRole).addClass("hide"); $(shrBtn).wx("cond",""); }else{ $(ctnRole).removeClass("hide"); var pageNext = view.pagenum * 1 + 1; var pageNextFrom = ( pageNext - 1 ) * view.pagesize * 1 + 1; var pageNextTo = ( pageNext ) * view.pagesize; var pageTotalRecs = tRecs; if (pageNextTo>=pageTotalRecs){ pageNextTo = pageTotalRecs; } $(ctnRole+" [wx-role='btnReadMore']").removeClass("hide"); $(ctnRole+" [wx-role='btnReadMore']").wx("page",pageNext); $(ctnRole+" [wx-role='btnReadMore']").unbind("click"); if ($.isFunction(action)){ $(ctnRole+" [wx-role='btnReadMore']").on("click",action); }else{ $(ctnRole+" [wx-role='btnReadMore']").on("click",function(){ $(shrBtn).wx("page",$(this).wx("page")); $(shrBtn).trigger("click"); }); } $(ctnRole+" [wx-role='hintRowNextFrom']").html(pageNextFrom); $(ctnRole+" [wx-role='hintRowNextTo']").html(pageNextTo); $(ctnRole+" [wx-role='hintRowTotal']").html(pageTotalRecs); } } /* REF // https://codepen.io/chriscoyier/pen/mPgoYJ document.addEventListener("keydown", function(event) { console.log(event); document.body.innerHTML = `     which: ${event.which}
  keyCode: ${event.keyCode}
    shiftKey: ${event.shiftKey}
     altKey: ${event.altKey}
    ctrlKey: ${event.ctrlKey}
   metaKey: ${event.metaKey} `; event.preventDefault(); }); */ var _cntFocusRole = null; function _listenComboKeys(){ document.addEventListener("keydown", function(event) { // $(document.activeElement); // 取的目前被 焦點 的元件 // $.clog($(document.activeElement).wx("role")+":K="+event.which+":A="+event.altKey+":C="+event.ctrlKey+":S="+event.shiftKey+":M="+event.metaKey); if ($.isNothing($(document.activeElement).wx("role"))==false){ _cntFocusRole = $(document.activeElement); }else{ } if (_cntFocusRole!=null && $.isNothing(_cntFocusRole)==false && $.isNothing(_cntFocusRole.wx("role"))==false){ if (event.altKey==true){ $.clog("In Alt Combo "+String.fromCharCode(event.which)+"("+event.which+")"); var toChar = String.fromCharCode(event.which).toLowerCase(); if (event.which >= 112 && event.which<=123){ toChar = "f"+String(event.which*1-111).toString(); } if (event.which==8) toChar = "bks"; if (event.which==13) toChar = "enter"; if (event.which==27) toChar = "esc"; if (event.which==37) toChar = "left"; if (event.which==38) toChar = "up"; if (event.which==39) toChar = "right"; if (event.which==40) toChar = "down"; if (event.which==46) toChar = "del"; if (event.which==107 || event.which==187) toChar = "plus"; if (event.which==109 || event.which==189) toChar = "-"; if (event.which==106 || event.which==56) toChar = "*"; if (event.which==191 || event.which==111) toChar = "/"; if (event.which==33) toChar = "pgup"; if (event.which==34) toChar = "pgdw"; var pattern = "alt+"+toChar; // $.clog("[wx-cmb-key='"+pattern+"'][wx-cmb-role='"+_cntFocusRole.wx("role")+"'][wx-for='"+_cntFocusRole.wx("for")+"']"); // $("[wx-cmb-key='"+pattern+"'][wx-cmb-role='"+_cntFocusRole.wx("role")+"'][wx-for='"+_cntFocusRole.wx("for")+"']").trigger("click"); if (toChar=="bks" || toChar=="enter"){ $.clog("force mode"); $("[wx-cmb-key='"+pattern+"']").trigger("click"); }else{ $("[wx-cmb-key='"+pattern+"'][wx-cmb-role='"+_cntFocusRole.wx("role")+"']").trigger("click"); } event.preventDefault(); }else if(event.ctrlKey==true){ if (event.which!=116 && event.which!=67 && event.which!=86){ //if (event.which!=67 && event.which!=86){ $.clog("In Ctrl Combo "+String.fromCharCode(event.which)+"("+event.which+")"); var toChar = String.fromCharCode(event.which).toLowerCase(); if (event.which >= 112 && event.which<=123){ toChar = "f"+String(event.which*1-111).toString(); } if (event.which==8) toChar = "bks"; if (event.which==13) toChar = "enter"; if (event.which==27) toChar = "esc"; if (event.which==37) toChar = "left"; if (event.which==38) toChar = "up"; if (event.which==39) toChar = "right"; if (event.which==40) toChar = "down"; if (event.which==46) toChar = "del"; if (event.which==107 || event.which==187) toChar = "plus"; if (event.which==109 || event.which==189) toChar = "-"; if (event.which==106 || event.which==56) toChar = "*"; if (event.which==191 || event.which==111) toChar = "/"; if (event.which==33) toChar = "pgup"; if (event.which==34) toChar = "pgdw"; var pattern = "ctrl+"+toChar; if (toChar=="left" || toChar=="right"){ // ctrl left / right use for popwin btn selection $("[wx-cmb-key='"+pattern+"']").trigger("click"); }else{ //$("[wx-cmb-key='"+pattern+"'][wx-cmb-role='"+_cntFocusRole.wx("role")+"'][wx-for='"+_cntFocusRole.wx("for")+"']").trigger("click"); $("[wx-cmb-key='"+pattern+"'][wx-cmb-role='"+_cntFocusRole.wx("role")+"']").trigger("click"); } event.preventDefault(); } }else if(event.shiftKey==true){ }else if(event.metaKey==true){ } } }); };_listenComboKeys();// 切記要享有 ready 的優點(DOM可存取就執行) 必須確保沒有 window.onload / $(window).load(fn) 事件,或者必須在 window.onload / $(window).load(fn) 之前。 $(document).ready(function () { // 蒐集可回收利用的物件放置於 _wx_reusable_pool $.collectReusable(); initEvents(); $("[wx-role='inpAcc']").trigger("focus"); }) // 若是針對 版面調整 或者被載入的資源自動尺寸結果的調整,就必須要等 window.onload / $(window).load(fn) 完成後才會是對的。 // 所以最好是先定義好 layout 的尺寸,就可以避免使用 window.onload / $(window).load(fn) 來根 ready 相互干擾。 //$(window).load(function(){ // //}) // 開始宣告 母豬母狗 的事 function initEvents(){ // btnLogin $("[wx-next]").on("keydown",function(e){ if (e.which === 13) { switch($(this).wx("next").substr(0,1)){ case "$": var tFor = $(this).wx("for"); var tNext = $(this).attr("wx-next").substr(1); $("[wx-"+tNext+"][wx-for='"+tFor+"']").trigger("focus"); break; default: $($(this).attr("wx-next")).trigger("focus"); break; } } }); $("[wx-role='inpPwd']").on("keydown",function(e){ if (e.which === 13) { $("[wx-role='btnLogin']").trigger("click"); } }); } //