var dtSearchTitleParam = []; var btnIsClick = true; var ajaxReloadCallBack; window.YT = window.YT || {}; YT.Math = {}; /// <summary> /// | Dropdown | 建置dropdown /// </summary> /// <param type="object" name="eleObj">{btnId = 按鈕element Id ,dropdownId = 下拉選單 element Id}</param> /// <param type="array" name="divObj">[{id = input element id , name = input element name, type = input element type, other = input element other attr, parent = sub parent element id }]</param> $.fn.SetDropDown = function (eleObj, divObj) { let btnEle = $("#" + eleObj.btnId); let strHtml = ``; btnEle.wrap("<div></div>"); strHtml += `<div id="${eleObj.dropdownId}" class="custom-dropdown sort-dropdown dropdown-menu" aria-labelledby="${eleObj.btnId}">`; $.each(divObj, function (index, value) { strHtml += `<div class="dropdown-item-checkbox ${value.parent != null && value.parent != undefined ? "dropdown-item-sub" : ""}"> <input id="${value.id ?? ""}" name="${value.name ?? ""}" type="${value.type ?? ""}" value="${value.value ?? null}" class="dropdown-item-input" data-parent="${value.parent ?? ""}" ${value.other ?? ""}> <label class="dropdown-item-input-label">${value.text ?? ""}</label> </div>` }) btnEle.parent("div").append(strHtml); $("#" + eleObj.dropdownId).find(".dropdown-item-checkbox input:checked").trigger("click", "init"); } Array.prototype.Distinct = function () { return this.filter((value, index, self) => { return self.indexOf(value) === index; }); } Array.prototype.DistinctBy = function (...otherCol) { const result = []; $.each(this, function (index, value) { let filInd = result.findIndex(function (v, i) { let sameNum = 0; $.each(otherCol, function (i2, v2) { if (v[v2] == value[v2]) { sameNum++; } }) return sameNum == otherCol.length ? true : false; }) if (filInd == -1) { result.push(value); } }) return result; } Array.prototype.nSort = function () { function compareNumbers(a, b) { return a - b; } return this.sort(compareNumbers); } Array.prototype.oSort = function (key) { function compareNumbers(a, b) { return a[key] - b[key]; } return this.sort(compareNumbers); } BigInt.prototype.toJSON = function () { return this.toString() } $.fn.classList = function () { return this[0].className.split(/\s+/); }; $.fn.replaceClass = function (oriClass, newClass) { $(this).removeClass(oriClass).addClass(newClass); return $(this) }; //阿拉伯數字轉中文 Number.prototype.toChinese = function () { let chnNumChar = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]; let chnUnitSection = ["", "萬", "億", "萬億", "億億"]; let chnUnitChar = ["", "十", "百", "千"]; let strIns = '', chnStr = ''; let unitPos = 0; let section = this; let zero = true; while (section > 0) { let v = section % 10; if (v === 0) { if (!zero) { zero = true; chnStr = chnNumChar[v] + chnStr; } } else { zero = false; if (unitPos == 0 || (unitPos == 1 && section > 1)) { strIns = chnNumChar[v]; } else { strIns = ""; } strIns += chnUnitChar[unitPos]; chnStr = strIns + chnStr; } unitPos++; section = Math.floor(section / 10); } return chnStr; } $(function () { initTableEvent(); initddEleMargin(); select2bs4(); Date_Pic(); dataReadAttrbuite(); }) imgUploadFormat(); setupSltAddress(); jquValAddMethod(); YT.Math.Random = function (min, max) { return Math.floor(Math.random() * (max - min) + min); } /// <summary> /// Jquery validation add rule, select2 required. /// </summary> function jquValAddMethod() { if ($.validator) { $.validator.addMethod("requiredSelect", function (value, element) { let selVal = $(element).find(`option:selected`).val(); let selText = $(element).find(`option:selected`).text(); if (selVal == 0 || selText.indexOf("無") != -1) { return false; } return true; }, "必須選擇") $.validator.addMethod("requiredCheckbox", function (value, element) { if ($(element).find("input:checkbox:checked").length == 0) { return false; } return true; }, "必須選擇") } } /// <summary> /// Jquery validation form reValid on select2 change. /// </summary> $("body").on("change", ".select2bs4.error,.select2bs4.valid", function () { $(this).parents("form").valid(); }) /// <summary> /// Html tag convert to HTML ASCII(Encode) /// </summary> /// <param type="string" name="target">Html tag</param> function HtmlEncode(str) { let encodedStr = str.replace(/[\u0000-\u9999<>\&]/gim, function (i) { return '&#' + i.charCodeAt(0) + ';'; }); return encodedStr; } function SignEncode(str) { str = str.replace(/[\u0022\u0027]/gim, function (i) { return '&#' + i.charCodeAt(0) + ';'; }) return str; } /// <summary> /// login Tab class active切換 /// </summary> $("body").on("click", ".card ul.card-tab li.card-tab-option", function () { $(".card ul.card-tab li.card-tab-option").removeClass("active"); $(this).addClass("active"); }) /// <summary> /// 判斷照片div裡是否有主圖,無主圖自動把第一張設為主圖 /// </summary> /// <param type="string" name="target">div element Id</param> function isMasterImgExist(target) { if ($(target).find("input[type=radio]:checked").length == 0) { $(target).find("input[type=radio]:eq(0)").prop("checked", true); } } /// <summary> /// 複製文字/網址 /// </summary> /// <param type="string" name="target">element Id</param> function CopyUrlBtn(target, callback) { let $temp = $("<input>"); $("body").append($temp); $temp.val($(target).text()).select(); document.execCommand("copy"); $temp.remove(); callback ? callback() : ""; } /// <summary> /// 驗證解除 /// </summary> /// <param type="string" name="target">element Id</param> /// <param type="array" name="selDivArr">下拉選單div</param> function closeValidate(target, selDivArr) { let selDivStr = ''; if (Object.keys($(target).validate().settings.rules).length != 0) { if (selDivArr != undefined && selDivArr != null) { selDivStr = selDivArr.toString(); $(selDivStr).rules("remove", "SelRequire"); $(selDivStr).find("select").unbind(); $(selDivStr).removeClass("error"); } $("[aria-describedby^=tooltip]").tooltip("dispose"); $(target).validate().resetForm(); } } /// <summary> /// 重新驗證 /// </summary> /// <param type="string" name="target">element Id</param> /// <param type="array" name="selDivArr">下拉選單div</param> function resetValidate(target, selDivArr, validate) { closeValidate(target, selDivArr); validate(); $(target).valid(); } /// <summary> /// 價錢呈現統一 /// </summary> /// <param type="string/int/float" name="Amt">價格</param> function AmtFormat(Amt) { let type = 1; // 0: parseInt(整數) , 1: parseFloat(小數點0省略) ,2: toFixed (小數點強制取位數-四捨五入) let maxFixed = 2; //取小數點後幾位 let result; //輸出 if (Amt === null) { return null; } Amt = Amt || 0; if (type == 0) { result = parseInt(Amt); } else if (type == 1) { result = parseFloat(Amt); } else if (type == 2) { result = parseFloat(Amt).toFixed(maxFixed); } return result } /// <summary> /// 時間格式統一 /// </summary> /// <param type="string" name="dateTime">欲轉換格式之日期時間</param> /// <param type="string" name="dateType">需顯示的年月日時分秒毫秒,Y=年、M=月、d=日、H=時、m=分、s=秒、S=毫秒</param> /// <param type="string" name="locale">時區</param> function displayDate(dateTime, dateType = "YMdHms", locale = 'zh-TW') { let result = ''; if (dateTime) { let regex = /^\/Date\((\d+)\)\/$/gm; let t = Date.parse(dateTime); //若從資料庫回傳 /Date(xxxxxxxxxxxxxx)/ DateTime格式 if (regex.test(dateTime)) { t = parseInt(dateTime.replace(regex, '$1')); } //不符合時間格式 if (isNaN(t)) { return null; } let options = { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", fractionalSecondDigits: "3", hourCycle: "h23", } let d = new Date(t).toLocaleString(locale, options); d = new Date(d); let year = '', month = '', day = '', hour = '', minute = '', second = '', millisecond = '', date = '', time = ''; if (dateType != "date" && dateType != "time" && dateType != "datetime") { dateType.indexOf("Y") != -1 ? year = parseInt(d.getFullYear()) : ""; dateType.indexOf("M") != -1 ? month = parseInt(d.getMonth() + 1) : ""; dateType.indexOf("d") != -1 ? day = parseInt(d.getDate()) : ""; dateType.indexOf("H") != -1 ? hour = parseInt(d.getHours()) : ""; dateType.indexOf("m") != -1 ? minute = parseInt(d.getMinutes()) : ""; dateType.indexOf("s") != -1 ? second = parseInt(d.getSeconds()) : ""; dateType.indexOf("S") != -1 ? millisecond = parseInt(d.getMilliseconds()) : ""; } else if (dateType == "date") { year = d.getFullYear(); month = d.getMonth() + 1; day = d.getDate(); } else if (dateType == "time") { hour = d.getHours(); minute = d.getMinutes(); } else if (dateType == "datetime") { year = d.getFullYear(); month = d.getMonth() + 1; day = d.getDate(); hour = d.getHours(); minute = d.getMinutes(); } date = [year, String(month).padStart(2, '0'), String(day).padStart(2, '0')].filter(n => n).join("/"); time = [String(hour).padStart(2, '0'), String(minute).padStart(2, '0')].filter(n => n).join(":"); result = date.toString() + " " + time.toString(); if (dateType == "date") { result = date.toString(); } else if (dateType == "time") { result = time.toString(); } } return $.trim(result); } /// <summary> /// datatable event 初始化 /// </summary> function initTableEvent() { let windowScrollTop = 0, tableScrollTop = 0; //排序event if ($.fn.dataTable != undefined && $.fn.dataTable != null) { if ($.fn.dataTable.tables(true).length != 0) { //若頁面有datatable let table = ''; $($.fn.dataTable.tables(true)).each(function (index, value) { table = $(value).DataTable(); let tableId = table.context[0].sTableId; tabVis(table); $(value).on("order.dt", function () { $(".popover").remove(); //popover清空 }).DataTable() $(value).on("preDraw.dt", function () { tableScrollTop = $(`#${tableId}_wrapper .dataTables_scrollBody`).scrollTop(); windowScrollTop = $(window).scrollTop(); }).DataTable() $(value).on("draw.dt", function () { table.columns.adjust(); $(window).scrollTop(windowScrollTop); $(`#${tableId}_wrapper .dataTables_scrollBody`).scrollTop(tableScrollTop); loadDtSearchCol(table); loadSesSearchCol(); loadTabChk(tableId); tableHeadChkNotSort(tableId); //若head有checkbox,強制不sorting }).DataTable() dtReloadFn = (data) => { $(`#${tableId}_wrapper .dataTables_scrollBody`).scrollTop(tableScrollTop); $(window).scrollTop(windowScrollTop); ajaxReloadCallBack != undefined && ajaxReloadCallBack != null ? ajaxReloadCallBack() : ""; } }) table.columns.adjust(); } } } /// <summary> /// jquery loaded 事件 /// </summary> //function loadCallback(callback) { // select2bs4(); // Date_Pic(); // dataReadAttrbuite(); // callback ? callback() : ""; // initCkeditor(); //} /// <summary> /// dropdown aria-close 按下不消失dropdown /// </summary> $("body").on("click", ".dropdown-menu", function (e) { let eleId = $(this)[0].id; let eleLen = 0; if (eleId) { eleLen = $(`[data-target='${eleId}'][data-toggle='dropdown'][aria-close='false']`).length; } else { eleLen = $(this).prevAll("button[data-toggle='dropdown'][aria-close='false']").length } if (eleLen != 0) { e.stopPropagation(); } }) /// <summary> /// | Dropdown | 該parent底下sub element沒有勾選時,預設選擇下一個parent element /// </summary> /// <param type="element" name="Obj">dropdown sub input element</param> function ddSubEmptyCha(obj) { let ddmenu = $(obj).parents(".dropdown-menu"); let parentId = $(obj).data("parent"); let chklen = ddmenu.find(`.dropdown-item-sub .dropdown-item-input[data-parent=${parentId}]:checked`).length; if (chklen != 0) { $("#" + parentId).prop("checked", true); } else { let chkRadioId = ddmenu.find(".dropdown-item-checkbox input[type=radio]:checked")[0].id; $("#" + parentId).prop("checked", false); if (ddmenu.find(`.dropdown-item-sub .dropdown-item-input[data-parent=${chkRadioId}]`).length != 0) { if (ddmenu.find(`.dropdown-item-sub .dropdown-item-input[data-parent=${chkRadioId}]:checked`).length == 0) { $(obj).prop("checked", true).change(); } } } } /// <summary> /// | Dropdown | 選擇sub element時 /// </summary> $("body").on("change click", ".dropdown-item-sub .dropdown-item-input", function () { $(this).prop("checked", true); //ddSubEmptyCha(this); otherSubCha(this); subSubCha(this); subChkParentCha(this); ddSelectItemChaName(this); }) /// <summary> /// | Dropdown | 選擇篩選下拉選單項目改變按鈕名稱 /// </summary> /// <param type="element" name="Obj">dropdown input element</param> function ddSelectItemChaName(obj) { let result = ''; result = $(obj).next("label").text(); //let ddmenu = $(obj).parents(".dropdown-menu"); //ddmenu.find(".dropdown-item-checkbox:not(.dropdown-item-sub) input:checked").each(function (index, value) { // reuslt = $(value).next("label").text(); //}) $(obj).parents(".dropdown-menu").prev("button").text(result); } /// <summary> /// | Dropdown | 選擇parent項目 該parent底下sub項目一起勾選,若勾選沒有sub的parent項目,其他sub取消勾選 /// </summary> /// <param type="element" name="Obj">dropdown input element</param> function parentSubCha(obj) { let ddmenu = $(obj).parents(".dropdown-menu"); if ($(obj).prop("checked") == true) { //該(parent)element 被勾選後 if (ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).length != 0) { //判斷底下若有sub element ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).prop("checked", true); //勾選底下所有sub element ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).each(function (index, value) { subSubCha("#" + $(value)[0].id); }) } else { //判斷底下若沒有sub element ddmenu.find(`.dropdown-item-sub input`).not(obj).prop("checked", false); //其他sub element 取消勾選 } } } /// <summary> /// | Dropdown | 選擇sub parent項目 該sub parent底下sub項目一起勾選,若勾選沒有sub的sub parent項目,其他sub取消勾選 /// </summary> /// <param type="element" name="Obj">dropdown input element</param> function subSubCha(obj) { let ddmenu = $(obj).parents(".dropdown-menu"); if ($(obj).prop("checked") == true) { //該(sub)element 被勾選後 if (ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).length != 0) { //判斷底下若有sub element ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).prop("checked", true); //勾選底下所有sub element } } else { //該(sub)element 取消勾選後 if (ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).length != 0) { //判斷底下若有sub element ddmenu.find(`.dropdown-item-sub input[data-parent=${$(obj)[0].id}]`).prop("checked", false); //取消勾選底下所有sub element } } } /// <summary> /// | Dropdown | 選擇其中一sub項目 其他sub項目取消勾選 /// </summary> /// <param type="element" name="Obj">dropdown input element</param> function otherSubCha(obj) { let ddmenu = $(obj).parents(".dropdown-menu"); let parentId = $(obj).data("parent"); ddmenu.find(`.dropdown-item-checkbox.dropdown-item-sub .dropdown-item-input`).not(obj).prop("checked", false); } /// <summary> /// | Dropdown | 選擇其中一sub項目 該sub parent勾選 /// </summary> /// <param type="element" name="Obj">dropdown input element</param> function subChkParentCha(obj) { let parentId = $(obj).data("parent"); if ($(obj).prop("checked") == true) { $("#" + parentId).prop("checked", true); } } /// <summary> /// | Dropdown | 選擇parent element時 /// </summary> $("body").on("change click", ".dropdown-item-checkbox:not(.dropdown-item-sub) .dropdown-item-input", function () { ddSelectItemChaName(this); parentSubCha(this); }) /// <summary> /// | Dropdown | 初始化 parent sub element margin /// </summary> function initddEleMargin() { $(".sort-dropdown .dropdown-item-checkbox:not(.dropdown-item-sub) .dropdown-item-input").each(function (index, value) { let eleId = $(value)[0].id; setddEleMargin(eleId, 0); }) } /// <summary> /// | Dropdown | set parent sub element margin /// </summary> /// <param type="string" name="eleId">dropdown input element</param> /// <param type="int" name="margin">input element css margin</param> function setddEleMargin(eleId, margin = 0) { let subEle = $(`.sort-dropdown .dropdown-item-checkbox.dropdown-item-sub .dropdown-item-input[data-parent=${eleId}]`); let subId = ``; margin += 20; $.each(subEle, function (index, value) { subId = $(value)[0].id; $(value).parent(".dropdown-item-checkbox").css("margin-left", margin + "px"); setddEleMargin(subId, margin); }) } /// <summary> /// | table Filter | filter tag close icon on the datatable top (以datatable搜尋) /// </summary> $("body").on("click", ".tag-label-close[data-type='dt']", function () { let table = $($.fn.dataTable.tables(true)).DataTable(); let id = $(this)[0].id; let name = $(this).data("name"); $(this).parent(".tag-label").remove(); if (table) { closeDtSearchCol(table, id, name); //欄位搜尋清除 } }) /// <summary> /// | table Filter | filter tag close icon on the datatable top (以session傳值搜尋(尚未用到)) /// </summary> $("body").on("click", ".tag-label-close[data-type='ses']", function () { let table = $($.fn.dataTable.tables(true)).DataTable(); let name = $(this).parent(".tag-label")[0].id.split("tagLabel_")[1].split("_")[0]; let sesName = window.location.pathname + "_" + name; $(this).parent(".tag-label").remove(); if (table) { closeSesSearchCol(table, sesName, $(this).parent("label")); } }) /// <summary> /// | table Filter | dropdown item on the datatable top /// </summary> $("body").on("click", ".dataTables_wrapper .toolbar .dropdown-item-checkbox input", function (e, type) { let tableId = $(this).parents(".dataTables_wrapper")[0].id.split("_wrapper")[0]; if (type != "init") { //除了初始化以外,篩選過後頁面跳回至第1頁 $.each($("#" + tableId).DataTable().context[0].aoPreSearchCols, function (index, value) { if (value.sSearch != '') { $("#" + tableId).DataTable().column(index).search(''); } }) $("#" + tableId).DataTable().page(0); } $("#" + tableId).DataTable().ajax.reload(null, false); }) /// <summary> /// | table Filter | Load Datatable exists searching column. /// </summary> /// <param type="datatable" name="dt">executed datatable</param> function loadDtSearchCol(dt) { $.each(dt.context[0].aoPreSearchCols, function (index, value) { let id = "dtSearch_" + index; if (value.sSearch != '') { if ($(`.dataTables_wrapper > .selector .tag-label:contains(${value.sSearch})`).length == 0) { let data = dt.context[0].aoColumns[index].data; let title = setDtSearchTitle(dt, index, value) let btnTemp = `<label id="" class="tag-label mr-1">${title}<i id="${id}" data-type="dt" data-name="${data}" class="fas fa-times tag-label-close text-white ml-4"></i></label></div>`; $(".dataTables_wrapper > .selector").append(btnTemp); } } else { if ($("#" + id).length != 0) { $("#" + id).click(); } } }) } /// <summary> /// | table Filter | Set Datatable filter tag title on table top /// </summary> /// <param type="datatable" name="dt">executed datatable</param> /// <param type="int" name="index">SearchCol index</param> /// <param type="string" name="value">SearchCol value</param> function setDtSearchTitle(dt, index, value) { let title = dt.context[0].aoColumns[index].filterName ?? dt.context[0].aoColumns[index].title; let search = value.sSearch; let filterName = dt.context[0].aoColumns[index].filterName ?? ""; if (filterName.indexOf("__TITLE__") != -1 || filterName.indexOf("__VALUE__") != -1) { filterName = filterName.replace("__TITLE__", title); filterName = filterName.replace("__VALUE__", search); return filterName } else { return title + " : " + search; } } /// <summary> /// | table Filter | Set "dtSearchTitleParam" variable, used to set Datatable filter title. /// </summary> /// <param type="string" name="paramStr">paramter string</param> function setDtSearchTitleParam(colName, param) { param != null ? dtSearchTitleParam.push({ "name": colName, "text": param }) : ""; } /// <summary> /// | table Filter | Cleaning Datatable search column when click filter tag icon. /// </summary> /// <param type="datatable" name="dt">executed Datatable</param> /// <param type="string" name="id">closeing filter icon element Id</param> function closeDtSearchCol(dt, id, name) { let col = id.indexOf("dtSearch_") != -1 ? id.split("dtSearch_")[1] : ""; sessionStorage.removeItem(name); localStorage.removeItem(name); dt.column(col).search('').draw(false); } /// <summary> /// | table Filter | Load Datatable exists searching column (Session variable). /// </summary> function loadSesSearchCol() { $.each(Object.keys(sessionStorage), function (index, value) { if (value.indexOf(window.location.pathname) != -1) { let result = JSON.parse(Object.values(sessionStorage)[index]); let btnTemp = `<label id="tagLabel_${value.split("_")[1]}_${result[0].Id}" class="tag-label mr-1">${result[0].Text}<i id="closeLab${result[0].Id}" data-type="ses" class="fas fa-times tag-label-close text-white ml-4"></i></label></div>`; $(".dataTables_wrapper > .selector").append(btnTemp); } }) } /// <summary> /// | table Filter | Cleaning Datatable search column when click filter tag icon (Session variable). /// </summary> /// <param type="datatable" name="dt">executed Datatable</param> /// <param type="string" name="name">session name</param> /// <param type="element" name="obj">tag label element</param> function closeSesSearchCol(dt, name, obj) { sessionStorage.removeItem(name); obj.remove(); dt.ajax.reload(dtReloadFn, false); } function tabVis(dt) { let columnArr = dt.context[0].aoColumns; let strHtml = ``; $.each(columnArr, function (index, value) { strHtml += `<div class="custom-control custom-checkbox ml-2"> <input class="custom-control-input" type="checkbox" id="tabVis_${value.data}" data-idx="${value.idx}" value="${value.data}" ${value.bVisible ? "checked" : ""}> <label for="tabVis_${value.data}" class="custom-control-label">${value.title}</label> </div>`; }) $("#table_filter").append(`<div class="btn-group"><button type="button" id="tabColVisBtn" class="btn btn-sm bg-gray-h t-white ml-2" data-toggle="dropdown" data-target="tabColVisDropdown" aria-close="false">欄位顯示</button> <div id="tabColVisDropdown" class="custom-dropdown dropdown-menu dropdown-menu-right" aria-labelledby="tabColVisBtn" > <div class="row p-2"> ${strHtml} </div> </div></div>`) $("body").on("change", "input[id^=tabVis]", function () { let idx = $(this).data("idx"); let chk = $(this).prop("checked"); dt.columns(idx).visible(chk); dt.columns.adjust(); }) } var tabChkArr = []; function tableHeadChkNotSort(tabId) { $(`#${tabId} thead input:checkbox`).each(function (index, value) { $(value).parents("th").removeClass("sorting_asc"); $(value).parents("th").removeClass("sorting_desc"); }) } function loadTabChk(tabId) { $(`#${tabId}_wrapper thead tr th input:checkbox`).prop("checked", false); $.each(tabChkArr, function (index, value) { $(`${tabId} tbody tr td input:checkbox[data-rowid=${value.rowId}]`).prop("checked", true).change(); }) } /// <summary> /// | Sidebar | User headshot css adjusts on sidebar collapsing. /// </summary> $("html").on("mouseover", "body.sidebar-collapse .main-sidebar", function () { $(this).find(".logo-link").css("width", "250px").css("overflow", "visible"); $(this).find(".logo-link img").css("left", "0px"); $(this).find(".user-panel .info").show(); }).on("mouseleave", "body.sidebar-collapse .main-sidebar", function () { $(this).find(".logo-link").css("width", "37px").css("overflow", "hidden").css("margin", "auto"); $(this).find(".logo-link img").css("left", "-16px"); $(this).find(".user-panel .info").hide(); }) /// <summary> /// | Sidebar | User headshot css adjusts on sidebar collapsing. /// </summary> $("body").on("click", ".nav-link[data-widget=pushmenu]", function () { let obj = $(this).parents("body").find(".main-sidebar"); if ($(this).parents("body").hasClass("sidebar-collapse")) { obj.find(".logo-link").css("width", "250px").css("overflow", "visible") obj.find(".logo-link img").css("left", "0px"); obj.find(".user-panel .info").show(); } else { obj.find(".logo-link").css("width", "37px").css("overflow", "hidden").css("margin", "auto"); obj.find(".logo-link img").css("left", "-16px"); obj.find(".user-panel .info").hide(); } }) /// <summary> /// Set bootstrap modal and show /// </summary> /// <param type="string" name="type">warning, error ,success</param> /// <param type="string" name="id">modal div element id</param> /// <param type="string/object" name="title">modal header h4 tag title</param> /// <param type="string/object" name="content">modal body content</param> /// <param type="string/Array" name="btnArr">modal foot button</param> function ShowModal(type = null, id, title, content, btnArr) { let btnHtml = ``, titleHtml = ``, conHtml = ``; //foot按鈕 if ($.isArray(btnArr) == true) { $.each(btnArr, (i, v) => { if (typeof v == "object") { let strData = ''; if (v.dataArr) { $.each(v.dataArr, function (index, value) { strData += "data-" + value.key + "=" + value.value; }) } btnHtml += `<button ${v.id ? `id='${v.id}'` : ""} ${v.name ? `name='${v.name}'` : ""} type="button" class="btn ${v.class ?? "btn-primary"}" ${v.dismiss ? "data-dismiss='modal'" : ""} ${strData || ""}>${v.text ?? "了解"}</button>`; } }) } else { btnHtml = `<button type="button" class="btn btn-primary" data-dismiss="modal">了解</button>`; } //header title if (typeof title == "object") { titleHtml += `<h4 ${title.id ? `id=${title.id}` : ""} ${title.name ? `name=${title.name}` : ""} class="modal-title ${type ? `modal-icon-${type}` : ""} ${title.class ?? ""}" ${title.style ? `style="${title.style}"` : ""}">${title.text}</h4>` } else { titleHtml = `<h4 class="modal-title ${type ? `modal-icon-${type}` : ""}">${title}</h4>`; } //body content if (typeof content == "object") { conHtml += `<h4 ${content.id ? `id=${content.id}` : ""} ${content.name ? `name=${content.name}` : ""} class="${content.class ?? ""}" ${content.style ? `style="${content.style}"` : ""}">${content.text}</h4>` } else { conHtml = `<label class="w-100 text-center">${content}</label>`; } let strHtml = `<div id="${id}-Modal" class="modal fade" role="dialog"> <div class="modal-dialog modal-dialog-centered"> <!-- Modal content--> <div class="modal-content"> <div class="modal-header"> ${titleHtml} <button type="button" class="close" data-dismiss="modal">×</button> </div> <div class="modal-body"> ${conHtml} </div> <div class="modal-footer"> ${btnHtml} </div> </div> </div> </div>`; $("body").prepend(strHtml); $(`#${id}-Modal`).modal("show"); $("body").on("hidden.bs.modal", `#${id}-Modal`, function () { setTimeout(function () { $(`#${id}-Modal`).remove(); }, 500) }) } /// <summary> /// init load select2 on Html after shown Modal /// </summary> $("body").on("shown.bs.modal", "div[id$='-Modal']", function () { let table = $($.fn.dataTable.tables(true)).DataTable(); table.columns.adjust(); if ($("div[id$='-Modal'].show").length > 1) { $($("div[id$='-Modal'].show")[0]).css("z-index", parseInt($($("div[id$='-Modal'].show")[1]).css("z-index")) + 2); $(".modal-backdrop:last").css("z-index", parseInt($($("div[id$='-Modal'].show")[1]).css("z-index")) + 1); } select2bs4(); Date_Pic(); }) ///// <summary> ///// Modal hide show tip check exit. ///// </summary> //$("body").on("hide.bs.modal", "div[id$='-Modal'][aria-mode='noticeMode']:not([aria-close='true'])", function (e) { // console.log(e) // let ariaType = $(this).find(".modal-body").attr("aria-type"); // if (ariaType && ariaType != "read") { // let modalId = $(this).attr("id"); // let btnArr = [{ id: "_modalBackToEdit", text: "繼續編輯", class: "btn-secondary", dismiss: true }, { id: "_modalExit", text: "離開", dismiss:true,dataArr: [{ key: "id", value: modalId }]}] // ShowModal("warning", "closeModalWarning", "資料即將遺失", "資料不會被保存,確認離開此編輯頁面?", btnArr); // return false; // } //}) ///// <summary> ///// click modal tip check exit button. ///// </summary> //$("body").on("click", "#closeModalWarning-Modal #_modalExit", function (e) { // let modalId = $(this).data("id"); // $("#" + modalId).attr("aria-close", true); // $("#" + modalId).modal("hide"); // setTimeout(function () { // $("#" + modalId).removeAttr("aria-close"); // },1000) //}) /// <summary> /// init load select2 on Html after shown Modal /// </summary> $("body").on("hidden.bs.modal", "div[id$='-Modal']", function (e) { if ($("body > .modal-backdrop.show").length != 0) { $("body").addClass("modal-open"); } }) /// <summary> /// init load select2 on Html after shown Modal /// </summary> $("body").on("show.bs.modal", "div[id$='-Modal']", function () { if ($(this).find(".GiCouCode").length != 0) { $(this).find(".GiCouCode").change(); $(this).find(".GiCitCode").change(); } select2bs4(); Date_Pic(); }) /// <summary> /// init load select2 /// </summary> function select2bs4(selector = null) { selector = selector || ".select2bs4"; if ($(selector).length != 0) { $(selector).each((i, obj) => { let colArr = $(obj).classList().filter(x => x.indexOf("col-") != -1); colArr.length != 0 ? colArr.push("p-0") : ""; let $sel = $(obj).select2({ theme: 'bootstrap4', /* width: 'auto',*/ minimumResultsForSearch: -1, containerCssClass: $(obj).hasClass("form-control-sm") ? "form-control-sm" : "", }); $sel.data().select2.$container.addClass(colArr.join(" ")); //console.log($(obj).select2().data().select2) }) } function memSelFormat(icon) { let fbName = $(icon.element).data("fb"); let lineName = $(icon.element).data("line"); let realName = icon.text; let id = icon.id; return $(`<span>${realName} ${memLineName(lineName, id)}${memFbName(fbName, id)}</span>`); }; statusSelDraHtml(); $(selector).each((index, value) => { let selVal = $(value).data("read-value"); if (selVal !== undefined && selVal !== null && selVal !== "") { $(value).find(`option[value=${selVal}]`).prop("selected", true); $(value).change(); } }) } /// <summary> /// Set status select draw to html. /// </summary> function statusSelDraHtml() { if (typeof statusArr != "undefined") { let strHtml = `<option value="1">${statusArr[1]}</option> <option value="0">${statusArr[0]}</option>`; $("select[data-seltype='status']").html(strHtml); } } /// <summary> /// Set table Ststus column value style. /// </summary> /// <param type="string" name="value">column value</param> function setTableStatus(value) { let text = value == 1 ? statusArr[1] : value == 0 ? statusArr[0] : statusArr[9]; return `<label class="status-tag" data-value="${value}">${text}</label>`; } /// <summary> /// | Upload-File | Limit images format on Upload form. /// </summary> function imgUploadFormat() { $("div[id^=preview]").parent("div").find("input[type='file']").attr("accept", "image/jpeg, image/png"); } /// <summary> /// Using Ajax get image. /// </summary> /// <param type="int" name="sysTabId">SysTabId</param> /// <param type="int" name="rowId">RowId</param> /// <param type="int" name="fpId">FilPurId</param> /// <param type="int" name="fkId">FilKinId</param> /// <param type="function" name="success">success callback</param> function getImg(sysTabId, rowId, fpId, fkId, success) { Sccp5Ajax = new SCCP5.Ajax(varApiUrl + `sp_File_Sl/byParams?SysTabId=${sysTabId}&Rowid=${rowId}&FilPurId=${fpId}&FilKinId=${fkId}`, null, success).send(); } /// <summary> /// Read image through the path. /// </summary> /// <param type="string" name="imgName">imgName</param> function readImg(imgName, thumb = false) { let result = ''; result = varPathImg + "/" + (thumb ? "s" : "") + (imgName || ""); return result; } /// <summary> /// Read image through the path. /// </summary> /// <param type="string" name="imgName">imgName</param> function imgHtml(src, cls = null, width = 70, height = null) { let result = ''; if (src != null && src != "" && src != undefined) { result = `<img class="${cls ?? ""}"src="${src}" style="${width ? `width:${width}px;` : ""} ${height ? `height:${height}px;` : ""}" onerror="defImg(this)">` } return result; } /// <summary> /// Json to base64 put on Url. /// </summary> /// <param type="object" name="Object">Object</param> function utoa(obj) { let result = btoa(unescape(encodeURIComponent(obj))); result = result.split("=")[0]; result = result.replace("+", "-"); result = result.replace("/", "_"); return result } /// <summary> /// Base64 convert to string /// </summary> /// <param type="object" name="str">string</param> function atou(str) { let result = decodeURIComponent(escape(atob(str))); return result } /// <summary> /// Protecting the input element value overflows max value. /// </summary> /// <param type="object" name="Object">Object</param> $("body").on("keyup", "input[max]", function () { parseFloat($(this).val()) > parseFloat($(this).attr("max")) ? $(this).val($(this).attr("max")) : ""; }) /// <summary> /// Date Time Picker Initial /// </summary> function Date_Pic() { if ($.fn.datetimepicker) { $('i.fa-calendar').parents("div.date").datetimepicker({ format: 'YYYY/MM/DD', }); $('i.fa-clock').parents("div.date").datetimepicker({ format: 'HH:mm', }); } } /// <summary> /// Form disabled /// </summary> /// <param type="string" name="id">Object</param> function formDisabled(id) { $(`form#${id} input,form#${id} select,form#${id} textarea`).prop("disabled", true); } /// <summary> /// Image full show on click. /// </summary> $("body").on("click", "img[data-extname]", function () { let ext = ["jpg", "jpeg", "png", "gif"]; if (ext.indexOf($(this).data("extname")) != -1) { $("body").append("<div class='image-full-show'></div>"); let strhtml = $($(this).clone()).addClass("image-full"); $(".image-full-show").html(strhtml); } }) /// <summary> /// Image full hide on click. /// </summary> $("body").on("click", ".image-full-show", function () { $(".image-full-show").remove(); }) /// <summary> /// decimal place on floor. /// </summary> function roundDown(num, decimal) { return Math.floor((num + Number.EPSILON) * Math.pow(10, decimal)) / Math.pow(10, decimal); } function setupSltAddress() { if ($(".GiCouCode,.GiCitCode,.GiPosCode").length != 0) { $(".GiCouCode").html(`<option value="0">請選擇國家</option>`); $(".GiCitCode").html(`<option value="0">請選擇縣市</option>`); $(".GiPosCode").html(`<option value="0">請選擇鄉鎮</option>`); setupGiCouCode(); setupGiCitCode(); setupGiPosCode(); $(".GiCouCode").each((index, value) => { $(value).change(); }) } } // 0-4 //設定 "國家" 下拉選單 function setupGiCouCode() { //ajax 成功函式 function Success(data) { let htmlStr = ''; $.each(data, function (index, element) { htmlStr += `<option value=${element.Code} data-valname="${element.Name}">${element.Code} ${element.Name} </option>`; }); $(".GiCouCode").html(htmlStr); } Sccp5Ajax = new SCCP5.Ajax("/Utility/GetGiCountry", null, Success).send(); } // 0-4-1 //設定 "縣市" 下拉選單 function setupGiCitCode() { $("body").on("change", ".GiCouCode", function (e) { e.preventDefault(); let obj = this; let objName = $(obj).data("name"); let selectedText = $(this).find("option:selected").text(); $(this).next("span.select2").find(".select2-selection__rendered").text(selectedText).attr("title", selectedText); //抓國家碼 886 let GiCouCode = $(this).find("option:selected").val(); //判斷選取國家後是否有資料 $(obj).nextAll('.GiCitCode').length == 0 ? $(`select[data-name=${objName}].GiCitCode`).empty() : $(obj).nextAll('.GiCitCode').empty(); $(obj).nextAll('.GiPosCode').length == 0 ? $(`select[data-name=${objName}].GiPosCode`).empty() : $(obj).nextAll('.GiPosCode').empty(); if (GiCouCode == "") { return false } //ajax 成功函式 function Success(data) { let htmlStr = `<option value="0">請選擇縣市</option>`; let htmlStr2 = `<option value="0">請選擇鄉鎮</option>`; $.each(data, function (index, element) { htmlStr += `<option value=${element.Code} data-valname="${element.Name}">${element.Code} ${element.Name} </option>`; }); $(obj).nextAll('.GiCitCode').length == 0 ? $(`select[data-name=${objName}].GiCitCode`).html(htmlStr) : $(obj).nextAll('.GiCitCode').html(htmlStr); $(obj).nextAll('.GiPosCode').length == 0 ? $(`select[data-name=${objName}].GiPosCode`).html(htmlStr2) : $(obj).nextAll('.GiPosCode').html(htmlStr2); } Sccp5Ajax = new SCCP5.Ajax("/Utility/GetGiCity?CountryCode=" + GiCouCode, null, Success).send(); }); //$(".GiCouCode").change(); } // 0-4-2 //設定 "鄉鎮區" 下拉選單 function setupGiPosCode() { $("body").on("change", ".GiCitCode", function (e) { e.preventDefault(); let obj = this; let objName = $(obj).data("name"); let htmlStr = `<option value="0">請選擇鄉鎮</option>`; let selectedText = $(this).find("option:selected").text(); $(this).next("span.select2").find(".select2-selection__rendered").text(selectedText).attr("title", selectedText); let GiCouCode = $(this).parent("div").find(".GiCouCode option:selected").val(); let GiCitName = $(this).parent("div").find(".GiCitCode option:selected").text().split(" ")[1]; $(obj).nextAll('.GiPosCode').length == 0 ? $(`select[data-name=${objName}].GiPosCode`).html(htmlStr) : $(obj).nextAll('.GiPosCode').html(htmlStr); if (GiCouCode == "" || GiCitName == undefined) { return false } //ajax 成功函式 function Success(data) { //console.log(data); $.each(data, function (index, element) { htmlStr += `<option value=${element.Code} data-valname="${element.Name}" >${element.Code.substr(0, 3)} ${element.Name} </option>`; }); $(obj).nextAll('.GiPosCode').length == 0 ? $(`select[data-name=${objName}].GiPosCode`).html(htmlStr) : $(obj).nextAll('.GiPosCode').html(htmlStr); } Sccp5Ajax = new SCCP5.Ajax("/Utility/GetGiPosCode/byParams?CityName=" + GiCitName, null, Success).send(); }); //$(".GiCitCode").change(); } function chkboxToHtml(id, name, value, text, cls, other, dataArr = []) { let dataStr = ''; $.each(dataArr, function (index, v) { dataStr += `data-${v.key}='${v.value}' `; }) let result = `<div class="custom-control custom-checkbox ${cls ?? ""}"> <input class="custom-control-input" type="checkbox" id="${id ?? ""}" name="${name ?? ""}" value="${value ?? ""}" ${dataStr}> <label for="${id ?? ""}" class="custom-control-label row align-items-center m-0 mr-2">${text ?? ""}</label> ${other ?? ""} </div>`; return result; } $("body").on("change", "input:checkbox[value='_all'],input:checkbox[value='_one']", function () { let togType = $(this).val().split("_")[1]; let chkName = $(this).attr("name"); let chked = $(this).prop("checked"); //相同name屬性 checkbox 皆勾選 $(`input:checkbox[name=${chkName}]`).prop("checked", chked); //觸發勾選 checkbox change事件 $(`input:checkbox[name=${chkName}]:not([value='_${togType}'])`).trigger("change", ["mannual"]); //最後element 觸發 ajax reload 事件 $(`input:checkbox[name=${chkName}]:not([value='_${togType}']):last`).change(); }) $("body").on("change", "input:checkbox[data-bindfilname]", function () { let chkName = $(this).data("bindfilname"); let chked = $(this).prop("checked"); $(`input:checkbox[name=${chkName}]`).prop("checked", chked); $(`input:checkbox[name=${chkName}]:not([value='_all']):last`).trigger("change", ["mannual"]); $(`input:checkbox[name=${chkName}]:not([value='_all']):last`).change(); }) $("body").on("change", "input:checkbox[name]", function () { //當有name的情況時,判斷若有全選checkbox,全部checked後全選checkbox按下。 let chkName = $(this).attr("name"); let chked = $(this).prop("checked"); chkBaseNameAll(chkName); chkBaseNameOne(chkName); chkBindFilNameChked(chkName, chked); }) /// <summary> /// | Checkbox | Base on checkbox element name execute all checked. /// </summary> function chkBaseNameAll(chkName) { let len = $(`input:checkbox[name=${chkName}]:not([value='_all'])`).length; $(`input:checkbox[value='_all'][name=${chkName}]`).prop("checked", false); $(`input:checkbox[name=${chkName}]:not([value='_all'])`).each((i, v) => { if (!$(v).prop("checked")) { return false; } len == i + 1 ? $(`input:checkbox[value='_all'][name=${chkName}]`).prop("checked", true) : ""; }) } /// <summary> /// | Checkbox | Tick If there is one. /// </summary> function chkBaseNameOne(chkName) { $(`input:checkbox[value='_one'][name=${chkName}]`).prop("checked", false); if ($(`input:checkbox[name=${chkName}]:not([value='_one']):checked`).length != 0) { $(`input:checkbox[value='_one'][name=${chkName}]`).prop("checked", true); } } /// <summary> /// | Checkbox | If the checkbox has 'bindfilname' dataset , auto checked. /// </summary> function chkBindFilNameChked(chkName, chked) { if (!chked) { chked = $(`input:checkbox[name=${chkName}]:checked`).length == 0 ? false : true; } $(`input:checkbox[data-bindfilname=${chkName}]`).prop("checked", chked); } function dataReadAttrbuite() { $("[data-read-type='checkbox'][data-read-value]").each(function (index, value) { let val = $(value).data("read-value"); if (val != undefined && val != null && val != "") { //example : 12,22,31,55 if (val.toString().indexOf(",") != -1) { $.each(val.split(","), function (index2, value2) { $(value).find(`input:checkbox[value=${value2}]`).prop("checked", true).change(); }) } //example : 22 else { $(value).find(`input:checkbox[value=${val}]`).prop("checked", true).change(); } } }) $("[data-read-type='text'][data-read-value]").each(function (index, value) { let val = $(value).data("read-value"); if (val != undefined && val != null && val != "") { //example : xxxx,xxxxxx,xxxxxxxxx,xxxxxxx if (val.toString().indexOf(",") != -1) { $.each(val.split(","), function (index2, value2) { $(value).find(`input[type=text]:eq(${index2})`).val(value2).change(); }) } //example : xxxxxx else { $(value).find(`input[type=text]:first`).val(val).change(); } } }) $("[data-read-type='radio'][data-read-value]").each(function (index, value) { let val = $(value).data("read-value"); if (val != undefined && val != null && val != "") { //example : 12,22,31,55 if (val.toString().indexOf(",") != -1) { $.each(val.split(","), function (index2, value2) { $(value).find(`input:radio[value=${value2}]`).prop("checked", true).change(); }) } //example : 22 else { $(value).find(`input:radio[value=${val}]`).prop("checked", true).change(); } } }) $("select[data-read-value]").each(function (index, value) { let selVal = $(value).data("read-value"); if (selVal !== undefined && selVal !== null && selVal !== "") { $(value).find(`option[value=${selVal}]`).prop("selected", true); $(value).change(); } }) } // custom tab // example : // <button id="test" data-target="#okDiv" data-tabname="tab1"></button> // <div id="okDiv" data-tabrole="child" data-tabname="tab1"></div> $("body").on("click", "[data-tabname][data-target]", function () { let target = $(this).data("target"); let obj = this; let tabName = $(target).data("tabname"); if (tabName) { if ($(target).data("tabrole") == "child") { $(obj).trigger("yt:tab:show"); $(`[data-tabname='${tabName}'][data-tabrole='child']`).css("opacity", 0).hide(); $(target).show().animate({ opacity: 1 }, 200, function () { $(obj).trigger("yt:tab:shown"); }); } } }) function toBool(boolstr) { if (boolstr && typeof boolstr == "string") { return boolstr.toLowerCase() === "true"; } return null; } /** * 下載檔案 * @param {any} url * @param {any} filename */ async function download(url, filename) { let toDataURL = function (url) { return fetch(url).then((response) => { if (!response.ok) { throw new Error("Not 2xx response", { cause: response }); } else { return response.blob(); } }).then(blob => { return URL.createObjectURL(blob); }).catch(function (error) { return null; }); } const a = document.createElement("a"); let href = await toDataURL(url) if (href) { a.href = href; a.download = filename ? filename : ""; document.body.appendChild(a); a.click(); document.body.removeChild(a); return true; } else { return false; } } function onEvent(type, selector, callback) { $("body").off(type, selector); $("body").on(type, selector, callback); } /** * element array sort * @param {any} selector * @param {any} attrName */ function getSorted(selector, attrName) { return $($(selector).sort(function (a, b) { var aVal = parseInt($(a).attr(attrName)), bVal = parseInt($(b).attr(attrName)); return aVal - bVal; })); } //data-tourl $("body").on("click", "[data-tourl]", function () { let url = $(this).data("tourl"); if ($(this).data("target") == "_blank") { window.open(url, "_blank"); } else { location.href = url; } }); /** * * Base64 encode / decode * http://www.webtoolkit.info/ * **/ YT.Base64 = { // private property _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", // public method for encoding encode: function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = YT.Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); } return output; }, // public method for decoding decode: function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } output = YT.Base64._utf8_decode(output); return output; }, // private method for UTF-8 encoding _utf8_encode: function (string) { string = string.replace(/\r\n/g, "\n"); var utftext = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, // private method for UTF-8 decoding _utf8_decode: function (utftext) { var string = ""; var i = 0; var c = c1 = c2 = 0; while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } } YT.Url = function (url, ...other) { let paramArr = []; $.each(other, function (index, value) { if (typeof value == "object") { $.each(value, function (index2, value2) { if (value2 != null) { paramArr.push(index2 + "=" + value2); } }) } }) if (paramArr.length == 0) { if (url[url.length - 1] == "?") { url.splice(url.length - 1, 1); } } else { if (url.indexOf("?") == -1) { url += "?"; } else { if (url[url.length - 1] != "?") { url[url.length - 1] != "&" ? url + "&" : ""; } } } url = url + paramArr.join("&"); return url; } YT.Loading = function (type, ele = null, text = null, delay = 0) { if (type == "start") { let html = `<div class="yt-page-loading"></div>`; $("body").append(html) ele = YTAlert.Tip(text || "資料上傳中,請勿離開頁面。", "show"); return ele; } else if (type == "finish" && ele != null) { $(".yt-page-loading").fadeOut(); $(ele.ele).YTAlert().hide(delay); } } //change css of clicked button function btnSelCss(elem) { $.each($(elem).parent().find('button'), function (i, v) { $(v).removeClass('btn-dark'); $(v).addClass('btn-secondary'); }); $(elem).removeClass('btn-secondary'); $(elem).addClass('btn-dark'); }