let $preview_indonesia = null; let $preview_english = null; let $preview_chinese = null; let $preview_japanese = null; let $preview_arabic = null; let $preview_local = null; let $enable_indonesia = null; let $enable_english = null; let $enable_chinese = null; let $enable_japanese = null; let $enable_arabic = null; let $enable_local = null; let $tbody_message = null; let $tbody_broadcastzones = null; let $select_airline = null; let $select_city = null; let $select_places = null; let $select_shalat = null; let $select_reason = null; let $select_conveyorbelt = null; let $select_procedure = null; let $select_compensation = null; let $input_gatenumber = null; let $input_flightnumber = null; let $input_licenseplate = null; let $input_conveyorbelt = null; let $input_etad = null; let $row_airplane = null; let $row_city = null; let $row_gatenumber = null; let $row_time = null; let $col_reason = null; let $col_places = null; let $col_shalat = null; let $col_conveyorbelt = null; let $col_procedure = null; let $col_licenseplate = null; /** * @type {message[]} */ let selected_messages = []; /** * @typedef {Object} message * @property {number} id - The ID of the message * @property {string} description - The description of the message * @property {string} language - The language of the message * @property {string} message_details - The detailed message content */ /** * @typedef {Object} variabledata * @property {string} tag - The tag of the variable * @property {string} value - The value of the variable */ /** * Fetch API helper function * @param {string} endpoint Endpoint URL * @param {string} method Method (GET, POST, etc.) * @param {Object} headers Headers to include in the request * @param {Object} body Body of the request * @param {Function} cbOK Callback function for successful response * @param {Function} cbError Callback function for error response */ function fetchAPI(endpoint, method, headers = {}, body = null, cbOK, cbError) { let url = window.location.origin + "/api/" + endpoint; let options = { method: method, headers: headers } if (body !== null) { options.body = JSON.stringify(body); if (!options.headers['Content-Type']) { options.headers['Content-Type'] = 'application/json'; } } fetch(url, options) .then(async (response) => { if (!response.ok) { let msg; try { let _xxx = await response.json(); msg = _xxx.message || response.statusText; } catch { msg = await response.statusText; } throw new Error(msg); } return response.json(); }) .then(data => { cbOK(data); }) .catch(error => { cbError(error); }); } window.semiautodata = { /** @type {message[]} */ messages: null, /** @type {variabledata[]} */ airlines: null, /** @type {variabledata[]} */ cities: null, /** @type {variabledata[]} */ places: null, /** @type {variabledata[]} */ shalat: null, /** @type {variabledata[]} */ sequences: null, /** @type {variabledata[]} */ reasons: null, /** @type {variabledata[]} */ procedures: null, /** @type {variabledata[]} */ gates: null, /** @type {variabledata[]} */ compensation: null, /** @type {variabledata[]} */ greetings: null, /** @type {string[]} */ broadcastzones: null, Clear: () => { window.semiautodata.messages = []; window.semiautodata.airlines = []; window.semiautodata.cities = []; window.semiautodata.places = []; window.semiautodata.shalat = []; window.semiautodata.sequences = []; window.semiautodata.reasons = []; window.semiautodata.procedures = []; window.semiautodata.gates = []; window.semiautodata.compensation = []; window.semiautodata.greetings = []; window.semiautodata.broadcastzones = []; }, Add_Message: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Message: input must be a non-empty string"); return false; } const parts = str.split(';'); if (!Array.isArray(parts) || parts.length !== 4) { console.warn("Add_Message: input must contain exactly 4 semicolon-separated parts"); return false; } const [idPart, description, language, message_details] = parts.map(p => p.trim()); const id = Number(idPart); if (!Number.isInteger(id)) { console.warn("Add_Message: first part must be an integer id"); return false; } const duplicate = window.semiautodata.messages.some(m => { if (!m) return false; const mid = Number(m.id); const mlang = (m.language || "").trim(); return Number.isInteger(mid) && mid === id && mlang === language; }); if (duplicate) { console.warn(`Add_Message: message with id ${id} and language "${language}" already exists`); return false; } window.semiautodata.messages.push({ id: id, description: description, language: language, message_details: message_details }); return true; }, Add_Airline: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Airline: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Airline: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Airline: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.airlines.some(a => (a && (a.tag || "").trim() === tag && (a.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Airline: airline "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.airlines.push({ tag, value }); return true; }, Add_City: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_City: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_City: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_City: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.cities.some(c => (c && (c.tag || "").trim() === tag && (c.value || "").trim() === value)); if (duplicate) { console.warn(`Add_City: city "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.cities.push({ tag, value }); return true; }, Add_Place: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Place: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Place: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Place: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.places.some(p => (p && (p.tag || "").trim() === tag && (p.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Place: place "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.places.push({ tag, value }); return true; }, Add_Shalat: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Shalat: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Shalat: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Shalat: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.shalat.some(s => (s && (s.tag || "").trim() === tag && (s.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Shalat: shalat "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.shalat.push({ tag, value }); return true; }, Add_Reason: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Reason: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Reason: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Reason: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.reasons.some(r => (r && (r.tag || "").trim() === tag && (r.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Reason: reason "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.reasons.push({ tag, value }); return true; }, Add_Procedure: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Procedure: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Procedure: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Procedure: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.procedures.some(p => (p && (p.tag || "").trim() === tag && (p.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Procedure: procedure "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.procedures.push({ tag, value }); return true; }, Add_Compensation: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Compensation: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Compensation: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Compensation: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.compensation.some(c => (c && (c.tag || "").trim() === tag && (c.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Compensation: compensation "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.compensation.push({ tag, value }); return true; }, Add_Greeting: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_Greeting: input must be a non-empty string"); return false; } const parts = str.split(';').map(p => p.trim()); if (!Array.isArray(parts) || parts.length !== 2) { console.warn("Add_Greeting: input must contain exactly 2 semicolon-separated parts"); return false; } const [tag, value] = parts; if (!tag || !value) { console.warn("Add_Greeting: both tag and value must be non-empty"); return false; } const duplicate = window.semiautodata.greetings.some(g => (g && (g.tag || "").trim() === tag && (g.value || "").trim() === value)); if (duplicate) { console.warn(`Add_Greeting: greeting "${tag}" with value "${value}" already exists`); return false; } window.semiautodata.greetings.push({ tag, value }); return true; }, Add_BroadcastZone: (str) => { if (str == null || typeof str !== 'string' || str.trim().length === 0) { console.warn("Add_BroadcastZone: input must be a non-empty string"); return false; } const value = str.trim(); if (value.length === 0) { console.warn("Add_BroadcastZone: value must be non-empty"); return false; } const duplicate = window.semiautodata.broadcastzones.some(b => (b || "").trim() === value); if (duplicate) { console.warn(`Add_BroadcastZone: broadcast zone "${value}" already exists`); return false; } window.semiautodata.broadcastzones.push(value); return true; } } /** * Reload the database by fetching data from the Initialize endpoint */ function reload_database() { fetchAPI("Initialize", "GET", {}, null, (data) => { //TODO data masih dalam bentuk array of string, mesti diubah ke array of object window.semiautodata.Clear(); if (data.messages && Array.isArray(data.messages)) { for (let msg of data.messages) window.semiautodata.Add_Message(msg); } if (data.airlines && Array.isArray(data.airlines)) { for (let airline of data.airlines) window.semiautodata.Add_Airline(airline); } if (data.cities && Array.isArray(data.cities)) { for (let city of data.cities) window.semiautodata.Add_City(city); } if (data.places && Array.isArray(data.places)) { for (let place of data.places) window.semiautodata.Add_Place(place); } if (data.shalat && Array.isArray(data.shalat)) { for (let shalat of data.shalat) window.semiautodata.Add_Shalat(shalat); } if (data.reasons && Array.isArray(data.reasons)) { for (let reason of data.reasons) window.semiautodata.Add_Reason(reason); } if (data.procedures && Array.isArray(data.procedures)) { for (let procedure of data.procedures) window.semiautodata.Add_Procedure(procedure); } if (data.compensation && Array.isArray(data.compensation)) { for (let compensation of data.compensation) window.semiautodata.Add_Compensation(compensation); } if (data.greetings && Array.isArray(data.greetings)) { for (let greeting of data.greetings) window.semiautodata.Add_Greeting(greeting); } if (data.broadcastzones && Array.isArray(data.broadcastzones)) { for (let broadcastzone of data.broadcastzones) window.semiautodata.Add_BroadcastZone(broadcastzone); } fill_items(); }, (error) => { console.error("Error:", error); }); } function empty_preview() { $preview_arabic.empty(); $preview_chinese.empty(); $preview_english.empty(); $preview_indonesia.empty(); $preview_japanese.empty(); $preview_local.empty(); $enable_arabic.prop("checked", false); $enable_chinese.prop("checked", false); $enable_english.prop("checked", false); $enable_indonesia.prop("checked", false); $enable_japanese.prop("checked", false); $enable_local.prop("checked", false); } function enable_disable_fields() { $row_airplane.hide(); $row_city.hide(); $row_gatenumber.hide(); $row_time.hide(); $col_reason.hide(); $col_places.hide(); $col_shalat.hide(); $col_conveyorbelt.hide(); $col_procedure.hide(); $col_licenseplate.hide(); // show airplane row if English preview contains the placeholder const text = $preview_english.text() || ""; if (text.indexOf('[CITY]') !== -1) $row_city.show(); if (text.indexOf('[AIRPLANE_NAME]') !== -1) $row_airplane.show(); if (text.indexOf('[FLIGHT_NUMBER]') !== -1) $row_airplane.show(); if (text.indexOf('[GATENUMBER]') !== -1) $row_gatenumber.show(); if (text.indexOf('[ETAD]') !== -1) $row_time.show(); if (text.indexOf('[REASON]') !== -1) $col_reason.show(); if (text.indexOf('[PLACES]') !== -1) $col_places.show(); if (text.indexOf('[SHALAT]') !== -1) $col_shalat.show(); if (text.indexOf('[BCB]') !== -1) $col_conveyorbelt.show(); if (text.indexOf('[PROCEDURE]') !== -1) $col_procedure.show(); if (text.indexOf('[PLATNOMOR]') !== -1) $col_licenseplate.show(); } function ValidString(str) { return (str != null && typeof str === 'string' && str.trim().length > 0); } function update_preview(language) { let text = ""; let $preview = null; if (language === "indonesia") { $preview = $preview_indonesia; text = selected_messages.find(m => (m.language || "").toLowerCase() === "indonesia")?.message_details || ""; } else if (language === "english") { $preview = $preview_english; text = selected_messages.find(m => (m.language || "").toLowerCase() === "english")?.message_details || ""; } else if (language === "chinese") { $preview = $preview_chinese; text = selected_messages.find(m => (m.language || "").toLowerCase() === "chinese")?.message_details || ""; } else if (language === "japanese") { $preview = $preview_japanese; text = selected_messages.find(m => (m.language || "").toLowerCase() === "japanese")?.message_details || ""; } else if (language === "arabic") { $preview = $preview_arabic; text = selected_messages.find(m => (m.language || "").toLowerCase() === "arabic")?.message_details || ""; } else if (language === "local") { $preview = $preview_local; text = selected_messages.find(m => (m.language || "").toLowerCase() === "local")?.message_details || ""; } if (text.indexOf('[CITY]') !== -1) { let cities = $select_city.val(); if (Array.isArray(cities) && cities.length > 0) { let citiesNames = []; for (let cityTag of cities) { let ct = window.semiautodata.cities.find(c => c.tag === cityTag); if (ct) { citiesNames.push(ct.value); } } if (citiesNames.length > 0) { text = text.replace(/\[CITY\]/g, citiesNames.join(", ")); } } } if (text.indexOf('[AIRPLANE_NAME]') !== -1) { let airlineTag = $select_airline.val(); if (ValidString(airlineTag)) { let airlineObj = window.semiautodata.airlines.find(a => a.tag === airlineTag); let airlineName = airlineObj ? airlineObj.value : ""; if (airlineName.length > 0) { text = text.replace(/\[AIRPLANE_NAME\]/g, airlineName); } } } if (text.indexOf('[FLIGHT_NUMBER]') !== -1) { let airlineTag = $select_airline.val(); let flightNumber = $input_flightnumber.val(); if (ValidString(airlineTag) && ValidString(flightNumber)) { text = text.replace(/\[FLIGHT_NUMBER\]/g, `${airlineTag} ${flightNumber}`); } } if (text.indexOf('[GATENUMBER]') !== -1) { let gateNumber = $input_gatenumber.val(); if (ValidString(gateNumber)) { text = text.replace(/\[GATENUMBER\]/g, gateNumber); } } if (text.indexOf('[ETAD]') !== -1) { let etad = $input_etad.val(); if (ValidString(etad)) { text = text.replace(/\[ETAD\]/g, etad); } } if (text.indexOf('[REASON]') !== -1) { let reason = $select_reason.val(); if (ValidString(reason)) { let reasonobj = window.semiautodata.reasons.find(r => r.tag === reason); let reasontext = reasonobj ? reasonobj.value : ""; if (ValidString(reasontext)) { text = text.replace(/\[REASON\]/g, reasontext); } } } if (text.indexOf('[PLACES]') !== -1) { let placeTag = $select_places.val(); if (ValidString(placeTag)) { let placeobj = window.semiautodata.places.find(p => p.tag === placeTag); let placetext = placeobj ? placeobj.value : ""; if (ValidString(placetext)) { text = text.replace(/\[PLACES\]/g, placetext); } } } if (text.indexOf('[SHALAT]') !== -1) { let shalatTag = $select_shalat.val(); if (ValidString(shalatTag)) { let shalatobj = window.semiautodata.shalat.find(s => s.tag === shalatTag); let shalattext = shalatobj ? shalatobj.value : ""; if (ValidString(shalattext)) { text = text.replace(/\[SHALAT\]/g, shalattext); } } } if (text.indexOf('[BCB]') !== -1) { let bcbTag = $select_bcb.val(); if (ValidString(bcbTag)) { text = text.replace(/\[BCB\]/g, bcbTag); } } if (text.indexOf('[PROCEDURE]') !== -1) { let procedureTag = $select_procedure.val(); if (ValidString(procedureTag)) { let procedureobj = window.semiautodata.procedures.find(p => p.tag === procedureTag); let proceduretext = procedureobj ? procedureobj.value : ""; if (ValidString(proceduretext)) { text = text.replace(/\[PROCEDURE\]/g, proceduretext); } } } if (text.indexOf('[PLATNOMOR]') !== -1) { let platNomorTag = $select_licenseplate.val(); if (ValidString(platNomorTag)) { text = text.replace(/\[PLATNOMOR\]/g, platNomorTag); } } if (text.indexOf('[SEQUENCE]') !== -1) { let sequenceTag = $select_sequence.val(); if (ValidString(sequenceTag)) { let sequenceobj = window.semiautodata.sequences.find(s => s.tag === sequenceTag); let sequencetext = sequenceobj ? sequenceobj.value : ""; if (ValidString(sequencetext)) { text = text.replace(/\[SEQUENCE\]/g, sequencetext); } } } if ($preview) { $preview.text(text); } } function isComplete(chkbox, preview) { if (chkbox.is(":checked")) { const text = preview.text(); if (text.indexOf('[') !== -1) { return false; } if (text.indexOf(']') !== -1) { return false; } } return true; } function check_complete_message() { let complete = true; if (!isComplete($enable_indonesia, $preview_indonesia)) complete = false; if (!isComplete($enable_english, $preview_english)) complete = false; if (!isComplete($enable_chinese, $preview_chinese)) complete = false; if (!isComplete($enable_japanese, $preview_japanese)) complete = false; if (!isComplete($enable_arabic, $preview_arabic)) complete = false; if (!isComplete($enable_local, $preview_local)) complete = false; if (complete) { $("#send_broadcast").removeClass("btn-disable").addClass("btn-enable"); } else { $("#send_broadcast").removeClass("btn-enable").addClass("btn-disable"); } } function update_all_previews() { update_preview("indonesia"); update_preview("english"); update_preview("chinese"); update_preview("japanese"); update_preview("arabic"); update_preview("local"); check_complete_message(); } function fill_items() { $tbody_message.empty(); $tbody_broadcastzones.empty(); $select_airline.select2(); $select_city.select2(); $select_places.empty(); $select_shalat.empty(); $select_reason.empty(); $select_procedure.empty(); $select_compensation.empty(); $input_gatenumber.empty(); $input_flightnumber.empty(); $input_licenseplate.empty(); $input_conveyorbelt.empty(); $input_etad.empty(); empty_preview(); if (window.semiautodata !== null) { if (window.semiautodata.messages !== null && Array.isArray(window.semiautodata.messages) && window.semiautodata.messages.length > 0) { for (let msg of window.semiautodata.messages) { const txt = msg.description + " [" + msg.id + "]"; // check if tbody_message already has a row with the same text let exists = false; $("#tbody_message tr td").each(function () { if ($(this).text() === txt) { exists = true; } }); if (!exists) { let $tr = $(""); let $td = $("").text(txt); $tr.append($td); $tbody_message.append($tr); $tr.css("cursor", "pointer"); $tr.data("msgid", msg.id); $tr.on("click", function (e) { const $row = $(this); const groupId = $row.data("msgid"); const willSelect = !$row.hasClass("table-active"); // helper to map language string to preview & checkbox function applyLang(lang, value, checked) { const l = (lang || "").toString().trim().toLowerCase(); if (l.startsWith("indonesia")) { if (checked) $preview_indonesia.text(value); else $preview_indonesia.empty(); $enable_indonesia.prop("checked", !!checked); return true; } if (l.startsWith("english")) { if (checked) $preview_english.text(value); else $preview_english.empty(); $enable_english.prop("checked", !!checked); return true; } if (l.startsWith("chinese")) { if (checked) $preview_chinese.text(value); else $preview_chinese.empty(); $enable_chinese.prop("checked", !!checked); return true; } if (l.startsWith("japanese")) { if (checked) $preview_japanese.text(value); else $preview_japanese.empty(); $enable_japanese.prop("checked", !!checked); return true; } if (l.startsWith("arabic")) { if (checked) $preview_arabic.text(value); else $preview_arabic.empty(); $enable_arabic.prop("checked", !!checked); return true; } if (l.startsWith("local")) { if (checked) $preview_local.text(value); else $preview_local.empty(); $enable_local.prop("checked", !!checked); return true; } return false; } // helper to clear previews for a given group id function clearGroupPreviews(gid) { if (!window.semiautodata || !Array.isArray(window.semiautodata.messages)) return; const sameMsgs = window.semiautodata.messages.filter(m => Number(m.id) === Number(gid)); for (let m of sameMsgs) { applyLang(m.language, "", false); } } selected_messages = []; if (willSelect) { // unselect other selected rows and clear their previews $tbody_message.find("tr.table-active").each(function () { if (this === e.currentTarget) return; const $other = $(this); const otherId = $other.data("msgid"); $other.removeClass("table-active"); clearGroupPreviews(otherId); }); // select this row and apply its messages to previews $row.addClass("table-active"); if (window.semiautodata && Array.isArray(window.semiautodata.messages)) { const sameMsgs = window.semiautodata.messages.filter(m => Number(m.id) === Number(groupId)); for (let m of sameMsgs) { applyLang(m.language, m.message_details, true); selected_messages.push(m); } enable_disable_fields(); update_all_previews(); } } else { // deselect this row and clear its previews $row.removeClass("table-active"); clearGroupPreviews(groupId); } }); } } } if (window.semiautodata.broadcastzones !== null && Array.isArray(window.semiautodata.broadcastzones) && window.semiautodata.broadcastzones.length > 0) { for (let zone of window.semiautodata.broadcastzones) { { const uid = 'bz_' + Math.random().toString(36).slice(2, 9); let $tr = $(""); let $checkbox = $("").attr({ type: "checkbox", id: uid, value: zone }); let $label = $("").attr("for", uid).text(zone); let $td = $("").append($checkbox).append(" ").append($label); $tr.append($td); $tbody_broadcastzones.append($tr); } } } if (window.semiautodata.airlines !== null && Array.isArray(window.semiautodata.airlines) && window.semiautodata.airlines.length > 0) { const airlinedata = window.semiautodata.airlines.map(a => ({ id: a.tag, text: a.value + " [" + a.tag + "]" })); $select_airline.select2({ data: airlinedata, placeholder: "Select an airline", width: '100%', multiple: false }); $select_airline.val(null).trigger("change"); $select_airline.on('change', function () { update_all_previews(); }); } if (window.semiautodata.cities !== null && Array.isArray(window.semiautodata.cities) && window.semiautodata.cities.length > 0) { const citydata = window.semiautodata.cities.map(c => ({ id: c.tag, text: c.value + " [" + c.tag + "]" })); $select_city.select2({ data: citydata, placeholder: "Select a city", width: '100%', multiple: true }); // disable sorting on select2 selection $select_city.on('select2:select', function (e) { let element = e.params.data.element; $(this).append(element); // move selected item to the end $(this).trigger('change'); // refresh select2 display }); $select_city.val(null).trigger("change"); $select_city.on('change', function () { update_all_previews(); }); } if (window.semiautodata.places !== null && Array.isArray(window.semiautodata.places) && window.semiautodata.places.length > 0) { $select_places.select2({ placeholder: "Select a place", width: '100%', multiple: false, data: window.semiautodata.places.map(p => ({ id: p.tag, text: p.value + " [" + p.tag + "]" })) }); $select_places.val(null).trigger("change"); $select_places.on('change', function () { update_all_previews(); }); } if (window.semiautodata.shalat !== null && Array.isArray(window.semiautodata.shalat) && window.semiautodata.shalat.length > 0) { $select_shalat.select2({ placeholder: "Select shalat time", width: '100%', multiple: false, data: window.semiautodata.shalat.map(s => ({ id: s.tag, text: s.value + " [" + s.tag + "]" })) }); $select_shalat.val(null).trigger("change"); } if (window.semiautodata.reasons !== null && Array.isArray(window.semiautodata.reasons) && window.semiautodata.reasons.length > 0) { $select_reason.select2({ placeholder: "Select a reason", width: '100%', multiple: false, data: window.semiautodata.reasons.map(r => ({ id: r.tag, text: r.value + " [" + r.tag + "]" })) }); $select_reason.val(null).trigger("change"); $select_reason.on('change', function () { update_all_previews(); }); } if (window.semiautodata.compensation !== null && Array.isArray(window.semiautodata.compensation) && window.semiautodata.compensation.length > 0) { $select_compensation.select2({ placeholder: "Select compensation", width: '100%', multiple: false, data: window.semiautodata.compensation.map(c => ({ id: c.tag, text: c.value + " [" + c.tag + "]" })) }); $select_compensation.val(null).trigger("change"); $select_compensation.on('change', function () { update_all_previews(); }); } if (window.semiautodata.procedures !== null && Array.isArray(window.semiautodata.procedures) && window.semiautodata.procedures.length > 0) { $select_procedure.select2({ placeholder: "Select procedure", width: '100%', multiple: false, data: window.semiautodata.procedures.map(p => ({ id: p.tag, text: p.value + " [" + p.tag + "]" })) }); $select_procedure.val(null).trigger("change"); $select_procedure.on('change', function () { update_all_previews(); }); } $input_conveyorbelt.on('input', function () { update_all_previews(); }); $input_gatenumber.on('input', function () { update_all_previews(); }); $input_flightnumber.on('input', function () { update_all_previews(); }); $input_licenseplate.on('input', function () { update_all_previews(); }); $input_etad.on('input', function () { update_all_previews(); }); } } function send_broadcast_message() { console.log("send_broadcast_message"); if ($("#send_broadcast").hasClass("btn-disable")) { alert("Cannot send broadcast message. Please complete all required fields."); return; } // get all checked broadcast zones from tbody_broadcastzones let selected_zones = []; $tbody_broadcastzones.find("input[type='checkbox']").each(function () { const $checkbox = $(this); if ($checkbox.is(":checked")) { selected_zones.push($checkbox.val()); } }); if (selected_zones.length === 0) { alert("Please select at least one broadcast zone."); return; } let languages = []; if ($enable_indonesia.is(":checked")) languages.push("INDONESIA"); if ($enable_english.is(":checked")) languages.push("ENGLISH"); if ($enable_chinese.is(":checked")) languages.push("CHINESE"); if ($enable_japanese.is(":checked")) languages.push("JAPANESE"); if ($enable_arabic.is(":checked")) languages.push("ARABIC"); if ($enable_local.is(":checked")) languages.push("LOCAL"); if (languages.length === 0) { alert("Please select at least one language to send."); return; } let description = selected_messages.length > 0 ? selected_messages[0].description : ""; if (!ValidString(description)) { alert("Message not selected"); return; } let tags = []; let msg = selected_messages[0]; tags.push("ANN_ID:"+msg.id); if (msg.message_details.indexOf('[CITY]') !== -1) { let cities = $select_city.val(); if (Array.isArray(cities) && cities.length > 0) { tags.push("CITY:" + cities.join(";")); } } if (msg.message_details.indexOf('[AIRPLANE_NAME]') !== -1) { tags.push("AL:" + $select_airline.val()); } if (msg.message_details.indexOf('[FLIGHT_NUMBER]') !== -1) { tags.push("FLNUM:" + $input_flightnumber.val()); } if (msg.message_details.indexOf('[PLATNOMOR]') !== -1) { tags.push("PLATNOMOR:" + $input_licenseplate.val()); } if (msg.message_details.indexOf('[PLACES]') !== -1) { tags.push("PLACES:" + $select_places.val()); } if (msg.message_details.indexOf('[ETAD]') !== -1) { tags.push("ETAD:" + $input_etad.val()); } if (msg.message_details.indexOf('[SHALAT]') !== -1) { tags.push("SHALAT:" + $select_shalat.val()); } if (msg.message_details.indexOf('[BCB]') !== -1) { tags.push("BCB:" + $input_conveyorbelt.val()); } if (msg.message_details.indexOf('[GATENUMBER]') !== -1) { tags.push("GATECODE:" + $input_gatenumber.val()); } if (msg.message_details.indexOf('[REASON]') !== -1) { tags.push("REASON:" + $select_reason.val()); } if (msg.message_details.indexOf('[PROCEDURE]') !== -1) { tags.push("PROCEDURE:" + $select_procedure.val()); } let payload = { description: description, languages: languages.join(";"), tags: tags.join(" "), broadcastzones: selected_zones.join(";") } console.log("Payload:", payload); fetchAPI("SemiAuto", "POST", {}, payload, (data) => { alert("Broadcast message sent successfully."); }, (error) => { console.error("Error:", error); alert("Error sending broadcast message: " + error); }); } // App start here $(document).ready(function () { console.log("javascript loaded"); $preview_indonesia = $("#message_indonesia"); $preview_english = $("#message_english"); $preview_chinese = $("#message_chinese"); $preview_japanese = $("#message_japanese"); $preview_arabic = $("#message_arabic"); $preview_local = $("#message_local"); $enable_indonesia = $("#checkbox_indonesia"); $enable_english = $("#checkbox_english"); $enable_chinese = $("#checkbox_chinese"); $enable_japanese = $("#checkbox_japanese"); $enable_arabic = $("#checkbox_arabic"); $enable_local = $("#checkbox_local"); $tbody_message = $("#tbody_message"); $tbody_broadcastzones = $("#tbody_broadcastzones"); $select_airline = $("#select_airline"); $select_city = $("#select_city"); $select_places = $("#select_places"); $select_shalat = $("#select_shalat"); $select_reason = $("#select_reason"); $select_procedure = $("#select_procedure"); $select_compensation = $("#select_compensation"); $input_gatenumber = $("#input_gatenumber"); $input_flightnumber = $("#input_flightnumber"); $input_licenseplate = $("#input_licenseplate"); $input_conveyorbelt = $("#input_conveyorbelt"); $input_etad = $("#input_etad"); $row_airplane = $("#row_airplane"); $row_city = $("#row_city"); $row_gatenumber = $("#row_gatenumber"); $row_time = $("#row_time"); $col_reason = $("#col_reason"); $col_places = $("#col_places"); $col_shalat = $("#col_shalat"); $col_conveyorbelt = $("#col_conveyorbelt"); $col_procedure = $("#col_procedure"); $col_licenseplate = $("#col_licenseplate"); reload_database(); $("#reload_database").off("click").on("click", function () { reload_database(); }); $("#send_broadcast").off("click").on("click", function () { send_broadcast_message(); }); });