Refactor multiple JavaScript classes to use ES6 syntax, including Download, Pdf, Printer, PrinterPos, PoleDisplay, and Simulator. Update method names for consistency and improve error handling. Modify AJAX requests to enhance functionality and user experience.
This commit is contained in:
+256
-224
@@ -4,233 +4,265 @@
|
||||
Desc. : JS Class Printer & Printer POS
|
||||
Created By : Siau Pheng ([email protected]).
|
||||
Created Date : May 27th, 2007.
|
||||
Last Modified : September 21st, 2026.
|
||||
Last Modified : November 2nd, 2026.
|
||||
|
||||
(c) 3FONIA Software; WWW.3FONIA.COM.
|
||||
|
||||
*******************************************************************/
|
||||
*******************************************************************
|
||||
*
|
||||
* Class Printer
|
||||
*
|
||||
* Standard Web Document Printing & Report Preview Class
|
||||
*
|
||||
* @license MIT, https://www.3fonia.com
|
||||
* @copyright Copyright (c) 2008-2026, Siau Pheng <[email protected]>
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {string} options.url - Endpoint URL Print Page
|
||||
* @param {number} [options.zoom=90] - Zoom percentage in viewer
|
||||
* @param {Array} [options.params] - Request payload
|
||||
*/
|
||||
|
||||
var Printer = function(options){
|
||||
var vars = {
|
||||
'url': '',
|
||||
'zoom': 90,
|
||||
'param': []
|
||||
};
|
||||
this.construct = function(options){
|
||||
if (typeof options == 'object') {
|
||||
$.extend(vars, options);
|
||||
} else vars.url = options;
|
||||
};
|
||||
this.set_url = function (url){
|
||||
vars.url = url;
|
||||
};
|
||||
this.set_zoom = function (zoom){
|
||||
if (zoom) vars.zoom = zoom;
|
||||
},
|
||||
this.add_param = function (par_id, par_val){
|
||||
var _getvalue = (par_val) ? par_id + "=" + escape(par_val) : par_id;
|
||||
vars.param.push(_getvalue);
|
||||
},
|
||||
this.doPrint = function(){
|
||||
if (!vars.url) {
|
||||
console.warn(vars.param + ", cek url php!");
|
||||
return false;
|
||||
}
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: vars.url,
|
||||
data: FoniaJS.RequestParam(vars.param),
|
||||
success: (txt) => {
|
||||
var $printData = $('#dataPrint');
|
||||
if (!$printData.length) {
|
||||
$printData = $('<div/>', {id:'dataPrint','class':'d-none d-print-block print-body'}).appendTo('body');
|
||||
}
|
||||
$printData.html(txt);
|
||||
window.print();
|
||||
},
|
||||
error: (typeof vars.onFailure === "function") ? vars.onFailure : null,
|
||||
});
|
||||
class Printer {
|
||||
constructor(options = {}) {
|
||||
this.url = typeof options === 'string' ? options : options.url || '';
|
||||
this.zoom = options.zoom || 90;
|
||||
this.params = options.params || [];
|
||||
}
|
||||
|
||||
addParam(id, val) {
|
||||
this.params.push(val !== undefined ? `${id}=${encodeURIComponent(val)}` : id);
|
||||
return this;
|
||||
};
|
||||
this.doPreview = function(){
|
||||
if (!vars.url) console.warn(vars.param + ", cek url php!");
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: vars.url,
|
||||
data: FoniaJS.RequestParam(vars.param),
|
||||
success: (txt) => {
|
||||
if ('' == txt) {
|
||||
FoniaJS.showInfo('Tidak ada data untuk pembuatan laporan !');
|
||||
return false;
|
||||
}
|
||||
var _wtxt =
|
||||
'<div class="modal fade" id="winAPPPrint" tabindex="-1" role="dialog" data-bs-keyboard="false" data-bs-show="false" data-bs-backdrop="static" aria-labelledby="winAPPPrintLabel" aria-hidden="true">'+
|
||||
'<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-fs" role="document">'+
|
||||
'<div class="modal-content">'+
|
||||
'<div class="modal-header"><h5 class="modal-title" id="winAPPPrintLabel">Preview Laporan</h5><div class="ms-auto"><button class="btn me-2" id="tombCetak" type="button" aria-label="Cetak"><i class="bi-printer me-2"></i><span aria-hidden="true">Cetak</span></button><button class="btn" type="button" data-bs-dismiss="modal" aria-label="Tutup"><i class="bi-x-lg me-2"></i><span aria-hidden="true">Tutup</span></button></div></div>'+
|
||||
'<div class="modal-body print-body" id="divPrintP">'+txt+'</div>'+
|
||||
'</div></div></div>';
|
||||
if ($('#winAPPPrint')) $('#winAPPPrint').modal('dispose').remove();
|
||||
$(_wtxt).on('shown.bs.modal', (e) => {
|
||||
$('#winAPPPrint').find('#tombCetak').click(() => {
|
||||
var $printData = $('#dataPrint');
|
||||
if (!$printData.length) {
|
||||
$printData = $('<div/>', {id:'dataPrint','class':'d-none d-print-block print-body'}).appendTo('body');
|
||||
}
|
||||
$printData.html($('#divPrintP').html());
|
||||
FoniaJS.closeWindow($('#winAPPPrint'));
|
||||
window.print();
|
||||
});
|
||||
}).on('hidden.bs.modal', (e) => {
|
||||
$(this).remove();
|
||||
}).modal('show');
|
||||
},
|
||||
error: (typeof vars.onFailure === "function") ? vars.onFailure : null,
|
||||
});
|
||||
};
|
||||
this.construct(options);
|
||||
};
|
||||
}
|
||||
|
||||
var PrinterPos = function(options) {
|
||||
var b_default = false;
|
||||
var _options = {
|
||||
'url': '',
|
||||
'param': [],
|
||||
'printer': null,
|
||||
'cut_paper': "\x1D\x56\x41",
|
||||
'open_draw': "\x1B\x70\x30\x19\x19",
|
||||
'chr_norm': "\x1B\x21\x01",
|
||||
'chr_bold': "\x1B\x21\x10",
|
||||
'chr_sbold': "\x1B\x21\x31",
|
||||
'chr_uline': "\x1B\x21\x80"
|
||||
};
|
||||
this.construct = function(options) {
|
||||
if (typeof options == 'object') {
|
||||
$.extend(_options, options);
|
||||
} else _options.url = options;
|
||||
if (FoniaJS._def_printer) _options.printer = FoniaJS._def_printer;
|
||||
};
|
||||
this.detectPrinter = function() {
|
||||
if (!qz.websocket.isActive()) {
|
||||
FoniaJS.showInfo('Status Printer belum Active !');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.getPrinters = function() {
|
||||
return [];
|
||||
};
|
||||
this.setPrinter = function(nprint) {
|
||||
(nprint != null) && (_options.printer = nprint);
|
||||
};
|
||||
this.useDefaultPrinter = function() {
|
||||
b_default = true;
|
||||
};
|
||||
this.set_url = function(url) {
|
||||
_options.url = url;
|
||||
};
|
||||
this.add_param = function(par_id, par_val) {
|
||||
var _getvalue = (par_val) ? par_id + '=' + escape(par_val) : par_id;
|
||||
_options.param.push(_getvalue);
|
||||
};
|
||||
this.exec = function() {
|
||||
if (!this.detectPrinter()) return;
|
||||
if (this.b_default) {
|
||||
var parent = this;
|
||||
qz.printers.getDefault().then(function(data) {
|
||||
var nama_p = data;
|
||||
if (data.name != undefined) {
|
||||
nama_p = data.name;
|
||||
}
|
||||
parent._options.param.push('Printer='+nama_p);
|
||||
return parent.do_print(nama_p, parent._options.url, parent._options.param);
|
||||
}, function(data) {
|
||||
FoniaJS.showInfo(data);
|
||||
});
|
||||
} else {
|
||||
var _nprinter = _options.printer;
|
||||
if (typeof _nprinter === 'object' && _nprinter.name == undefined) {
|
||||
if (_nprinter.file != undefined) _nprinter = _nprinter.file;
|
||||
if (_nprinter.host != undefined) _nprinter = _nprinter.host + ":" + _nprinter.port;
|
||||
} else {
|
||||
if (_nprinter.name != undefined) _nprinter = _nprinter.name;
|
||||
if (_nprinter== undefined) _nprinter = 'None';
|
||||
}
|
||||
_options.param.push('Printer='+_nprinter);
|
||||
this.do_print(_options.printer, _options.url, _options.param);
|
||||
}
|
||||
};
|
||||
this.do_print = function(nama_p, url, params) {
|
||||
var qzcfg = qz.configs.create(nama_p);
|
||||
new Request({
|
||||
url: url,
|
||||
sendParam: params,
|
||||
onSuccess: (ajson) => {
|
||||
if (typeof ajson === "object") {
|
||||
var hasil_cetak = (ajson.type == "escp") ? this.gen_escp(ajson) : this.gen_epl(ajson);
|
||||
qz.print(qzcfg, hasil_cetak);
|
||||
} else {
|
||||
FoniaJS.showInfo('Error dalam proses Cetak.');
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
this.gen_escp = function(adata) {
|
||||
var ohead = [];
|
||||
var osheet = [], ocetak = [];
|
||||
ohead.push("\x1B\x40");
|
||||
ohead.push("\x1B\x61\x01");
|
||||
if (adata.config.logo != null) {
|
||||
//ohead.push({type:'raw',format:'image',data:adata.config.logo,options:{language:'ESCPOS',dotDensity:'double'}});
|
||||
//ohead.push("\x1B\x32");
|
||||
ohead.push({type:'raw',format:'image',flavor:'base64',data:adata.config.logo,options:{language:'ESCPOS',dotDensity:'double'}});
|
||||
ohead.push("\x1B\x32");
|
||||
}
|
||||
if (parseInt(adata.config.fontsize) == 2) {
|
||||
_options.chr_norm = "\x1B\x21\x02";
|
||||
}
|
||||
if (adata.header.length > 0) {
|
||||
for (i = 0; i < adata.header.length; i++) {
|
||||
if (i==0 && adata.config.logo==null) ohead.push(_options.chr_bold);
|
||||
ohead.push(adata.header[i] + "\x0A");
|
||||
if (i==0 && adata.config.logo==null) ohead.push(_options.chr_norm);
|
||||
}
|
||||
}
|
||||
for (s = 0; s < adata.content.length; s++) {
|
||||
if (adata.content[s].length == 0) continue;
|
||||
osheet = ohead.slice(0);
|
||||
for (i = 0; i < adata.content[s].length; i++) {
|
||||
var tmp_cont = adata.content[s][i];
|
||||
tmp_cont = tmp_cont.replace('_SBOLD_', _options.chr_sbold)
|
||||
.replace('_BOLD_', _options.chr_bold)
|
||||
.replace('_NORM_', _options.chr_norm)
|
||||
.replace('_ULINE_', _options.chr_uline);
|
||||
osheet.push(tmp_cont + "\x0A");
|
||||
}
|
||||
if (adata.config.cutpaper) {
|
||||
osheet.push(_options.cut_paper + "\x0A");
|
||||
}
|
||||
ocetak = ocetak.concat(osheet);
|
||||
}
|
||||
var notaout = [];
|
||||
if (adata.config.opendraw) {
|
||||
notaout.push(_options.open_draw);
|
||||
}
|
||||
for (i = 0; i < adata.config.times; i++) {
|
||||
notaout = notaout.concat(ocetak);
|
||||
}
|
||||
return notaout;
|
||||
};
|
||||
this.gen_epl = function(adata) {
|
||||
var cetak = [];
|
||||
for (i = 0; i < adata.content.length; i++) {
|
||||
cetak.push(adata.content[i] + "\r\n");
|
||||
}
|
||||
var notaout = [];
|
||||
for (i = 0; i < adata.config.times; i++) {
|
||||
notaout = notaout.concat(cetak);
|
||||
}
|
||||
return notaout;
|
||||
};
|
||||
this.construct(options);
|
||||
};
|
||||
doPrint() {
|
||||
if (!this.url) {
|
||||
console.warn('Url Laporan dibutuhkan!');
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: this.url,
|
||||
data: FoniaJS.RequestParam(this.params),
|
||||
success: (txt) => {
|
||||
let $printData = $('#dataPrint');
|
||||
if (!$printData.length) {
|
||||
$printData = $('<div/>', {
|
||||
id: 'dataPrint',
|
||||
class: 'd-none d-print-block print-body'
|
||||
}).appendTo('body');
|
||||
}
|
||||
$printData.html(txt);
|
||||
window.print();
|
||||
},
|
||||
error: typeof this.onFailure === 'function' ? this.onFailure : null
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
doPreview() {
|
||||
if (!this.url) {
|
||||
console.warn('Url Laporan dibutuhkan!');
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: this.url,
|
||||
data: FoniaJS.RequestParam(this.params),
|
||||
success: (txt) => {
|
||||
if (!txt) {
|
||||
FoniaJS.showInfo('Tidak ada data untuk pembuatan laporan !');
|
||||
return false;
|
||||
}
|
||||
const modalHtml = `
|
||||
<div class="modal fade" id="winAPPPrint" tabindex="-1" role="dialog" data-bs-keyboard="false" data-bs-show="false" data-bs-backdrop="static" aria-labelledby="winAPPPrintLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-fs" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="winAPPPrintLabel">Preview Laporan</h5>
|
||||
<div class="ms-auto">
|
||||
<button class="btn me-2" id="tombCetak" type="button" aria-label="Cetak">
|
||||
<i class="bi-printer me-2"></i><span aria-hidden="true">Cetak</span>
|
||||
</button>
|
||||
<button class="btn" type="button" data-bs-dismiss="modal" aria-label="Tutup">
|
||||
<i class="bi-x-lg me-2"></i><span aria-hidden="true">Tutup</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body print-body" id="divPrintP">${txt}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$('#winAPPPrint').modal('dispose').remove();
|
||||
$(modalHtml)
|
||||
.on('shown.bs.modal', () => {
|
||||
$('#winAPPPrint #tombCetak').off('click').on('click', () => {
|
||||
let $printData = $('#dataPrint');
|
||||
if (!$printData.length) {
|
||||
$printData = $('<div/>', {
|
||||
id: 'dataPrint',
|
||||
class: 'd-none d-print-block print-body'
|
||||
}).appendTo('body');
|
||||
}
|
||||
$printData.html($('#divPrintP').html());
|
||||
FoniaJS.closeWindow($('#winAPPPrint'));
|
||||
window.print();
|
||||
});
|
||||
})
|
||||
.on('hidden.bs.modal', function () {
|
||||
$(this).remove();
|
||||
})
|
||||
.modal('show');
|
||||
},
|
||||
error: typeof this.onFailure === 'function' ? this.onFailure : null
|
||||
});
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class PrinterPos
|
||||
*
|
||||
* Direct Thermal POS Printer Class (via QZ Tray API)
|
||||
*
|
||||
* @license MIT, https://www.3fonia.com
|
||||
* @copyright Copyright (c) 2008-2026, Siau Pheng <[email protected]>
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {string} options.url - Endpoint URL Print Page
|
||||
* @param {number} [options.printer=FoniaJS._def_printer] - Printer Name
|
||||
* @param {Array} [options.params] - Request payload
|
||||
*/
|
||||
|
||||
class PrinterPos {
|
||||
constructor(options = {}) {
|
||||
this.url = typeof options === 'string' ? options : options.url || '';
|
||||
this.printer = options.printer || (FoniaJS._def_printer ?? null);
|
||||
this.cut_paper = options.cut_paper || '\x1D\x56\x41';
|
||||
this.open_draw = options.open_draw || '\x1B\x70\x30\x19\x19';
|
||||
this.chr_norm = options.chr_norm || '\x1B\x21\x01';
|
||||
this.chr_bold = options.chr_bold || '\x1B\x21\x10';
|
||||
this.chr_sbold = options.chr_sbold || '\x1B\x21\x31';
|
||||
this.chr_uline = options.chr_uline || '\x1B\x21\x80';
|
||||
this.params = options.params || [];
|
||||
}
|
||||
|
||||
_detectPrinter() {
|
||||
if (!qz?.websocket?.isActive?.()) {
|
||||
FoniaJS.showInfo('Status Printer belum Active !');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
setPrinter(nprint) {
|
||||
if (nprint != null) this.printer = nprint;
|
||||
return this;
|
||||
}
|
||||
|
||||
addParam(id, val) {
|
||||
this.params.push(val !== undefined ? `${id}=${encodeURIComponent(val)}` : id);
|
||||
return this;
|
||||
}
|
||||
|
||||
async exec() {
|
||||
if (!this._detectPrinter()) return;
|
||||
|
||||
let printerName = this.printer;
|
||||
if (typeof printerName === 'object' && printerName !== null) {
|
||||
if (printerName.name !== undefined) {
|
||||
printerName = printerName.name;
|
||||
} else if (printerName.file !== undefined) {
|
||||
printerName = printerName.file;
|
||||
} else if (printerName.host !== undefined) {
|
||||
printerName = `${printerName.host}:${printerName.port}`;
|
||||
}
|
||||
}
|
||||
printerName = printerName ?? 'None';
|
||||
this.params.push(`Printer=${printerName}`);
|
||||
this.doPrint(this.printer, this.url, this.params);
|
||||
}
|
||||
|
||||
doPrint(printerName, url, params) {
|
||||
const qzcfg = qz.configs.create(printerName);
|
||||
new Request({
|
||||
url,
|
||||
sendParam: params,
|
||||
onSuccess: (ajson) => {
|
||||
if (typeof ajson === 'object' && ajson !== null) {
|
||||
const printPayload = ajson.type === 'escp' ? this.genEscp(ajson) : this.genEpl(ajson);
|
||||
qz.print(qzcfg, printPayload);
|
||||
} else {
|
||||
FoniaJS.showInfo('Error dalam proses Cetak.');
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
genEscp(adata) {
|
||||
const ohead = ['\x1B\x40', '\x1B\x61\x01'];
|
||||
if (adata.config?.logo) {
|
||||
ohead.push({
|
||||
type: 'raw',
|
||||
format: 'image',
|
||||
flavor: 'base64',
|
||||
data: adata.config.logo,
|
||||
options: { language: 'ESCPOS', dotDensity: 'double' }
|
||||
});
|
||||
ohead.push('\x1B\x32');
|
||||
}
|
||||
if (parseInt(adata.config?.fontsize, 10) === 2) {
|
||||
this.chr_norm = '\x1B\x21\x02';
|
||||
}
|
||||
if (Array.isArray(adata.header)) {
|
||||
adata.header.forEach((headerLine, index) => {
|
||||
if (index === 0 && !adata.config?.logo) ohead.push(this.chr_bold);
|
||||
ohead.push(`${headerLine}\x0A`);
|
||||
if (index === 0 && !adata.config?.logo) ohead.push(this.chr_norm);
|
||||
});
|
||||
}
|
||||
|
||||
let ocetak = [];
|
||||
if (Array.isArray(adata.content)) {
|
||||
adata.content.forEach((sheetContent) => {
|
||||
if (!sheetContent?.length) return;
|
||||
const osheet = [...ohead];
|
||||
sheetContent.forEach((line) => {
|
||||
const formattedLine = line
|
||||
.replace('_SBOLD_', this.chr_sbold)
|
||||
.replace('_BOLD_', this.chr_bold)
|
||||
.replace('_NORM_', this.chr_norm)
|
||||
.replace('_ULINE_', this.chr_uline);
|
||||
osheet.push(`${formattedLine}\x0A`);
|
||||
});
|
||||
if (adata.config?.cutpaper) {
|
||||
osheet.push(`${this.cut_paper}\x0A`);
|
||||
}
|
||||
ocetak = ocetak.concat(osheet);
|
||||
});
|
||||
}
|
||||
|
||||
let notaout = [];
|
||||
if (adata.config?.opendraw) {
|
||||
notaout.push(this.open_draw);
|
||||
}
|
||||
const times = adata.config?.times || 1;
|
||||
for (let i = 0; i < times; i++) {
|
||||
notaout = notaout.concat(ocetak);
|
||||
}
|
||||
return notaout;
|
||||
}
|
||||
|
||||
genEpl(adata) {
|
||||
const cetak = (adata.content || []).map((line) => `${line}\r\n`);
|
||||
let notaout = [];
|
||||
const times = adata.config?.times || 1;
|
||||
|
||||
for (let i = 0; i < times; i++) {
|
||||
notaout = notaout.concat(cetak);
|
||||
}
|
||||
return notaout;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user