var YourTeam = YourTeam || {}; YourTeam.JqDataTables = YourTeam.JqDataTables || {}; /* @deprecated since version 0.2 * @description change datatables prototype language * @author Darren Chen * @date 2018/04/18 */ $.fn.dataTable.defaults.oLanguage = { "sProcessing": "等待中...", "sLengthMenu": "顯示 _MENU_ 項結果", "sZeroRecords": "沒有匹配結果", "sInfo": "顯示第 _START_ 至 _END_ 項結果,共 _TOTAL_ 項", "sInfoEmpty": "顯示第 0 至 0 項結果,共 0 項", "sInfoFiltered": "(由 _MAX_ 項結果過濾)", "sInfoPostFix": "", "sSearch": "搜索:", "sUrl": "", "sThousands": "", "sEmptyTable": "表中數據為空", "sLoadingRecords": "載入中...", "sInfoThousands": ",", "oPaginate": { "sFirst": "首頁", "sPrevious": "上頁", "sNext": "下頁", "sLast": "末頁" }, "oAria": { "sSortAscending": ": 以升序排列此列", "sSortDescending": ": 以降序排列此列" } }; /* @deprecated since version 0.1 * @description init the jq datatables no data with the page ui * @param {String} tag jq datatables id(#id) or class(.class) * @param {Array} colnum_defs these is colnum def. with init the table * @param {function} initComplete after init complete run a function * @param {function} drawCallback after draw complete run a function * @author Darren Chen * @date 2020/12/10 */ function fnInitJqDataTablesNoData(tag, dataSet = null, columns = null, columnDefs = null, initComplete = null, drawCallback = null, rowsGroup = null, rowGroup = null, dom = '<"toolbar">frtipl' ) { let fnDrawCallBack = function () { drawCallback != null ? drawCallback() : ""; let api = this.api(); $(".dataTables_scrollBody").css("overflow", "auto"); if (api.rows().data().length <= 1) { $(".dataTables_scrollBody").css("overflow", "visible"); } } let table = null; let oTable = { "sDom": dom, "data": dataSet, "autoWidth": true, "processing": true, "columns": columns, "aoColumnDefs": columnDefs, "stateSave": true, "pagingType": "full_numbers_custom", "destroy": false, "initComplete": initComplete, "drawCallback": fnDrawCallBack, "rowsGroup": rowsGroup, "rowGroup": rowGroup, "retrieve": true, "responsive": { details: { target: '.dt-mobile-btn', type: "column", renderer: function (api, rowIdx, columns) { var data = $.map(columns, function (col, i) { return col.hidden ? '' + '' + col.title + ':' + ' ' + '' + col.data + '' + '' : ''; }).join(''); return data ? $('').append(data) : false; }, }, }, } let time = 0; table = $(tag).DataTable(oTable); table.on('processing', function (e, settings, processing) { //過100ms的讀取才秀出loading setTimeout(function () { time == 1 ? loadingSetting("show", "dtProcessing") : ""; }, 100); if (processing && time == 0) { //第一次讀取processing = true time = 1; } else if (!processing && time == 1 ) { //結束讀取後processing = false loadingSetting("hide", "dtProcessing"); time = 0; } }) table.on('responsive-display', function (e, datatable, row, showHide, update ) { table.columns.adjust(); }); return table; } function fnInitJqDataTables(tag, colnum_defs = null, initComplete = null, drawCallback = null) { return $(tag).DataTable({ "dom": '<"toolbar"><"wrapper"ti>', //"responsive": true, "autoWidth": true, //"aoColumns": columns, "aoColumnDefs": colnum_defs, "initComplete": initComplete, "drawCallback": drawCallback, }); } /* @deprecated since version 1.1 * @description init jq datatables use jQuery AJAX * @param {String} API url * @param {String} table id (#id) * @param {Object} data * @param {Object} columns * @param {Object} columns_def * @param {Object} order * @param {String} table header button id (#id) * @param {String} html tag string with the header * @return {String} JSON string * @author Darren Chen * @date 2020/12/11 */ function fnInitJqDataTablesAjax(apiUrl, tag, sendData = null, columns, columns_def, initComplete = null, drawCallback = null, rowsGroup = null, rowGroup = null ,order = null, btn = null, dom = null) { //$(tag).dataTable().fnClearTable(); //let sData = data ? (data.Data ? JSON.stringify(data.Data) : null) : null; if (sendData == null) { sendData = function (json) { console.log("讀取列表", json) return json; } } let fnDrawCallBack = function () { drawCallback != null ? drawCallback() : ""; let api = this.api(); $(".dataTables_scrollBody").css("overflow", "auto"); if (api.rows().data().length <= 1) { $(".dataTables_scrollBody").css("overflow", "visible"); } } let table = null; try { let oTable = { "ajax": { method: "GET", url: apiUrl, cache: true, async:false, dataSrc: sendData, }, "responsive": { details: { target: '.dt-mobile-btn', renderer: function (api, rowIdx, columns) { var data = $.map(columns, function (col, i) { return col.hidden ? '' + ' ' + '' + '' : ''; }).join(''); return data ? $('
' + col.title + ':' + '' + col.data + '
').append(data) : false; } }, }, "data": null, "EmptyTable": true, "destroy": true, "processing": false, "sDom":'<"toolbar">frtipl', "pagingType": $(window).width() < 768 ? "simple" : "full_numbers_custom", //"responsive": true, "autoWidth": true, "aoColumns": columns, "aoColumnDefs": columns_def, "deferRender": true, "fixedColumns": true, "stateSave": true, "scrollX": true, "scrollY": "700px", "scrollCollapse": true, "autoWidth": true, //"sScrollY": "480px", "orderMulti": true, "header": "#liaison_header", "initComplete": initComplete, "drawCallback": fnDrawCallBack, "rowGroup": rowGroup, "rowsGroup": rowsGroup, }; if (order) { oTable.order = order; } if (dom) { oTable.dom = dom; } let time = 0; table = $(tag).DataTable(oTable); table.on('processing', function (e, settings, processing) { //過100ms的讀取才秀出loading setTimeout(function () { time == 1 ? loadingSetting("show", "dtProcessing") : ""; }, 100); if (processing && time != 1) { //第一次讀取processing = true time = 1; } else if (!processing && time == 1) { //結束讀取後processing = false loadingSetting("hide", "dtProcessing"); time = 0; } }) } catch (e) { console.error(e); } return table; } function fnInitJqDataTablesOdata(apiUrl, tag, sendData, columns, columns_def, drawCallback = null, order = null) { //$(tag).dataTable().fnClearTable(); //let sData = data ? (data.Data ? JSON.stringify(data.Data) : null) : null; let table = null; try { let oTable = { "sAjaxSource": apiUrl, "iODataVersion": 3, "aoColumns": columns, "aoColumnDefs": columns_def, "fnServerData": fnServerOData, // required "bProcessing": true, "bServerSide": true, // optional "bDestroy": true, "bUseODataViaJSONP": false, // set to true if using cross-domain requests "sDom": '<"toolbar">f<"selector">rtipl', "stateSave": true, }; if (order) { oTable.order = order; } table = $(tag).DataTable(oTable); } catch (e) { console.error(e); } return table; } function fnInitJqDataTablesServerSideAjax(apiUrl, tag, sendData, columns, columns_def, initComplete = null, drawCallback = null, rowsGroup = null, rowGroup = null, order = null, btn = null, dom = null) { //$(tag).dataTable().fnClearTable(); //let sData = data ? (data.Data ? JSON.stringify(data.Data) : null) : null; let table = null; let fnDrawCallBack = function () { let api = this.api(); drawCallback != null ? drawCallback(api) : ""; //若只有一列 overflow改為 visible (tooltip/popover 不會阻擋) $(".dataTables_scrollBody").css("overflow", "auto"); if (api.rows().data().length <= 1) { $(".dataTables_scrollBody").css("overflow", "visible"); } } try { let oTable = { "sAjaxSource": apiUrl, //"ajax": { // "method":"POST", // "url": apiUrl, //}, "responsive": { details: { renderer: function (api, rowIdx, columns) { var data = $.map(columns, function (col, i) { return col.hidden ? '' + ' ' + '' + '' : ''; }).join(''); return data ? $('
' + col.title + ':' + '' + col.data + '
').append(data) : false; } }, }, "fnServerParams": sendData, "data": null, "EmptyTable": true, "destroy": true, "processing": false, "sDom": '<"toolbar">f<"selector">rtipl', "paging": true, "pagingType": $(window).width() < 768 ? "simple" : "full_numbers_custom", //"responsive": true, "autoWidth": true, "aoColumns": columns, "aoColumnDefs": columns_def, "deferRender": true, "fixedColumns": true, "stateSave": true, "stateSaveParams": function (settings, data) { //紀錄該頁是否有篩選Filter if ($(".column_filter")) { let saveFilterArr = []; $(".column_filter input:checkbox:checked").each(function (i, v) { let id = $(v)[0].id; saveFilterArr.push(id); }) data.CustomFilter = JSON.stringify(saveFilterArr); //把勾選的篩選儲存到datatable state } }, "scrollX": true, "scrollY": "700px", "scrollCollapse": true, "autoWidth": true, //"sScrollY": "480px", "orderMulti": true, "bServerSide": true, "header": "#liaison_header", "initComplete": initComplete, "drawCallback": fnDrawCallBack, "rowGroup": rowGroup, "rowsGroup": rowsGroup, }; if (order) { oTable.order = order; } if (dom) { oTable.dom = dom; } let time = 0; table = $(tag).DataTable(oTable); $.fn.DataTable.ext.pager.numbers_length = 9; console.log($.fn.DataTable.ext.pager) table.on('processing', function (e, settings, processing) { //過100ms的讀取才秀出loading setTimeout(function () { time == 1 ? loadingSetting("show", "pageload") : ""; }, 100); if (processing && time == 0) { //第一次讀取processing = true time = 1; } else if (!processing && time == 1 && tableStatus != 2){ //結束讀取後processing = false loadingSetting("hide", "pageload"); time = 0; } }) table.on('xhr', function (e, settings, json, xhr) { console.log("讀取列表", json.aaData); }) table.on('page', function (e, setting) { $(`${tag}_wrapper .dataTables_scrollBody`).scrollTop(0); pageScrollPos = 0; }) } catch (e) { console.error(e); } return table; } YourTeam.JqDataTables.getTableByOdata = fnInitJqDataTablesOdata; YourTeam.JqDataTables.getTableByAjax = fnInitJqDataTablesAjax; YourTeam.JqDataTables.getTableByServerSideAjax = fnInitJqDataTablesServerSideAjax; YourTeam.JqDataTables.getTableByStatic = fnInitJqDataTablesNoData; YourTeam.JqDataTables.getTableByNoAjax = fnInitJqDataTables; /* @deprecated since version 1.1 * @description add one new row with the jq datatables * @param {Object} table the jq datatables * @param {Object} item one JSON item with the data Object * @param {Object} data the data Object * @return * @author Darren Chen * @date 2020/12/11 */ function fnJqDataTablesNewRow(table, itemSpace) { let isSuccess = false; try { table.row.add(itemSpace).draw(false); } catch (e) { console.error(e); return isSuccess; } return isSuccess; } YourTeam.JqDataTables.newRow = fnJqDataTablesNewRow; /* @deprecated since version 1.1 * @description add one row and data with the jq datatables * @param {Object} table the jq datatables * @param {Object} item one JSON item with the data Object * @param {Object} data the data Object * @return * @author Darren Chen * @date 2020/12/11 */ function fnJqDataTablesAddRow(table, item) { let isSuccess = false; try { if (table && item) { table.row.add(item).draw(false); } } catch (e) { console.error(e); return isSuccess; } return isSuccess; } YourTeam.JqDataTables.addRow = fnJqDataTablesAddRow; /* @deprecated since version 1.1 * @description remove one row and data with the jq datatables * @param {String} tableId the datatables`s id * @param {String} elementSelector the jq selector with remove row element * @return {Bollean} isSuccess * @author Darren Chen * @date 2020/12/11 */ function fnJqDataTablesRemoveRow(tableId, elementSelector) { let isSuccess = false; try { $('#' + tableId + ' tbody').on('click', elementSelector, function () { table.row($(this).parents('tr')).remove().draw(false); }); isSuccess = true; } catch (e) { console.error(e); return isSuccess; } return isSuccess; } YourTeam.JqDataTables.removeRow = fnJqDataTablesRemoveRow; /* @deprecated since version 0.3 * @description display buton * @param {Boolean} have create power? * @param {Boolean} have edit power? * @param {Boolean} have delete power? * @param {Boolean} have print power? * @return {String} * @author Darren Chen * @date 2018/04/18 */ function showControlItem(Create, Edit, Delete, Print) { if (Create) { $("#btnCreat").show(); $("#ERP_insert").show(); } else { $("#btnCreat").hide(); $("#ERP_insert").hide(); } if (Edit) { $("a.green").show(); $("#date_check").show(); } else { $("a.green").hide(); $("#date_check").hide(); } if (Delete) { $("#checkDelete").show(); $("#date_check").show(); $("a.red").show(); } else { $("#checkDelete").hide(); $("#date_check").hide(); $("a.red").hide(); } if (Print) { $("a[name='print']").show(); } else { $("a[name='print']").hide(); } } let hide_star = "********"; /* @deprecated since version 0.2 * @description replace the field * @param {String} the element id * @param {Boolean} ready only * @author Darren Chen * @date 2018/04/18 */ function hide_field(tag, is_readonly = null) { var text = ""; $(tag).each(function () { if ($(this).prop("tagName").toLowerCase() === "input") { text = $(this).val().toString(); if (text === "-999999999") { $(this).val(hide_star); } } else if ($(this).prop("tagName").toLowerCase() === "div") { text = $(this).text().toString(); if (text === "-999999999") { $(this).text(hide_star); } } else if ($(this).prop("tagName").toLowerCase() === "td") { text = $(this).text().toString(); if (text === "-999999999") { $(this).text(hide_star); } } if (is_readonly) { $(this).prop("readonly", true); } }); } /* @deprecated since version 0.1 * @description 阻止ServerSide Datatable 在特定時間內傳出大量值 * @author JunHao Lin * @date 2021/12/22 */ function serverSideExecLimit() { let lastTime; $($.fn.dataTable.tables(true)).on('order.dt page.dt search.dt xhr.dt', function (e, settings, ordArr) { //排序時Callback會回傳兩次,所以判斷時間差只抓取一次 //(時間差之內的排序執行 || 換頁執行 || 搜尋執行) if (settings.oInit.bServerSide == true) { if (((e.timeStamp - lastTime <= 300 && (e.handleObj.origType == "order") || e.handleObj.origType == "page" || e.handleObj.origType == "search")) && settings.oAjaxData != undefined && (settings.oAjaxData).length != 0) { if (tableStatus == 0) { //tableStatus = 0 | 還沒觸發執行 tableStatus = 1 //tableStatus = 1 | 已觸發執行,可接受執行 calEventTime = setInterval(function () { //計數五秒 if (timeNum == 5) { //若到第五秒 pageEventNum = searchEventNum = orderEventNum = 0 //執行次數復歸 timeNum = 0 //秒數歸零 tableStatus = 0 //狀態復歸 clearInterval(calEventTime) //計數關閉 } timeNum++; //秒數++ }, 1000) } //在五秒之內,排序執行超過五次 if (timeNum < 5 && orderEventNum >= 5 && e.handleObj.origType == "order" && tableStatus == 1) { tableStatus = 2; } //在五秒之內,搜尋執行超過五次 if (timeNum < 5 && searchEventNum >= 10 && e.handleObj.origType == "search" && tableStatus == 1) { tableStatus = 2; } //在五秒之內,換頁執行超過五次 if (timeNum < 5 && pageEventNum >= 5 && e.handleObj.origType == "page" && tableStatus == 1) { tableStatus = 2; } //執行次數++ switch (e.handleObj.origType) { case "order": orderEventNum++; break; case "search": searchEventNum++; break; case "page": pageEventNum++; break; } //tableStatus = 2 | 已觸發執行,不可接受執行(超出執行條件) if (tableStatus == 2) { showAlert("danger", "執行次數過多!") loadingSetting("show","dtServerSide"); //出現loading setTimeout(function () { loadingSetting("hide", "dtServerSide"); pageEventNum = searchEventNum = orderEventNum = 0 //執行次數復歸 timeNum = 0 //秒數歸零 tableStatus = 0 //狀態復歸 clearInterval(calEventTime) //計數關閉 }, 5000) } } } lastTime = e.timeStamp; //時間差 }).DataTable() } YourTeam.JqDataTables.limitServerSideExec = serverSideExecLimit; function sortNumbersIgnoreText(a, b, high) { var reg = /[+-]?((\d+(\.\d*)?)|\.\d+)([eE][+-]?[0-9]+)?/; a = a.match(reg); a = a !== null ? parseFloat(a[0]) : high; b = b.match(reg); b = b !== null ? parseFloat(b[0]) : high; return ((a < b) ? -1 : ((a > b) ? 1 : 0)); } jQuery.extend(jQuery.fn.dataTableExt.oSort, { "sort-numbers-ignore-text-asc": function (a, b) { return sortNumbersIgnoreText(a, b, Number.POSITIVE_INFINITY); }, "sort-numbers-ignore-text-desc": function (a, b) { return sortNumbersIgnoreText(a, b, Number.NEGATIVE_INFINITY) * -1; } });