- Converted PoleDisplay from a function-based structure to a class-based structure for improved readability and maintainability. - Simplified the Open and Close methods to handle port state more clearly. - Enhanced the Send method to support both string and array inputs for sending data. - Updated the cd_Text method to use modern JavaScript features for padding calculations. - Modified the user_log method in Auth class to streamline database fetch and update logic.
1098 lines
47 KiB
JavaScript
1098 lines
47 KiB
JavaScript
/*******************************************************************
|
|
|
|
Module : /assets/js/fonia3.js
|
|
Desc. : JS - Fonia Custom Class v3
|
|
Created By : Siau Pheng ([email protected]).
|
|
Created Date : June 19th, 2009.
|
|
Last Modified : November 1st, 2026.
|
|
|
|
(c) 3FONIA Software; WWW.3FONIA.COM.
|
|
|
|
*******************************************************************/
|
|
|
|
'use strict';
|
|
|
|
// Helper for invoking dynamic object functions safely
|
|
const _executeFuncByName = (functionName, ...args) => {
|
|
if (!functionName) return;
|
|
const parts = functionName.split('.');
|
|
const fn = parts.reduce((curr, key) => (curr && curr[key]), window);
|
|
if (typeof fn === 'function') {
|
|
const parCon = parts.slice(0, -1).reduce((curr, key) => (curr && curr[key]), window) || window;
|
|
return fn.apply(parCon, args);
|
|
}
|
|
console.warn(`Fungsi ${functionName} tidak ada!`);
|
|
return null;
|
|
};
|
|
|
|
var FoniaJS = {
|
|
version: "3.2.0",
|
|
APP_ID: 0,
|
|
APP_SID: "",
|
|
WEB_HOST: "",
|
|
WEB_FULLPATH: "",
|
|
WEB_MOBILE: 0,
|
|
AUTH_LEVEL: 9,
|
|
User: { ID: null, UID: 0, GID: 0, Level: 0 },
|
|
locales: [],
|
|
deflocal: "",
|
|
_debug: ["localhost", "127.0.0.1"].includes(location.hostname),
|
|
|
|
setConfig(key, skey) {
|
|
if (typeof key === 'string' && key !== '') {
|
|
const data = $.base64.decode(key).split(";");
|
|
this.APP_ID = data[0];
|
|
this.APP_SID = data[1];
|
|
this.WEB_HOST = data[2];
|
|
this.WEB_FULLPATH = data[3];
|
|
this.WEB_MOBILE = data[4];
|
|
this.AUTH_LEVEL = parseInt(data[5], 10);
|
|
}
|
|
if (typeof skey === 'string' && skey !== '') {
|
|
const sdata = $.base64.decode(skey).split(";");
|
|
this.User.ID = sdata[0];
|
|
this.User.UID = parseInt(sdata[1], 10);
|
|
this.User.GID = parseInt(sdata[2], 10);
|
|
this.User.Level = parseInt(sdata[3], 10);
|
|
}
|
|
},
|
|
|
|
user_level(l = 9) {
|
|
return this.User.Level <= l;
|
|
},
|
|
|
|
user_level_not(l = 9) {
|
|
return this.User.Level !== l;
|
|
},
|
|
|
|
callMenu(p, q) {
|
|
const sendParam = [`p=${p}`];
|
|
if (q !== null) sendParam.push(`q=${q}`);
|
|
|
|
new Request({
|
|
url: "auth/menu",
|
|
sendParam,
|
|
onSuccess: (apop) => {
|
|
if (apop.login === false) {
|
|
this.showErrorLocale("Fonia.sess_expire");
|
|
setTimeout(() => { self.location = self.location.href; }, 1600);
|
|
return false;
|
|
}
|
|
if (!apop.php || !window[apop.func]) {
|
|
this.showErrorLocale("Fonia.page404");
|
|
return false;
|
|
}
|
|
window[apop.func]['PHP'] = apop.php;
|
|
window[apop.func]['KODE'] = apop.kode;
|
|
const isWin = apop.iswindow === true;
|
|
if (isWin && IndexJS.index) IndexJS.index();
|
|
new Request({
|
|
url: `${apop.php}/index`,
|
|
onSuccess: (ajson) => {
|
|
if (isWin) {
|
|
this.showWindow(apop.kode, apop.title, ajson.html, apop.width, apop.button, () => {
|
|
_executeFuncByName(`${apop.func}.index`, q);
|
|
});
|
|
} else {
|
|
$("#pageToolbarBot").html(this.genToolButton(apop.button));
|
|
$('#pageContent').html(ajson.html);
|
|
_executeFuncByName(`${apop.func}.index`, q);
|
|
}
|
|
}
|
|
}).send();
|
|
}
|
|
}).send();
|
|
},
|
|
|
|
loadMenu() {
|
|
$('.mlink').on('click', (e) => {
|
|
const sbar = $(e.currentTarget).closest('#sidebarMain');
|
|
const linkid = e.currentTarget.id.replace('Link', '');
|
|
FoniaJS.callMenu(linkid);
|
|
if (sbar.length) sbar.modal('toggle');
|
|
});
|
|
$('.slink').on('click', (e) => {
|
|
const ddown = $(e.currentTarget).closest('.dropdown-menu');
|
|
if (ddown.length) ddown.dropdown('toggle');
|
|
});
|
|
$('#HomeLink').on('click', () => {
|
|
this.closeAllWindows();
|
|
if (IndexJS.index) IndexJS.index();
|
|
});
|
|
$('#ExitLink').on('click', () => {
|
|
new Request({
|
|
url: "auth/logout",
|
|
onFailure: () => { self.location = self.location.href; },
|
|
onSuccess: (respon) => {
|
|
self.location = (respon && respon.nexthost !== '/') ? respon.nexthost : self.location.href;
|
|
}
|
|
}).send();
|
|
});
|
|
},
|
|
|
|
_showToast(message, bgClass, wtime = 3000) {
|
|
const $toast = $(`
|
|
<div class="toast align-items-center text-white ${bgClass} border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="${wtime}">
|
|
<div class="d-flex">
|
|
<div class="toast-body me-2">${message}</div>
|
|
<button type="button" class="btn-close me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
|
</div>
|
|
</div>
|
|
`).appendTo('#div-toast');
|
|
$toast.on('hidden.bs.toast', (e) => $(e.currentTarget).remove());
|
|
(new bootstrap.Toast($toast)).show();
|
|
},
|
|
|
|
showInfo(message, wtime) {
|
|
this._showToast(message, 'bg-info', wtime);
|
|
},
|
|
|
|
showError(message, wtime) {
|
|
this._showToast(message, 'bg-danger', wtime);
|
|
},
|
|
|
|
showInfoLocale(tobj, wtime) {
|
|
this.showInfo(this.locale(tobj), wtime);
|
|
},
|
|
|
|
showErrorLocale(tobj, wtime) {
|
|
this.showError(this.locale(tobj), wtime);
|
|
},
|
|
|
|
showAuth(fungcall, ocall, tmsg, bnotsuper, buserover) {
|
|
const _breq = ocall !== null;
|
|
const _bsuper = bnotsuper == null ? true : !bnotsuper;
|
|
const _buover = buserover ?? false;
|
|
const _tsid = Math.floor(Math.random() * 99999999);
|
|
let _ceksuper = null;
|
|
const _isi = `
|
|
<div class="row mb-1" id="Auth_SP1">
|
|
<div class="col-sm-6 col-lg-5 col-form-label">Username</div>
|
|
<div class="col-sm-6 col-lg-7">
|
|
<input type="text" class="form-control" id="UID" name="UID" value="${!_bsuper ? this.User.ID : ''}" required="true">
|
|
</div>
|
|
</div>
|
|
<div class="row mb-1" id="Auth_SP2">
|
|
<div class="col-sm-6 col-lg-5 col-form-label">Password</div>
|
|
<div class="col-sm-6 col-lg-7">
|
|
<input type="password" class="form-control" id="PWD" name="PWD" value="" required="true">
|
|
</div>
|
|
</div>
|
|
<div class="row mb-1 d-none" id="Auth_SP3">
|
|
<div class="col-12 text-center"><p>${this.locale("Fonia.auth_wait_msg")}</p></div>
|
|
</div>
|
|
<hr class="my-2">
|
|
<div class="row mt-1">
|
|
<div class="col-4">
|
|
<button type="button" class="btn btn-outline-primary shadow-none" id="butSReq">Request</button>
|
|
</div>
|
|
<div class="col-8 text-end">
|
|
<button type="button" class="btn btn-danger me-2" id="butSBatal" data-bs-dismiss="modal">Batal</button>
|
|
<button type="button" class="btn btn-success" id="butSOK">OK</button>
|
|
</div>
|
|
</div>`;
|
|
const authTitle = (this.AUTH_LEVEL < 9 && _bsuper) ? this.locale("Fonia.auth_super") : this.locale("Fonia.auth_user");
|
|
|
|
this.winSAuth = this.showWindow('SAuth', authTitle, _isi, 'sm', '', () => {
|
|
$('#butSOK').on('click', () => {
|
|
$('#butSOK').prop('disabled', true);
|
|
new Request({
|
|
url: "auth/supervisi",
|
|
sendParam: ["data=super-check", "UID", "PWD", `SUPER=${_bsuper}`, `UOVER=${_buover}`],
|
|
onSuccess: (adata) => {
|
|
if (adata.status === 1) fungcall();
|
|
else this.showError(adata.pesan);
|
|
this.closeWindow(this.winSAuth);
|
|
}
|
|
}).send();
|
|
});
|
|
$('#butSBatal').on('click', () => {
|
|
if (_ceksuper) {
|
|
clearInterval(_ceksuper);
|
|
new Request({
|
|
url: "auth/supervisi",
|
|
sendParam: ["data=super-cancel", `KODE=${ocall.KODE}`, `REQ_SID=${this.APP_SID}`, `REQ=${_tsid}`]
|
|
}).send();
|
|
}
|
|
});
|
|
$('#butSReq').on('click', () => {
|
|
if (!_breq) return false;
|
|
$('#Auth_SP1, #Auth_SP2').addClass('d-none');
|
|
$('#Auth_SP3').removeClass('d-none');
|
|
$('#butSOK').prop('disabled', true);
|
|
new Request({
|
|
url: "auth/supervisi",
|
|
sendParam: ["data=super-request", `KODE=${ocall.KODE}`, `REQ_SID=${this.APP_SID}`, `REQ=${_tsid}`, `MSG=${tmsg}`]
|
|
}).send();
|
|
let _cobalagi = 5;
|
|
_ceksuper = setInterval(() => {
|
|
$('#butSBatal').html(`${this.locale("Fonia.cancel")} (${_cobalagi})`);
|
|
if (_cobalagi === 0) {
|
|
clearInterval(_ceksuper);
|
|
new Request({
|
|
url: "auth/supervisi",
|
|
sendParam: ["data=super-cancel", `KODE=${ocall.KODE}`, `REQ_SID=${this.APP_SID}`, `REQ=${_tsid}`]
|
|
}).send();
|
|
this.closeWindow(this.winSAuth);
|
|
this.showErrorLocale("Fonia.auth_fail");
|
|
return false;
|
|
}
|
|
new Request({
|
|
url: "auth/supervisi",
|
|
sendParam: ["data=request-check", `KODE=${ocall.KODE}`, `REQ_SID=${this.APP_SID}`, `REQ=${_tsid}`],
|
|
onSuccess: (adata) => {
|
|
if (adata.status === 1) {
|
|
clearInterval(_ceksuper);
|
|
this.showInfoLocale("Fonia.auth_success");
|
|
fungcall();
|
|
this.closeWindow(this.winSAuth);
|
|
} else {
|
|
_cobalagi--;
|
|
}
|
|
}
|
|
}).send();
|
|
}, 3000);
|
|
});
|
|
$('#UID').on('keyup', (e) => {
|
|
if ([13, 9].includes(e.which) && e.currentTarget.value !== '') $('#PWD').focus();
|
|
});
|
|
$('#PWD').on('keyup', (e) => {
|
|
if (e.currentTarget.value !== '' && e.which === 13) $('#butSOK').trigger('click');
|
|
});
|
|
FoniaJS.setFocus(_bsuper === false ? "#PWD" : "#UID");
|
|
});
|
|
},
|
|
|
|
genWinToolBut(menu) {
|
|
if (!menu || typeof menu !== 'object') {
|
|
if (this._debug && menu) console.log('menu not object' + menu);
|
|
return '';
|
|
}
|
|
let ma = ' me-sm-2';
|
|
let smenu = '<div class="col-12 col-md-auto px-0 text-center text-sm-start">';
|
|
$(menu).each((i, atom) => {
|
|
if (Object.keys(atom).length === 0) {
|
|
smenu += '</div><div class="col-12 col-sm-auto px-0 text-center text-sm-end">';
|
|
ma = ' ms-sm-2';
|
|
} else {
|
|
if (atom.i === 'butTutup' || atom.i === 'butBatal') {
|
|
atom.v = atom.i === 'butTutup' ? 'Tutup' : 'Batal';
|
|
atom.c = 'danger';
|
|
atom.d = '';
|
|
}
|
|
const xt = atom?.d !== undefined ? ' data-bs-dismiss="modal"' : '';
|
|
smenu += `<button type="button" class="btn btn-${atom?.c ?? 'info'} mb-2 mb-sm-0${ma} col-10 col-sm-auto" id="${atom.i}"${xt}>${atom.v}</button>`;
|
|
}
|
|
});
|
|
return smenu + '</div>';
|
|
},
|
|
|
|
genToolButton(menu) {
|
|
if (!menu || typeof menu !== 'object') {
|
|
if (this._debug && menu) console.log('menu not object' + menu);
|
|
return '';
|
|
}
|
|
let ma = ' me-sm-2';
|
|
let smenu = '<div class="row mt-2 my-sm-2 justify-content-sm-between"><div class="col-sm-6 text-center text-sm-start">';
|
|
$(menu).each((i, atom) => {
|
|
if (Object.keys(atom).length === 0) {
|
|
smenu += '</div><div class="col-sm-6 text-center text-sm-end">';
|
|
ma = ' ms-sm-2';
|
|
} else {
|
|
if (atom.i === 'butTutup' || atom.i === 'butBatal') {
|
|
atom.v = atom.i === 'butTutup' ? 'Tutup' : 'Batal';
|
|
atom.c = 'danger';
|
|
atom.d = '';
|
|
}
|
|
smenu += `<button type="button" class="btn btn-${atom?.c ?? 'info'} mb-2 mb-sm-0${ma} col-10 col-sm-3" id="${atom.i}">${atom.v}</button>`;
|
|
}
|
|
});
|
|
return smenu + '</div></div>';
|
|
},
|
|
|
|
FormDecorated() {
|
|
const cleanInputVal = (val) => {
|
|
let res = val.replace(/[^0-9.-]/g, '');
|
|
if (res.indexOf('-') > 0) res = res.charAt(0) + res.slice(1).replace(/-/g, '');
|
|
const parts = res.split('.');
|
|
return parts.length > 2 ? parts[0] + '.' + parts.slice(1).join('') : res;
|
|
};
|
|
|
|
$('input.form-control[class*=integer], input.form-control[class*=angka]').each((i, el) => {
|
|
const elm = $(el);
|
|
if (elm.attr('o3')) return;
|
|
elm.attr('o3', '1').on('keypress keyup paste', (e) => {
|
|
elm.val(elm.val().replace(/[^\d].+/, ""));
|
|
if (e.which < 48 || e.which > 57) e.preventDefault();
|
|
});
|
|
});
|
|
|
|
$('input.form-control[class*=double], input.form-control[type=number]').each((i, el) => {
|
|
const elm = $(el);
|
|
if (elm.attr('o3')) return;
|
|
elm.attr('o3', '1').on('keypress keyup input', (e) => {
|
|
if (e.type === 'keypress') {
|
|
if ((e.which !== 45 || elm.val().includes('-')) && (e.which !== 46 || elm.val().includes('.')) && (e.which < 48 || e.which > 57)) {
|
|
e.preventDefault();
|
|
}
|
|
} else {
|
|
elm.val(cleanInputVal(elm.val()));
|
|
}
|
|
});
|
|
|
|
if (elm.hasClass('double')) {
|
|
elm.on('blur', () => elm.val(FoniaJS.FloatToStr(elm.val(), 2)))
|
|
.on('focus', (e) => {
|
|
elm.val(FoniaJS.StrToFloat(elm.val()));
|
|
elm.select();
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
});
|
|
|
|
$('input.form-control, textarea.form-control, select.form-select').each((i, el) => {
|
|
const elm = $(el);
|
|
if (elm.attr('o3')) return;
|
|
elm.attr('o3', '1').on('keyup blur change', (e) => {
|
|
const fnAttr = elm.attr(`o${e.type === 'keyup' ? 'kyup' : e.type === 'blur' ? 'blur' : 'chan'}`);
|
|
if (fnAttr) _executeFuncByName(fnAttr);
|
|
|
|
e.preventDefault();
|
|
});
|
|
});
|
|
|
|
$('input.form-check-input[type=radio]').each((i, el) => {
|
|
const elm = $(el);
|
|
if (elm.attr('o3')) return;
|
|
elm.attr('o3', '1').on('click', () => {
|
|
const oclic = elm.attr('ochan');
|
|
const elp = $('#' + elm.attr('name'));
|
|
if (elp.length && elm.is(':checked')) elp.val(elm.val());
|
|
if (oclic) _executeFuncByName(oclic);
|
|
});
|
|
});
|
|
|
|
$('input.form-check-input[type=checkbox]').each((i, el) => {
|
|
const elm = $(el);
|
|
if (elm.attr('o3')) return;
|
|
elm.attr('o3', '1').on('change', () => {
|
|
const odata = JSON.parse(elm.attr('odata') ?? '[]');
|
|
const ochan = elm.attr('ochan');
|
|
if (odata.length > 0) elm.val(elm.is(':checked') ? odata[0] : odata[1]);
|
|
if (ochan) _executeFuncByName(ochan);
|
|
});
|
|
});
|
|
|
|
$('input[class*=error][type=hidden]').each((i, el) => this.showError($(el).val()));
|
|
|
|
$('.option-tags').each((i, el) => {
|
|
const elm = $(el);
|
|
if (typeof $.fn.select2 !== 'function') return;
|
|
const _opts = { tags: false, dropdownAutoWidth: true, width: 'auto', theme: 'bootstrap-5', language: 'id' };
|
|
const _dmodal = elm.closest('div.modal');
|
|
if (_dmodal.length) _opts.dropdownParent = _dmodal;
|
|
elm.select2(_opts);
|
|
if (elm.prop('required')) elm.removeAttr('required');
|
|
});
|
|
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
|
|
if (typeof $.fn.datepicker === 'function') {
|
|
$('.input-group.date').datepicker({
|
|
format: 'dd-mm-yyyy',
|
|
weekStart: 1,
|
|
language: 'id',
|
|
autoclose: true,
|
|
todayHighlight: true,
|
|
enableOnReadonly: false
|
|
});
|
|
}
|
|
if (typeof autosize === 'function') autosize($('textarea'));
|
|
},
|
|
|
|
RequestParam(aparam) {
|
|
const _cblist = {};
|
|
const _ohasil = {};
|
|
|
|
$('tbody input[id*="cbox"][type="checkbox"]:checked').each((i, b) => {
|
|
const arr = b.id.split('_');
|
|
if (!_cblist[arr[0]]) _cblist[arr[0]] = [];
|
|
_cblist[arr[0]].push(arr[2]);
|
|
});
|
|
|
|
$.each(_cblist, (i, b) => {
|
|
_ohasil[`List_CB_${i}`] = b.join();
|
|
});
|
|
|
|
if (Array.isArray(aparam)) {
|
|
aparam.forEach(_par => {
|
|
if (typeof _par !== "string") return;
|
|
const _ind = _par.indexOf('=');
|
|
if (_ind !== -1) {
|
|
_ohasil[_par.slice(0, _ind)] = _par.slice(_ind + 1);
|
|
} else if ($(`#${_par}`).length) {
|
|
const $elem = $(`#${_par}`);
|
|
let _val = $elem.val();
|
|
const isNum = $elem.is('.integer, .number, .double');
|
|
|
|
if (_val === undefined) {
|
|
_val = isNum ? 0 : '';
|
|
} else {
|
|
_val = isNum ? this.StrToFloat(_val) : encodeURIComponent(_val);
|
|
}
|
|
_ohasil[_par] = _val;
|
|
}
|
|
});
|
|
}
|
|
_ohasil['SID'] = Math.floor(Math.random() * 99999999);
|
|
return _ohasil;
|
|
},
|
|
|
|
StrToFloat(str_val) {
|
|
if (!str_val) return 0;
|
|
const pref = /[()-]/.test(str_val) ? '-' : '';
|
|
return parseFloat(pref + String(str_val).replace(/[(),-]/g, ''));
|
|
},
|
|
|
|
FloatToStr(nangka, ndesi = 2) {
|
|
const num = nangka ? Number(nangka) : 0;
|
|
return new Intl.NumberFormat('en-US', {
|
|
minimumFractionDigits: ndesi,
|
|
maximumFractionDigits: ndesi
|
|
}).format(num);
|
|
},
|
|
|
|
formatBytes(bytes, deci = 0) {
|
|
if (bytes === 0) return '0 Bytes';
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
return `${parseFloat((bytes / Math.pow(1024, i)).toFixed(deci))} ${sizes[i]}`;
|
|
},
|
|
|
|
showConfirm(str_judul, str_isi, func_callback, conf_tipe) {
|
|
const _cfunc = typeof func_callback === "function" ? func_callback : () => {};
|
|
const _ctipe = conf_tipe == null ? 'modal-warning' : `modal-${conf_tipe}`;
|
|
const _btipe = conf_tipe == null ? 'btn-warning' : `btn-${conf_tipe}`;
|
|
|
|
const _wtxt = `
|
|
<div class="modal fade" id="winAPPConf" tabindex="-1" role="dialog" data-bs-keyboard="false" data-bs-show="false" data-bs-backdrop="false" aria-labelledby="winAPPConfLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered ${_ctipe} modal-400" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="winAPPConfLabel">${str_judul}</h5>
|
|
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body text-center text-break mh-100">${str_isi}</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tidak</button>
|
|
<button type="button" class="btn ${_btipe} ms-2" id="winConfirmY">Ya</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>`;
|
|
|
|
if ($('#winAPPConf').length) $('#winAPPConf').modal('dispose').remove();
|
|
|
|
$(_wtxt).on('shown.bs.modal', () => {
|
|
$('#winConfirmY').focus().on('click', () => {
|
|
_cfunc();
|
|
$('#winAPPConf').modal('hide');
|
|
});
|
|
}).modal('show');
|
|
},
|
|
|
|
showWindow(id_wind, s_judul, s_isi, i_width, s_toolb, f_onload, f_offload, b_scroll) {
|
|
let t_width = '';
|
|
const t_scroll = b_scroll === false ? '' : 'modal-dialog-scrollable';
|
|
const f_oncall = typeof f_onload === "function" ? f_onload : () => {};
|
|
const f_offcall = typeof f_offload === "function" ? f_offload : () => {};
|
|
|
|
if (typeof i_width === 'string') t_width = `modal-${i_width}`;
|
|
else if (i_width <= 300) t_width = 'modal-sm';
|
|
else if (i_width <= 400) t_width = 'modal-400';
|
|
else if (i_width <= 500) t_width = 'modal-500';
|
|
else if (i_width <= 800) t_width = 'modal-lg';
|
|
else if (i_width <= 1200) t_width = 'modal-xl';
|
|
else t_width = 'modal-fs';
|
|
|
|
let t_toolb = '';
|
|
if (s_toolb) {
|
|
t_toolb = `<div class="modal-footer justify-content-sm-between">${this.genWinToolBut(s_toolb)}</div>`;
|
|
}
|
|
|
|
const _wtxt = `
|
|
<div class="modal fade" id="win${id_wind}" tabindex="-1" data-bs-keyboard="false" data-bs-backdrop="static" aria-labelledby="win${id_wind}Label" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered ${t_scroll} ${t_width}">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="win${id_wind}Label">${s_judul}</h5>
|
|
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">${s_isi}</div>
|
|
${t_toolb}
|
|
</div>
|
|
</div>
|
|
</div>`;
|
|
|
|
if ($(`#win${id_wind}`).length) $(`#win${id_wind}`).modal('dispose').remove();
|
|
|
|
$(_wtxt).on('shown.bs.modal', () => {
|
|
f_oncall();
|
|
FoniaJS.FormDecorated();
|
|
}).on('hidden.bs.modal', (e) => {
|
|
f_offcall();
|
|
$(e.currentTarget).remove();
|
|
}).modal('show');
|
|
|
|
return `#win${id_wind}`;
|
|
},
|
|
|
|
closeWindow(elWin) {
|
|
if ($(elWin).length) $(elWin).modal('hide');
|
|
},
|
|
|
|
closeAllWindows() {
|
|
$(".modal").each((i, el) => {
|
|
const $el = $(el);
|
|
if ($el.hasClass('show')) $el.modal('toggle');
|
|
if ($el.attr('id') !== 'sidebarMain') $el.modal('dispose').remove();
|
|
});
|
|
$(".fon-autotext, .fon-autopos").remove();
|
|
if ($("#dataPrint").length) $("#dataPrint").empty();
|
|
},
|
|
|
|
setFocus(obj) {
|
|
$(obj).select().focus();
|
|
},
|
|
|
|
lPad(n, width, z = "0") {
|
|
return String(n).padStart(width, z);
|
|
},
|
|
|
|
setCookie(cname, cvalue, exdays) {
|
|
const d = new Date();
|
|
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
|
|
document.cookie = `f${this.APP_ID}_${cname}=${cvalue};expires=${d.toUTCString()};path=/`;
|
|
},
|
|
|
|
getCookie(cname) {
|
|
const name = `f${this.APP_ID}_${cname}=`;
|
|
const ca = document.cookie.split(';');
|
|
for (let c of ca) {
|
|
c = c.trim();
|
|
if (c.indexOf(name) === 0) return c.substring(name.length);
|
|
}
|
|
return "";
|
|
},
|
|
|
|
locale(key, oset) {
|
|
if (typeof oset === "object") {
|
|
this.locales[key] = oset;
|
|
if (this.deflocal === '') this.deflocal = key;
|
|
} else {
|
|
if (!this.locales[this.deflocal]) return "";
|
|
return key.split('.').reduce((cur, k) => cur?.[k], this.locales[this.deflocal]);
|
|
}
|
|
},
|
|
|
|
AutoComplete(elm, turl, aparam, options) {
|
|
let objComp = {
|
|
preventEnter: true,
|
|
resolverSettings: {
|
|
url: turl,
|
|
param: Array.isArray(aparam) || typeof aparam === 'object' ? aparam : []
|
|
}
|
|
};
|
|
if (typeof options === 'object') objComp = $.extend(true, {}, objComp, options);
|
|
|
|
$(elm).off().nextAll('div.bootstrap-autocomplete').remove();
|
|
$(elm).closest('div.modal-body, div.modal-content').css('overflow', 'visible');
|
|
new AutoComplete(elm, objComp);
|
|
},
|
|
|
|
getAppID() {
|
|
return this.APP_ID;
|
|
}
|
|
};
|
|
|
|
class Request {
|
|
options = {
|
|
url: '',
|
|
sendParam: [],
|
|
onSuccess: () => {},
|
|
onFailure: () => {},
|
|
data: null,
|
|
dataType: 'json'
|
|
};
|
|
|
|
constructor(options) {
|
|
$.extend(this.options, options);
|
|
}
|
|
|
|
send() {
|
|
if (!this.options.url) {
|
|
console.log(`${this.options.sendParam}, cek url php!`);
|
|
return false;
|
|
}
|
|
this.options.data = $.extend(this.options.data, FoniaJS.RequestParam(this.options.sendParam));
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: this.options.url,
|
|
data: this.options.data,
|
|
success: typeof this.options.onSuccess === "function" ? this.options.onSuccess : () => {},
|
|
error: typeof this.options.onFailure === "function" ? this.options.onFailure : () => {},
|
|
complete: FoniaJS.FormDecorated(),
|
|
dataType: this.options.dataType
|
|
});
|
|
return this;
|
|
}
|
|
}
|
|
|
|
class Request_JSF extends Request {
|
|
constructor(options) {
|
|
const _options = Object.assign({}, options);
|
|
_options.onSuccess = (data) => {
|
|
if (data?.length > 0) {
|
|
data.forEach((ini) => {
|
|
if (ini.type === "table" && $(ini.id)) this.make_table(ini);
|
|
if (ini.type === "form" && $(ini.id)) this.make_form(ini);
|
|
if (ini.type === "option" && $(ini.id)) this.make_option(ini);
|
|
if (ini.type === "html" && $(ini.id)) this.make_html(ini);
|
|
if (ini.type === "msg") this.show_msg(ini);
|
|
});
|
|
}
|
|
if (typeof options.onSuccess === "function") options.onSuccess(data);
|
|
};
|
|
super(_options);
|
|
}
|
|
|
|
show_msg(ini) {
|
|
const wtime = parseInt(ini.wait, 10);
|
|
if (ini.mode === "error") FoniaJS.showError(ini.value, wtime);
|
|
else FoniaJS.showInfo(ini.value, wtime);
|
|
}
|
|
|
|
make_html(ini) {
|
|
$(`#${ini.id}`).html(ini.value);
|
|
}
|
|
|
|
make_form(ini) {
|
|
const formIni = $(`#${ini.id}`);
|
|
formIni.val(ini.value);
|
|
if (ini.css) formIni.prop('disabled', ini.css === 'disabled');
|
|
}
|
|
|
|
make_option(ini) {
|
|
const optIni = $(`#${ini.id}`);
|
|
if (!optIni.length) return;
|
|
|
|
if (ini.avalue) {
|
|
optIni.empty();
|
|
let o_group = 0;
|
|
ini.avalue.forEach((i) => {
|
|
if (i.optgroup) {
|
|
if (0 < o_group++) optIni.append('</optgroup>');
|
|
optIni.append(`<optgroup label="${i.optgroup}">`);
|
|
return;
|
|
}
|
|
optIni.append($('<option>', {
|
|
value: i.value, text: i.html || '\u00A0', label: i.text || '', 'olabel': i.label || ''
|
|
}));
|
|
});
|
|
if (o_group > 0) optIni.append('</optgroup>');
|
|
}
|
|
if (ini.value) optIni.val(ini.value);
|
|
optIni.trigger('change');
|
|
}
|
|
|
|
make_table(ini) {
|
|
const divData = $(`#${ini.id}`).empty();
|
|
let strHead = '<thead><tr>', iCol = 0, aSortCol = [], aTombol = [];
|
|
|
|
$(ini.header).each((key, val) => {
|
|
if (val.o === ini.config.sort_col) iCol = key;
|
|
strHead += `<th data-class-name="${val.f}">${val.c}</th>`;
|
|
aSortCol.push(val.s ? { 'orderDataType': val.s } : null);
|
|
});
|
|
|
|
let ChkField = '';
|
|
if (ini.option.length > 0) {
|
|
let strAksi = 'Aksi';
|
|
$(ini.option).each((key, val) => {
|
|
if (val.type === 'checkbox') {
|
|
strAksi = `<input class="form-check-input" type="checkbox" id="${ini.id}_cbhead_${val.field}" value="${val.avalue[1]}">`;
|
|
ChkField = val.field;
|
|
}
|
|
if (['button', 'button-dt'].includes(val.type)) {
|
|
aTombol[val.icon] = [val.label, val.type === 'button' ? 0 : 1];
|
|
}
|
|
});
|
|
strHead += `<th data-class-name="c">${strAksi}</th>`;
|
|
} else {
|
|
strHead += '<th data-class-name="hid"> </th>';
|
|
}
|
|
aSortCol.push({ 'orderable': false });
|
|
strHead += '</tr></thead>';
|
|
|
|
let strFoot = '';
|
|
if (ini.footer) {
|
|
strFoot = '<tfoot><tr>';
|
|
$(ini.footer).each((key, val) => {
|
|
strFoot += `<th class="${ini.header[key].f}">${val.c}</th>`;
|
|
});
|
|
strFoot += '<th> </th></tr></tfoot>';
|
|
}
|
|
|
|
let sClass = ini.config.css ? ` ${ini.config.css}` : '';
|
|
if (ini.config.func_select) sClass += ' table-select';
|
|
const strTab = `<table id="${ini.id}Tabel" class="table table-striped table-bordered table-hover${sClass}">`;
|
|
|
|
let strBody = '<tbody>';
|
|
$(ini.content).each((key, val) => {
|
|
strBody += '<tr>';
|
|
val.forEach((vali, keyi) => {
|
|
if (keyi === 0) return;
|
|
strBody += `<td>${vali}</td>`;
|
|
});
|
|
|
|
let _tbtn1 = "", _tbtn2 = "";
|
|
if (val[0].rowcss) _tbtn1 += `<span class="rowcss ${val[0].rowcss}"></span>`;
|
|
|
|
if (ini.option.length > 0) {
|
|
if (val[0].button.length > 0) {
|
|
val[0].button.forEach((valb) => {
|
|
const _link = aTombol[valb[0]][1] === 1 ? 'fon-tabel-dt' : valb[0];
|
|
const _cssa = valb[1] === '' ? '' : ` text-${valb[1]}`;
|
|
const _cssb = valb[1] === '' ? ' normal' : ` btn-${valb[1]}`;
|
|
if (ini.config.txtbutton === true) {
|
|
_tbtn1 += `<button class="btn tbl-rowbtn d-none d-lg-inline-block ${_link}${_cssb} me-2${val[0].button.length > 1 ? ' mb-2' : ''}" type="button">${aTombol[valb[0]][0]}</button>`;
|
|
_tbtn2 += `<a class="table-icon d-lg-none ${_link}${_cssa}" tabindex="-1" title="${aTombol[valb[0]][0]}"><i class="bi-${valb[0]}"></i></a>`;
|
|
} else {
|
|
_tbtn2 += `<a class="table-icon ${_link}${_cssa}" title="${aTombol[valb[0]][0]}"><i class="bi-${valb[0]}"></i></a>`;
|
|
}
|
|
});
|
|
}
|
|
if (val[0].checkbox) {
|
|
_tbtn1 += `<div><input class="form-check-input" type="checkbox" id="${ChkField}_cbox_${val[0].checkbox.field}" value="${val[0].checkbox.value}"></div>`;
|
|
}
|
|
}
|
|
strBody += `<td class="${ini.config.txtbutton === true ? '' : 'text-nowrap'}">${_tbtn1}${_tbtn2}</td></tr>`;
|
|
});
|
|
strBody += '</tbody>';
|
|
|
|
$(divData).append(`${strTab}${strHead}${strBody}${strFoot}</table>`);
|
|
|
|
const opsi = {
|
|
responsive: true,
|
|
columnDefs: [{ responsivePriority: 1, targets: 0 }, { responsivePriority: 2, targets: 1 }, { responsivePriority: 0, targets: -1 }],
|
|
lengthMenu: [],
|
|
dom: '<"row"<"col-sm-12"tr>><"row"<"col-sm-12 col-lg-auto"<"toolbar">><"col-sm-3 col-lg-auto ms-lg-auto"l><"col-sm-9 col-lg-auto"p>>',
|
|
autoWidth: false,
|
|
processing: true,
|
|
searching: false,
|
|
columns: aSortCol,
|
|
order: [[iCol, ini.config.sort_dir === 'A' ? 'asc' : 'desc']],
|
|
pageLength: ini.config.row_count,
|
|
stateSave: true,
|
|
stateSaveCallback: (sett, data) => localStorage.setItem(ini.id, JSON.stringify(data)),
|
|
stateLoadCallback: () => {
|
|
try {
|
|
const data = JSON.parse(localStorage.getItem(ini.id)) ?? {};
|
|
data.length = ini.config.row_count;
|
|
return data;
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
};
|
|
|
|
if (ini.config.live) {
|
|
$.each(this.options.data, (key, val) => {
|
|
if (key === 'SID') this.options.data[key] = Math.floor(Math.random() * 99999999);
|
|
if (key === 'mode_detail') this.options.data[key] = 'live-data';
|
|
});
|
|
|
|
opsi.serverSide = true;
|
|
opsi.ajax = {
|
|
url: this.options.url,
|
|
type: 'POST',
|
|
data: this.options.data,
|
|
dataFilter: (data) => {
|
|
let jsono = { 'draw': 0, 'recordsTotal': 0, 'recordsFiltered': 0, 'data': [] };
|
|
try {
|
|
const json = JSON.parse(data);
|
|
if (!$.isEmptyObject(json) && json.length > 0) {
|
|
json.forEach((lini) => {
|
|
if (lini.type === 'table-live' && lini.id === ini.id) {
|
|
jsono.draw = lini.config.draw;
|
|
jsono.recordsTotal = lini.config.recordsTotal;
|
|
jsono.recordsFiltered = lini.config.recordsFiltered;
|
|
jsono.data = lini.data;
|
|
}
|
|
});
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
|
|
jsono.data.forEach((val, key) => {
|
|
const optval = val[0];
|
|
jsono.data[key].shift();
|
|
let _tbtn1 = "", _tbtn2 = "";
|
|
|
|
if (optval.rowcss) _tbtn1 += `<span class="rowcss ${optval.rowcss}"></span>`;
|
|
if (ini.option.length > 0) {
|
|
if (optval.button.length > 0) {
|
|
optval.button.forEach((valb) => {
|
|
const _link = aTombol[valb[0]][1] === 1 ? 'fon-tabel-dt' : valb[0];
|
|
const _cssa = valb[1] === '' ? '' : ` text-${valb[1]}`;
|
|
const _cssb = valb[1] === '' ? ' normal' : ` btn-${valb[1]}`;
|
|
if (ini.config.txtbutton === true) {
|
|
_tbtn1 += `<button class="btn tbl-rowbtn d-none d-lg-inline-block ${_link}${_cssb} me-2${optval.button.length > 1 ? ' mb-2' : ''}" type="button">${aTombol[valb[0]][0]}</button>`;
|
|
_tbtn2 += `<a class="table-icon d-lg-none ${_link}${_cssa}" tabindex="-1" title="${aTombol[valb[0]][0]}"><i class="bi-${valb[0]}"></i></a>`;
|
|
} else {
|
|
_tbtn2 += `<a class="table-icon ${_link}${_cssa}" title="${aTombol[valb[0]][0]}"><i class="bi-${valb[0]}"></i></a>`;
|
|
}
|
|
});
|
|
}
|
|
if (optval.checkbox) {
|
|
_tbtn1 += `<div><input class="form-check-input" type="checkbox" id="${ChkField}_cbox_${optval.checkbox.field}" value="${optval.checkbox.value}"></div>`;
|
|
}
|
|
}
|
|
jsono.data[key].push(_tbtn1 + _tbtn2);
|
|
});
|
|
return JSON.stringify(jsono);
|
|
}
|
|
};
|
|
}
|
|
|
|
if (ini.option.length > 0) opsi.columnDefs.push({ responsivePriority: 3, targets: -1 }, { orderable: false, targets: -1 });
|
|
if (ini.navi.no_navi === true) opsi.paging = false;
|
|
|
|
if (ini.config.scrollbar === true) {
|
|
opsi.scrollY = ini.config.scroll_height;
|
|
opsi.deferRender = true;
|
|
opsi.scroller = { loadingIndicator: true };
|
|
}
|
|
|
|
let _navibar = '';
|
|
if (ini.navi.button) {
|
|
const _dis = ini.config.nobutton === true ? ' disabled=true' : '';
|
|
const _bcss = ini.config.nobutton === true ? 'btn-secondary' : 'btn-info';
|
|
_navibar += '<div class="row"><div class="col">';
|
|
ini.navi.button.forEach((val, key) => {
|
|
_navibar += `<button type="button" class="btn rounded-pill ${_bcss} me-2 navi-btn-${key}"${_dis}>${val.label}</button>`;
|
|
});
|
|
_navibar += '</div></div>';
|
|
}
|
|
|
|
opsi.initComplete = () => {
|
|
if (ini.navi.button) {
|
|
$(`#${ini.id}Tabel_wrapper div.toolbar`).html(_navibar);
|
|
if (ini.navi.button.length > 0) {
|
|
ini.navi.button.forEach((val, key) => {
|
|
$(`#${ini.id}Tabel_wrapper div.toolbar button[class*=navi-btn-${key}]`).on('click', (e) => {
|
|
e.preventDefault();
|
|
_executeFuncByName(val.func);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
opsi.drawCallback = () => {
|
|
$(`#${ini.id}Tabel tbody td:last-child:has(span.rowcss)`).each((i, el) => {
|
|
const span = $(el).find('span').attr('class').replace('rowcss ', '');
|
|
$(el).parent().addClass(span);
|
|
});
|
|
|
|
$(`#${ini.id}Tabel tbody td[class*="awr"]`).each((i, el) => {
|
|
const $el = $(el);
|
|
$el.attr('title', $el.html().replace(/<br\s*[\/]?>/gi, '\n').replace(/(<([^>]+)>)/gi, ''));
|
|
});
|
|
|
|
const api = this.api();
|
|
const menudiv = $(`select[name="${ini.id}Tabel_length"]`);
|
|
const record = api.page.info().recordsTotal ?? 0;
|
|
const _lmenu = [];
|
|
|
|
[10, 25, 50, 100].forEach((val) => {
|
|
if (val <= record || val === 10) _lmenu.push(val);
|
|
});
|
|
|
|
if (10 < record && !([25, 50, 100].includes(record))) {
|
|
_lmenu.push(record);
|
|
}
|
|
|
|
const _select = menudiv.val() ?? 10;
|
|
menudiv.empty();
|
|
_lmenu.forEach((val) => {
|
|
$('<option/>', { 'value': val, 'text': val }).appendTo(menudiv);
|
|
});
|
|
menudiv.val(_select);
|
|
|
|
if (ini.config.func_select) {
|
|
$(`#${ini.id}Tabel tbody`).off('click', 'tr').on('click', 'tr', (e) => {
|
|
const elm = $(e.currentTarget);
|
|
if (elm.attr('o3')) return;
|
|
elm.attr('o3', '1');
|
|
_executeFuncByName(ini.config.func_select, otabel.row(elm).data());
|
|
});
|
|
}
|
|
|
|
if (ini.option.length > 0) {
|
|
$(`#${ini.id}Tabel thead input[type=checkbox][id*=_cbhead_]`).off('change');
|
|
$(`#${ini.id}Tabel tbody input[type=checkbox][id*=_cbox_]`).off('change');
|
|
$(`#${ini.id}Tabel tbody`).off('click');
|
|
|
|
ini.option.forEach((val) => {
|
|
if (val.type === 'checkbox') {
|
|
$(`#${ini.id}Tabel thead input[type=checkbox][id*=_cbhead_]`).on('change', (e) => {
|
|
const _etarg = $(e.currentTarget);
|
|
const _chek = _etarg.is(':checked');
|
|
_etarg.val(_chek ? val.avalue[0] : val.avalue[1]);
|
|
$(`#${ini.id}Tabel tbody input[type=checkbox][id*=${val.field}_cbox_]`).each((i, el) => {
|
|
const _el = $(el);
|
|
_el.prop('checked', _chek).val(_chek ? val.avalue[0] : val.avalue[1]);
|
|
});
|
|
});
|
|
$(`#${ini.id}Tabel tbody input[type=checkbox][id*=_cbox_]`).on('change', (e) => {
|
|
const _ctarg = $(e.currentTarget);
|
|
const isZero = _ctarg.val() === val.avalue[1];
|
|
_ctarg.val(isZero ? val.avalue[0] : val.avalue[1]).prop('checked', isZero);
|
|
});
|
|
} else if (val.type === 'button') {
|
|
$(`#${ini.id}Tabel tbody`).on('click', `.${val.icon}`, (e) => {
|
|
const dta = otabel.row($(e.currentTarget).closest('tr')).data();
|
|
_executeFuncByName(val.func, dta, e.currentTarget);
|
|
});
|
|
} else if (val.type === 'button-dt') {
|
|
$(`#${ini.id}Tabel tbody`).on('click', '.fon-tabel-dt', (e) => {
|
|
const tr = $(e.currentTarget).closest('tr');
|
|
const row = otabel.row(tr);
|
|
if (row.child.isShown()) {
|
|
row.child.hide();
|
|
tr.removeClass('shown');
|
|
} else {
|
|
if (otabel.row('.shown').length) {
|
|
$('.fon-tabel-dt', otabel.row('.shown').node()).click();
|
|
}
|
|
const _dt_id = $(`<div id="TD_Fonia_${Math.floor(Math.random() * 99999999)}" class="fon-tabel-child" />`);
|
|
row.child(_dt_id).show();
|
|
tr.addClass('shown');
|
|
_executeFuncByName(val.func, row.data(), _dt_id);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
$(`#${ini.id}Tabel tbody`).on('click', 'td.dtr-control', (e) => {
|
|
const tr = $(e.currentTarget).closest('tr');
|
|
const row = otabel.row(tr);
|
|
if (row.child.isShown()) {
|
|
row.child.hide();
|
|
tr.removeClass('dt-hasChild parent');
|
|
} else {
|
|
let ind = 0;
|
|
let tampil = '<ul class="list-unstyled">';
|
|
api.columns().every(function() {
|
|
const kol = this.header();
|
|
if (kol.className.includes('dtr-hidden')) {
|
|
tampil += `<li class="py-1"><span class="d-inline-block" style="min-width:100px;">${kol.textContent}</span><span class="text-break">${row.data()[ind]}</span></li>`;
|
|
}
|
|
ind++;
|
|
});
|
|
tampil += '</ul>';
|
|
row.child(tampil).show();
|
|
tr.addClass('dt-hasChild parent');
|
|
}
|
|
});
|
|
};
|
|
|
|
const otabel = $(`#${ini.id}Tabel`).DataTable(opsi);
|
|
}
|
|
}
|
|
|
|
//const Request = (options) => new _Request(options);
|
|
//RequestF = (options) => new _Request_JSONF(options);
|
|
|
|
// jQuery Validator setup
|
|
if (jQuery.validator) {
|
|
jQuery.validator.setDefaults({
|
|
ignore: ':hidden, [readonly=readonly]',
|
|
submitHandler: () => {},
|
|
invalidHandler: () => FoniaJS.showError('Mohon lengkapi semua field yang berwarna merah !'),
|
|
highlight: (element) => $(element).addClass('is-invalid').removeClass('is-valid'),
|
|
unhighlight: (element) => $(element).addClass('is-valid').removeClass('is-invalid'),
|
|
errorPlacement: () => {}
|
|
});
|
|
|
|
jQuery.validator.addMethod('double_id', (value, el, param) => this.optional(el) || FoniaJS.StrToFloat(value) >= param, 'Nilai lebih dari Nol');
|
|
jQuery.validator.addMethod('filesize', (value, el, param) => this.optional(el) || el.files[0].size <= param, 'Ukuran file tidak diizinkan');
|
|
jQuery.validator.addMethod('notEqual', (value, el, param) => this.optional(el) || value != param, 'Ganti pilihan yang lain');
|
|
}
|
|
|
|
// DataTables extension overrides
|
|
if (jQuery.fn.dataTable) {
|
|
const dtOrder = jQuery.fn.dataTable.ext.order;
|
|
dtOrder['val-emptylast'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => $(td).html() === '' ? Number.MAX_SAFE_INTEGER : 0);
|
|
};
|
|
dtOrder['val-zerolast'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => $(td).html() == 0 ? Number.MAX_SAFE_INTEGER : $(td).html());
|
|
};
|
|
dtOrder['val-fnumber'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => $(td).text().trim().replace(/,/g, ""));
|
|
};
|
|
dtOrder['val-jam'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => moment($(td).text().trim(), "HH:mm:ss").format("X"));
|
|
};
|
|
dtOrder['val-tgl'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => moment($(td).text().trim(), "DD-MM-YYYY").format("X"));
|
|
};
|
|
dtOrder['val-tgljam'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => moment($(td).text().trim(), "DD-MM-YYYY HH:mm:ss").format("X"));
|
|
};
|
|
dtOrder['val-tgljams'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => moment($(td).text().trim(), "DD.MM.YY HH:mm:ss").format("X"));
|
|
};
|
|
dtOrder['dom-checkbox'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => $('input', td).prop('checked') ? '1' : '0');
|
|
};
|
|
dtOrder['dom-select-zerolast'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => $('select', td).val() == 0 ? Number.MAX_SAFE_INTEGER : $('select', td).val());
|
|
};
|
|
dtOrder['dom-nomen'] = function(settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes().map((td) => $(td).text().trim().replace('X.XX', '0.00'));
|
|
};
|
|
|
|
jQuery.extend(jQuery.fn.dataTable.ext.classes, { sLengthSelect: "form-select text-center" });
|
|
jQuery.extend(jQuery.fn.dataTable.defaults.oLanguage, {
|
|
"oAria": {
|
|
"sSortAscending": ": aktifkan urutan kolom keatas",
|
|
"sSortDescending": ": aktifkan urutan kolom kebawah"
|
|
},
|
|
"oPaginate": {
|
|
"sFirst": "<i class=\"bi-skip-backward\"></i>",
|
|
"sPrevious": "<i class=\"bi-rewind\"></i>",
|
|
"sNext": "<i class=\"bi-fast-forward\"></i>",
|
|
"sLast": "<i class=\"bi-skip-forward\"></i>"
|
|
},
|
|
"sEmptyTable": "Tidak ada data yang tersedia pada tabel ini",
|
|
"sProcessing": "",
|
|
"sLengthMenu": "_MENU_",
|
|
"sZeroRecords": "Tidak ditemukan data yang sesuai",
|
|
"sInfo": "Menampilkan _START_ sampai _END_ dari _TOTAL_ entri",
|
|
"sInfoEmpty": "Menampilkan 0 sampai 0 dari 0 entri",
|
|
"sInfoFiltered": "(disaring dari _MAX_ entri keseluruhan)",
|
|
"sInfoPostFix": "",
|
|
"sSearch": "Cari:",
|
|
"sUrl": "",
|
|
"sLoadingRecords": "Memuat...",
|
|
"sSearchPlaceholder": "Cari Kata Kunci",
|
|
"sDecimal": ",",
|
|
"sThousands": "."
|
|
});
|
|
}
|