function hrefonclickButtonGO(pagename, pagedatastring = '') { if (!pagename) { return false; } return `href="javascript:void(0);" onclick="ButtonGo('${pagename}',${pagedatastring});return false;"`; } function generateHTMLfromarray(prepend, append, array, func) { if (!func || !array) { return false; } let htmlres = prepend; array.forEach((value) => { if (value.length > 0) { htmlres += func(...value); } }); htmlres += append; return htmlres; } function imgiconuserdefault(imgsrc, imgwidth = '', imgheight = '', id = '', onclick = '') { if (!imgsrc) { return false; } if (!imgwidth) { imgwidth = 30; } if (!imgheight) { imgheight = 30; } if (id) { id = 'id="' + id + '"'; } else { id = '' } return ``; } function UICardStatsDetails(Title = '', number = 0, Unit = '', leftORright = 'left', numberid = '') { if (!leftORright) { leftORright = 'left'; } return `

${Title}

${number}

${Unit}
`; } /** * Generates an HTML string for displaying stats details. * * @param {array} statsarray - A 2D array containing stats data, where each inner array has the format [title, number, unit, leftorright,numberid] * @returns {string} HTML string representing the stats details */ function UIStatsDetailsArray(statsarray) { return generateHTMLfromarray('
', '
', statsarray, UICardStatsDetails); } /** * Generates an HTML string for displaying stats details. * * @param {array} statsarray - A 2D array containing stats data, where each inner array has the format [title, number, unit, leftorright,numberid] * @returns {string} HTML string representing the stats details including the balance wrapper */ function UIBalance_WrapperfromArray(statsarray) { if (!statsarray) { return false; } let htmlres = `
`; htmlres += UIStatsDetailsArray(statsarray); htmlres += '
' return htmlres; } function UIBalance_Wrapper_WalletFooter_Item(maintitle = '', onclickstring = '', imgsrc = '', href = '', subtitleline1 = '', subtitleline2 = '', subtitleline3 = '', subtitleline4 = '', imgwidth = '', imgheight = '') { if (!href) { href = "javascript:void(0);"; } if (!imgwidth) { imgwidth = "30"; } if (!imgheight) { imgheight = "30"; } return `
  • ${imgiconuserdefault(imgsrc, imgwidth, imgheight)} ${maintitle}
  • `; } function UIBalance_Wrapper_WalletFooter_Item_ButtonGO(maintitle, pagename, pagestring = '', iconclass = '', subtitleline1 = '', subtitleline2 = '', subtitleline3 = '', subtitleline4 = '') { if (!pagename) { return false; } const onclickstring = `ButtonGo('${pagename}','${pagestring}');return false;`; //const iconclass =`icon far fa-hdd`; const htmlres = UIBalance_Wrapper_WalletFooter_Item(maintitle, onclickstring, iconclass, false, subtitleline1, subtitleline2, subtitleline3, subtitleline4); return htmlres; } /** * Generates an HTML string for a balance wrapper item button array. * * @param {array} balancewrapper_item_array - A 2D array containing balance wrapper item data, where each inner array has the format [maintitle, pagename, pagestring, imagesrc, subtitleline1, subtitleline2, subtitleline3, subtitleline4,imgwidth,imgheight] * @returns {string} HTML string representing the balance wrapper item button array */ function UIBalance_Wrapper_WalletFooter_ARRAY(balancewrapper_item_array) { return generateHTMLfromarray(`', balancewrapper_item_array, UIBalance_Wrapper_WalletFooter_Item_ButtonGO); } /** * Generates an HTML string for a balance wrapper item button array. * * @param {array} statsarray - A 2D array containing stats data, where each inner array has the format [title, number, unit, leftorright] * @param {array} balancewrapper_item_array - A 2D array containing balance wrapper item data, where each inner array has the format [maintitle, pagename, pagestring, iconclass, subtitleline1, subtitleline2, subtitleline3, subtitleline4] * @param {string} style - a string containing custom style for the balance box * @returns {string} HTML string for the whole balance box */ function UIcreateBalanceBoxfromArray(statsarray, balancewrapper_item_array, style = 'border: solid 3px #000d88;') { let htmlres = `
    `; htmlres += UIBalance_WrapperfromArray(statsarray); htmlres += UIBalance_Wrapper_WalletFooter_ARRAY(balancewrapper_item_array); return htmlres; } function UIServices_Button(imgiconsrc, title = '', onclick = '', href = '', bgcolor8 = false) { if (!bgcolor8) { bgcolor8 = '' } else { bgcolor8 = 'bg_color_8'; } return `
  • ${title}
  • `; } function UIServices_Button_GOTOPAGE(imgiconsrc, title, pagename, pagedatastring = '') { return UIServices_Button(imgiconsrc, title, `ButtonGo('${pagename}','${pagedatastring}');return false;`, ''); } function UIServices_FullDIV_GOTOPAGE_Array(title, viewallhref = '', viewallonclick = '', viewalltext = '', services_button_array) { return generateHTMLfromarray(`

    ${title}

    ${viewalltext}
      `, '
    ', services_button_array, UIServices_Button_GOTOPAGE); } function UIServices_FullDIV_ONCLICK_Array(title, viewallhref = '', viewallonclick = '', viewalltext = '', services_button_array) { return generateHTMLfromarray(`

    ${title}

    ${viewalltext}
      `, '
    ', services_button_array, UIServices_Button); } function UISideText_DualColumnButton(text, pagename, pagedatastring = '', imgsrc = '', imgwidth = '', imgheight = '') { if (!pagename || !text) { return false; } if (!imgwidth) { imgwidth = 30; } if (!imgheight) { imgheight = 30; } return `
  • ${imgiconuserdefault(imgsrc, imgwidth, imgheight)}
    ${text}
  • `; } function UISideText_DualColumnButton_Array(sidetext_button_dualcolumn_array) { return generateHTMLfromarray('', sidetext_button_dualcolumn_array, UISideText_DualColumnButton); } function UICardSimple(title, text = '', id = '') { return CreateCardSimple(title, text, id); } function UIRecentSearchBar(searchplaceholdertext, classtosearch, id, imgsrclefticon = '', imgsrcrighticon = '', imgwidth = '', imgheight = '') { if (!imgwidth) { imgwidth = 30; } if (!imgheight) { imgheight = 30; } if (!classtosearch) { classtosearch = ''; } if (!imgsrclefticon) { imgsrclefticon = ''; } else { imgsrclefticon = imgiconuserdefault(imgsrclefticon, imgwidth, imgheight); } if (!searchplaceholdertext) { searchplaceholdertext = 'Search'; } let righticonhtml = ''; if (imgsrcrighticon) { righticonhtml = imgiconuserdefault(imgsrcrighticon, imgwidth, imgheight, id + '-leftsearchicon'); } else { righticonhtml = ''; } return ` `; } function UIRecentSearchable_Button_GO(title, subtitle, rightsidetext, classforsearch, pagename, pagedatastring = '', imgsrc, imgwidth = '', imgheight = '') { if (!pagename) { return false; } if (!imgwidth) { imgwidth = 30; } if (!imgheight) { imgheight = 30; } if (!classforsearch) { classforsearch = ''; } return `
  • `; } function UIRecentSearchable_Button_GO_ARRAY(title, recentssearchablebuttonarray, viewallpagetarget, viewallpagedata = '', viewalltext = '') { return generateHTMLfromarray(`

    ${title}${viewalltext}

    ', recentssearchablebuttonarray, UIRecentSearchable_Button_GO); } function UIListArrowButton_GO(title, subtitle, pagename, pagedatastring = '', imgsrc, imgwidth = '', imgheight = '') { if (!pagename) { return false; } if (!imgwidth) { imgwidth = 30; } if (!imgheight) { imgheight = 30; } return `
    ${imgiconuserdefault(imgsrc, imgwidth, imgheight)}

    ${title}

    ${subtitle}

    `; } function UIListArrowButton_GO_ARRAY(UIListArrowButtonGOARRAY) { return generateHTMLfromarray('', '', UIListArrowButtonGOARRAY, UIListArrowButton_GO); } function UISearchBox_with_BUTTONS_FULL(title, recentssearchablebuttonarray, UIListArrowButtonGOARRAY = '', viewallpagetarget, viewallpagedata = '', viewalltext = '', classtosearch = '', searchid = '', searchplaceholdertext = '', searchlefticon = '', searchrighticon = '', imgwidth = '', imgheight = '') { let htmlres = ''; if (classtosearch && searchid) { htmlres += UIRecentSearchBar(searchplaceholdertext, classtosearch, searchid, searchlefticon, searchrighticon, imgwidth, imgheight); } htmlres += UIRecentSearchable_Button_GO_ARRAY(title, recentssearchablebuttonarray, viewallpagetarget, viewallpagedata, viewalltext); if (UIListArrowButtonGOARRAY) { htmlres += UIListArrowButton_GO_ARRAY(UIListArrowButtonGOARRAY); } return htmlres; } function UIinputgroupcore(innerhtml = '', label = '', inputgroupid = '') { let htmllabel; if (!label && !inputgroupid) { htmllabel = ''; } else { htmllabel = ``; } return `${htmllabel}
    ${innerhtml}
    `; } //Input group function UIInputGroup(placeholder, type, id, label = '', classinput = '', spanclass = '', imginsteadofspan = '', required = false, textvalue = '', datalist = '', imgwidth = '', imgheight = '', disabled = false) { if (!required) { required = ''; } else { required = 'required'; } if (!type) { return false; } let span; let html; let inner; let labelid; if (!type) { type = 'text'; } if (!classinput) { classinput = 'form-control'; } if (datalist) { datalist = ' list="' + datalist + '" '; } else { datalist = ''; } span = ``; if (!imgwidth) { imgwidth = '40px'; } if (!imgheight) { imgheight = '40px'; } if (imginsteadofspan) { span = imgiconuserdefault(imginsteadofspan, imgwidth, imgheight, 'imgspan' + id); } if (!imginsteadofspan && !spanclass) { span = ''; } else { /* span =`
    ${span}
    `; */ } if (disabled) { disabled = ' disabled '; } if (label) { } inner = `${span}`; labelid = id + '-div-mb3'; html = UIinputgroupcore(inner, label, labelid); return html; } function UIInputGroupFileUploadDropzone(id, label = '', url = '', inputgroupid = '', width = '100%', disabled = '') { if (!url) { url = '/File/Upload/Unknown'; } clearbuttonid = 'ClearUploadButton-' + id; if (width) { width = ' style="width: ' + width + ';" '; } else { width = ''; } if (disabled) { disabled = 'style=" pointer-events: none;"'; } const clearuploadsbutton = ' ' + imgiconuserdefault('https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/b6dc254166b4.bin', '', '', clearbuttonid, `LoadDataPageFunc.ClearUpload['${id}']();`); return UIinputgroupcore('
    ', label + clearuploadsbutton, inputgroupid); } function DropZoneLOADDATAPAGEFUNC(url, dropzoneid, acceptedfiles = '', maxsizeMB = 100) { if (!url) { url = '/File/Upload/Unknown'; } const clearbuttonid = 'ClearUploadButton-' + dropzoneid; $('#' + clearbuttonid).hide(); window.Target_Uploaded_Files = []; if (!acceptedfiles) { acceptedfiles = DropZoneFunc.AcceptedFilesString.images; } if (typeof window.currentDropzone === 'undefined') { window.currentDropzone = {}; } // Initialize Dropzone const dzInstance = DropZoneFunc.InitializeDropZone( url, (response) => { if (response.success && response.hashkey) { if (!Target_Uploaded_Files.includes(response.hashkey)) { Target_Uploaded_Files.push(response.hashkey); } } else { dzInstance.removeFile(dzInstance.files[dzInstance.files.length - 1]); } if (Target_Uploaded_Files.length > 0) { $('#' + clearbuttonid).show(); } else { $('#' + clearbuttonid).hide(); } }, dropzoneid, acceptedfiles, 'file', maxsizeMB, false, (errorresponse) => { // handle error if needed } ); // Store globally window.currentDropzone[dropzoneid] = dzInstance; //dzInstance.dropzoneobject = dzInstance; dzInstance.functions = {}; dzInstance.functions.AddPreviouslyUploadedFiles = function (filesarray) { return DropZoneFunc.AddPreviouslyUploadedFiles(dzInstance, filesarray); }; dzInstance.functions.ReplaceDropzoneFiles = function (newFilesArray) { return DropZoneFunc.ReplaceDropzoneFiles(dropzoneid, newFilesArray); }; dzInstance.functions.ResetDropzoneUpload = function (url, obj = null, reqtype = 'POST', successfunc = false) { return DropZoneFunc.ResetDropzoneUpload(url, obj, reqtype, successfunc); }; dzInstance.functions.ClearDropzoneUpload = function () { return DropZoneFunc.ClearDropzoneUpload(dropzoneid, dzInstance); }; dzInstance.functions.hasOngoingUploads = function () { return DropZoneFunc.hasOngoingUploads(dzInstance); }; dzInstance.functions.RemoveLastUploadedDropzone = function () { return DropZoneFunc.RemoveLastUploadedDropzone(dzInstance); }; dzInstance.functions.AddFiles = function (dropzonemodal = 'Dropzone-Modal', errorcallback) { return DropZoneFunc.AddFiles(url = '/File/Upload', errorcallback, filename = 'file', maxfilesize = 100, acceptedFiles, dropzoneid, dropzonemodal); }; if (typeof LoadDataPageFunc.ClearUpload === 'undefined') { LoadDataPageFunc.ClearUpload = {}; } LoadDataPageFunc.ClearUpload[dropzoneid] = function () { $('#' + clearbuttonid).hide(); DropZoneFunc.ClearDropzoneUpload(dropzoneid, dzInstance); }; } function InitializeLoadDataPageFuncDropZonePhotoUpload(url, dropzoneid, acceptedfiles = '', maxsizeMB = 100) { if (typeof LoadDataPageFunc === 'undefined') { return false; } // console.log('initializing photodropzone'); LoadDataPageFunc.InitializePhotoDropZone = function () { return DropZoneLOADDATAPAGEFUNC(url, dropzoneid, acceptedfiles, maxsizeMB); }; } function SendPostDataURLData(url, data, sucessfunc, errorfunc = false, fromvarcache = false) { if (!url || !data) { return false; } let SendPostDataReqq = new RequestData(false); SendPostDataReqq.url(url).type('POST').data(data) .fromVarCache(fromvarcache) .success((response) => { if (typeof sucessfunc === 'function') { sucessfunc(response); } }).error((response) => { if (typeof errorfunc === 'function') { errorfunc(response); } }).go(); } function getInputAndTextareaValuesbyCSSClassName(className) { const elements = document.getElementsByClassName(className); const results = []; elements.forEach(element => { const id = element.id; const value = element.value; results.push({ id, value }); }); return results; } function getInputElementsValuesObjectbyCSSClassname(classname) { const elements = document.getElementsByClassName(classname); const results = {}; elements.forEach(element => { const id = element.id; const value = element.value; results[id] = value; }); return results; } // Helper function to extract hashkey from response (handles both string and JSON object responses) function getHashkeyFromResponse(response) { if (!response) return null; // If response is already a string/hash key if (typeof response === 'string') { return response; } // If response is an object with hashkey property (JSON response from backend) if (response && typeof response.hashkey === 'string') { return response.hashkey; } return null; } // Helper function to extract hashkey and call callback with it function getResponseHashkeyOrErrorMessage(response, successCallback, errorCallback) { const hashkey = getHashkeyFromResponse(response); if (hashkey) { successCallback(hashkey); } else { // Check if response is an error object if (response && typeof response === 'object' && !Array.isArray(response)) { const errorMessage = response.message || response.error || 'Unknown error'; errorCallback(errorMessage); } else { errorCallback('Invalid response format'); } } } function SendPostDataFormwithTARGETUPLOADEDFILES(url, forminputclass, successfunc, WithTarget_Uploaded_Files = true, errorfunc = false) { if (!url || !forminputclass || !successfunc) { return false; } let datatosend = getInputElementsValuesObjectbyCSSClassname(forminputclass); if (isObjectEmpty(datatosend)) { return false; } if (WithTarget_Uploaded_Files && typeof window.Target_Uploaded_Files !== 'undefined' && window.Target_Uploaded_Files.length > 0) { datatosend['files'] = Target_Uploaded_Files; } let target; let data = null; if (typeof currenttarget === 'object') { try { target = currenttarget['target']; } catch (error) { target = currenttarget; } try { data = currenttarget['data']; } catch (error) { data = null; } } else { target = currenttarget; data = null; } if (typeof datatosend.target === 'undefined') { datatosend['target'] = target; datatosend['data'] = data; } // Wrap successfunc to extract hashkey from JSON responses const wrappedSuccessFunc = function(response) { const hashkey = getHashkeyFromResponse(response); if (hashkey) { successfunc(hashkey); } else { // Pass original response for error handling successfunc(response); } }; SendPostDataURLData(url, datatosend, wrappedSuccessFunc, errorfunc, fromvarcache = false); } function UIInputGroupTEXTAREA(label = '', textareaID = '', required = false, textareaCONTENT = '', textareaCLASS = '', inputgroupid = '', disabled = '') { if (required) { required = ' required '; } else { required = ''; } if (disabled) { disabled = 'disabled' } const innerhtml = ``; return UIinputgroupcore(innerhtml, label, inputgroupid); } function UIInputGroupSelect(id = '', label = '', optionsarray = '', spanclass = '', imginsteadofspan = '', selectedvalue = '', imgwidth = '', imgheight = '', select_class = '', disabled = '') { //optionsarray =[['value1','text1'],['value2','text2',selectedtrue] ] let inner; let labelid; let htmlspan; let optionshtml = ''; if (!spanclass && !imginsteadofspan) { htmlspan = ''; } if (!imgwidth) { imgwidth = '40px'; } if (!imgheight) { imgheight = '40px'; } optionshtml = UIArraytoOptionforSelect(optionsarray, selectedvalue); if (spanclass) { htmlspan = ``; } if (imginsteadofspan) { htmlspan = imgiconuserdefault(imginsteadofspan, '10px', '10px'); } if (!spanclass && !imginsteadofspan) { htmlspan = ''; } else { htmlspan = `
    ${htmlspan}
    `; } if (disabled) { disabled = 'disabled'; } else { disabled = ''; } inner = `${htmlspan}`; labelid = id + '-select-div-mb3'; html = UIinputgroupcore(inner, label, labelid); return html; } function UIInputGroupDatePicker() { } function UIArraytoOptionforSelect(array, selectedvalue = '') { if (!array) { return ''; } let optionshtml = ''; let val; let selected; for (let i = 0; i < array.length; i++) { val = array[i]; // selected = (val[2] !== undefined) ? val[2] : ''; selected = ''; if (selectedvalue !== '' && selectedvalue == val[0]) { selected = 'selected'; } optionshtml += ``; } return optionshtml; } function UIReplaceCurrentOptionsSelect(selectid, optionsarray, selectedvalue = '') { if (!selectid || !optionsarray) { return false; } let optionshtml = UIArraytoOptionforSelect(optionsarray, selectedvalue); $('#' + selectid).html(optionshtml); } function UIInputGroupNumber(placeholder, id, label = '', classinput = '', min = '', max = '', spanclass = '', imginsteadofspan = '', required = false, val = 0, datalist = '', imgwidth = '', imgheight = '', disabled = false) { let UI = UIInputGroup(placeholder, 'number', id, label, classinput, spanclass, imginsteadofspan, required, val, datalist, imgwidth, imgheight, disabled); // console.log('placeholder ',placeholder,' label ', label); UI = '
    ' + UI + '
    '; UI = $(UI); let input = UI.find('input'); input.attr('min', min); input.attr('max', max); input.val(val); return UI.html(); } function UIInputGroupButton(buttontext, buttonclass = '', buttonid = '', onclick = '', buttonstyle = '') { if (!buttontext) { return false; } if (!buttonclass) { buttonclass = 'btn-primary'; } return `
    `; } function UIInputGroupCheckBox(input_id, label, checked = false, additional_input_class = '', additional_label_class = '') { if (checked === true) { checked = 'checked'; } else { checked = ''; } return `
    ` } function UISetDarkMode() { $('body').addClass('dark-mode'); $('.tf-balance-box').removeAttr('style'); $('.card').addClass('dark-mode'); $('.card-header').addClass('dark-mode'); $('.card-body').addClass('dark-mode'); $('.modal-content').addClass('dark-mode'); $('.btn').addClass('dark-mode'); $('input').addClass('dark-mode'); $('textarea').addClass('dark-mode'); $('select').addClass('dark-mode'); $('form').addClass('dark-mode'); } function UIUpdateBodyHTML(html = '') { $('#main-body').html(html); } function changeTopbarTitle(title) { $('#topbar-title').html(title); } function setDefaultBackOnclickifNoHistory(functtoCall) { if (!functtoCall) { defaultBackOnclick = null; } if (historylist.length < 2) { if (typeof functtoCall === 'function') { defaultBackOnclick = functtoCall; } } } function setDefaultbackGotoPageifNoHistory(pageName, targetdata) { const functiongoto = function () { gotoPage(pageName, targetdata); }; setDefaultBackOnclickifNoHistory(functiongoto); } function getcurrenttargetHash() { const url = new URL(window.location.href); const parts = url.pathname.split('/').filter(Boolean); return parts.at(-1) || null; } function requestGetData(targetURL, functionsuccess, cachefirst = false) { request.url(targetURL) .success((response) => { if (typeof functionsuccess === 'function') { functionsuccess(response); } }) .data() .fromVarCache(cachefirst) .type("GET") .go(); } let ElementDOM = {}; function getUIElementsAndAttributes() { const uiElements = document.querySelectorAll('UI'); const uiData = {}; uiElements.forEach(uiElement => { const attributes = {}; attributes.innerHTML = uiElement.innerHTML; let Elementname = uiElement.id; if (!Elementname) { Elementname = uiElement.attributes.name.value; } console.log(Elementname); Array.from(uiElement.attributes).forEach(attr => { attributes[attr.name] = attr.value; }); uiData[Elementname] = attributes; uiData[Elementname].id = uiElement.id; uiData[Elementname].name = uiElement.attributes.name.value; }); return uiData; } function CheckChangesVariableVSDOM(domID) { if (!domID) { return null; } const DOMElementData = getUIElementsAndAttributes()[domID] || false; if (!DOMElementData) { return null; } const VarElementData = ElementDOM[domID] || false; } function UIElementsUpdateCard(elementData) { if (!elementData) { return false; } } const ReplaceMainViewORTargetDiv = function (html, targetDiv, append = '', removeDivID = '') { if (!targetDiv) { targetDiv = 'main-body'; } if (typeof append === 'undefined' || !append) { append = ''; } let elem = document.getElementById(targetDiv); if (targetDiv === 'main-body') { const mainview = document.getElementById('MainView'); if (mainview) { elem = mainview; } else { elem.innerHTML = '
    ' + elem.innerHTML; } } if (removeDivID) { let removeElem = document.getElementById(removeDivID); if (removeElem) { removeElem.remove(); logDev('Removed element with ID: ' + removeDivID); } else { logDev(`Element with ID: ${removeDivID} not found.`); } } html += '
    '; html += append || ''; document.getElementById(targetDiv).innerHTML = html; // logDev(`Element with ID: ${targetDiv} replaced html with. ${html}`); } const processTopBarTitleAndDefaultBack = function (topbartitle, defaultback) { if (typeof topbartitle !== 'undefined') { changeTopbarTitle(topbartitle); } if (typeof defaultback !== 'undefined' && typeof defaultback.page !== 'undefined' && typeof defaultback.data !== 'undefined') { setDefaultbackGotoPageifNoHistory(defaultback.page, defaultback.data || 0); } } function setDynamicCSS(cssText) { let styleTag = document.getElementById("dynamic-css"); if (!styleTag) { styleTag = document.createElement("style"); styleTag.id = "dynamic-css"; document.head.appendChild(styleTag); } styleTag.innerHTML = cssText; } function resetDynamicCSS() { setDynamicCSS(''); } const FormBuilder = { config: {}, dropzones: {}, build: function (options) { this.config = options; const { targetDiv, fields, formClass, append, topbartitle, defaultback, onFormGenerated } = options; processTopBarTitleAndDefaultBack(topbartitle, defaultback); // document.getElementById(targetDiv).innerHTML = '
    Please Wait..
    '; ReplaceMainViewORTargetDiv('
    Please Wait..
    ', targetDiv); let requestData; let targetHash, targetData; if (typeof currenttarget === 'object') { try { targetHash = currenttarget['target']; } catch (error) { targetHash = currenttarget; } } else { targetHash = currenttarget; } try { targetData = currenttarget['data']; } catch (error) { targetData = []; } if (typeof this.config.requestData === 'undefined') { requestData = { 'target': targetHash, 'data': targetData }; } else { requestData = this.config.requestData; } loadDataWithCache({ url: this.config.currentDataUrl, current_page: this.config.pageName, executeFunction: function (response) { const html = this.createForm(fields, targetDiv, formClass, append); if (typeof onFormGenerated === 'function') { onFormGenerated(response, html); } }.bind(this), 'requestData': requestData, 'errorFunction': this.config.unabletoLoadFunc, }); }, createForm: function (fields, targetDiv, formClass, append) { let html = ''; fields.forEach(field => { const currentDataVal = currentData[field.currentdatavar] || ''; const valuetoDisplay = field.value || currentDataVal || ''; let newValue; const datalistMaker = function (id) { return ' '; } switch (field.type) { case 'text': html += UIInputGroup(field.placeholder || '', 'text', field.id, field.label, formClass, '', '', field.required, valuetoDisplay, field.datalist || '', field.image_width || '', field.image_height || '', field.disabled || false) + datalistMaker(field.id); break; case 'number': html += UIInputGroupNumber(field.placeholder || '', field.id, field.label, formClass, 1, '', '', '', field.required, valuetoDisplay, field.datalist || '', field.image_width || '', field.image_height || '', field.disabled || false) + datalistMaker(field.id); break; case 'textarea': html += UIInputGroupTEXTAREA(field.label, field.id, field.required || false, valuetoDisplay, formClass, '', field.disabled || ''); break; case 'dropzone': html += UIInputGroupFileUploadDropzone(field.id, field.label, field.uploadUrl, '', 'width:100%', field.disabled || ''); break; case 'select': html += UIInputGroupSelect(field.id, field.label, valuetoDisplay || '', field.spanclass || '', field.imginsteadofspan || '', field.selectedvalue || '', field.imgwidth || '', field.imgheight || '', formClass || '', field.disabled || false) break; case 'button': html += UIInputGroupButton(field.label, formClass, '', field.onClick || 'FormBuilder.submit()'); break; } }); html = CreateCardSimple(false, html); ReplaceMainViewORTargetDiv(html, targetDiv, append, 'loadingText'); this.initializeDropzones(fields); this.enforceBarcodeNumeric(fields); return html; }, initializeDropzones: function (fields) { fields.filter(f => f.type === 'dropzone').forEach(f => { // InitializeLoadDataPageFuncDropZonePhotoUpload( // f.uploadUrl, // f.id, // '', // 'clearuploadbutton', // '', // 100 // ); DropZoneLOADDATAPAGEFUNC(f.uploadUrl, f.id, '', f.maxsize); const currentDataVal = currentData[f.currentdatavar] || ''; this.dropzones[f.id] = currentDropzone[f.id]; if (f.existingFiles && Array.isArray(f.existingFiles) && f.existingFiles.length > 0) { this.dropzones[f.id].functions.ReplaceDropzoneFiles(f.existingFiles); console.log(`[FormBuilder] Restored ${f.existingFiles.length} files into dropzone ${f.id}`); } else if (currentDataVal) { this.dropzones[f.id].functions.ReplaceDropzoneFiles(currentDataVal); console.log(`[FormBuilder] Restored ${currentDataVal.length} files into dropzone ${f.id}`); } }); }, enforceBarcodeNumeric: function (fields) { fields.filter(f => f.id && f.id.toLowerCase().includes('barcode')).forEach(f => { const input = document.getElementById(f.id); if (input) { input.addEventListener('input', function () { this.value = this.value.replace(/[^0-9]/g, ''); }); } }); }, validate: function () { const inputs = getInputElementsValuesObjectbyCSSClassname(this.config.formClass); if (isObjectEmpty(inputs)) return false; const invalid = Object.keys(inputs).some(k => { const val = inputs[k]; return (!val && document.getElementById(k)?.required); }); if (invalid) { ModalQuickDismiss('Error', 'Please fill out all required fields.'); return false; } return true; }, submit: function () { if (!this.validate()) return; const { submitUrl, formClass, onSuccess, onError } = this.config; SendPostDataFormwithTARGETUPLOADEDFILES(submitUrl, formClass, (response) => { getResponseHashkeyOrErrorMessage(response, (hashkey) => { if (onSuccess) onSuccess(response); }, (err) => { // if (onError) onError(err); }); }, true, function (err) { if (onError) onError(err); }); } }; const ViewBuilder = { config: {}, loadPhotos: [], targetData: null, targetHash: null, build: function (options) { this.config = options; let { targetDiv, sections, dataurl, pageName, append, topbartitle, defaultback, initialize } = options; logDev('viewbuilder starting build with options:', options); processTopBarTitleAndDefaultBack(topbartitle, defaultback); this.targetData = currenttarget; if (typeof this.targetData === 'object') { this.targetHash = this.targetData.target; } else { this.targetHash = this.targetData; } let requestData; if (typeof this.config.requestData === 'undefined') { requestData = { 'target': this.targetHash, 'data': this.targetData }; } else { requestData = this.config.requestData; } logDev('viewbuilder requestData set to:', requestData); const renderErrorPage = (response) => { sections = null; sections = [{ type: 'card', id: 'errorCard', hidden: false, value: this.config.defaultErrorHTML || 'Error Loading Data', }]; logDev('viewbuilder Error:'); this.buildhtml(sections, targetDiv, append); } logDev('viewbuilder loading data from URL:', dataurl); loadDataWithCache({ url: dataurl, current_page: pageName, executeFunction: function (response) { logDev('viewbuilder Response Data:', response); if (typeof initialize === 'function') { initialize(response); logDev('Initialize function ran after response:'); } if (!response) { logDev('viewbuilder No response received, rendering error page:'); renderErrorPage(response); } try { logDev('viewbuilder building html with sections:', sections); this.buildhtml(sections, targetDiv, append); } catch (error) { logDev('viewbuilder Error building html:', error); console.error(error); renderErrorPage(response); } }.bind(this), 'requestData': requestData, 'errorFunction': function (err) { logDev('viewbuilder Error loading data:', err); if (typeof this.config.unabletoLoadFunc === 'function') { this.config.unabletoLoadFunc(); } }.bind(this), }); }, getValorCurrentData: function (section) { if (!section) { logDev('viewbuilder getValorCurrentData called with no section, returning null.'); return null; } let currentDataVal = null; if ( typeof currentData !== 'undefined' && section.currentdatavar && currentData[section.currentdatavar] !== undefined ) { currentDataVal = currentData[section.currentdatavar]; } return section.value ?? currentDataVal ?? null; }, buildhtml: function (sections, targetDiv, append) { logDev('viewbuilder building html with sections:', sections); let html = '
    '; sections.forEach((section, i) => { html += this.renderSection(section, i); }); if (!targetDiv) { targetDiv = 'main-body'; } // let elem = document.getElementById(targetDiv); html += '
    '; html += append || ''; // document.getElementById(targetDiv).innerHTML = html; ReplaceMainViewORTargetDiv(html, targetDiv, append); if (html && targetDiv) { logDev('viewbuilder replaced main view or target div with html:' + html); } else { logDev('viewbuilder html or targetDiv is empty, skipping ReplaceMainViewORTargetDiv.'); } this.postRender(); }, renderSection: function (section, index) { switch (section.type) { case 'photos': return this.renderPhotosCard(section, index); case 'details': return this.renderDetailsCard(section, index); case 'buttons': return this.renderButtonsCard(section, index); case 'card': return this.renderCustomCard(section, index); default: return ''; } }, renderPhotosCard: function (section, index) { logDev('viewbuiler Rendering Photos Card for section:', section); if (typeof section.target === 'undefined' || !section.target) { section.target = this.targetHash; } Preloaders.ImageList(section.target, section.phototype); const photosData = this.getValorCurrentData(section); let loadingText = 'Loading photos...'; if (photosData) { this.loadPhotos.push(photosData); } else { loadingText = 'No Photos'; } logDev('viewbuilder Rendering Photos Card Success', section); return `
    ${loadingText}
    `; }, renderDetailsCard: function (section, index) { let htmlcols = ''; logDev('viewbuiler Rendering Details Card for section:', section); const detailscol = section.data; detailscol.forEach((arrVar) => { if (arrVar.type !== 'text') return; let textToDisplay = this.getValorCurrentData(arrVar); if (typeof arrVar.func === 'function') { try { textToDisplay = arrVar.func(); } catch (error) { textToDisplay = ''; } } textToDisplay = this.detailsCard.text(textToDisplay); if (typeof arrVar.bold === 'boolean' && arrVar) { textToDisplay = '' + textToDisplay + ''; } if (typeof arrVar.h === 'number' && arrVar) { textToDisplay = '' + textToDisplay + ''; } if (textToDisplay) { htmlcols += this.detailsCard.text(textToDisplay); } else { console.warn('No text or current data available for:', arrVar); } }); logDev('viewbuilder Rendering Details Card Success', section); return `
    ${htmlcols}
    `; }, detailsCard: { text: function (text) { return `
    ${text}
    `; }, }, renderButtonsCard: function (section, index) { logDev('viewbuiler Rendering Buttons Card for section:', section); const buttonsHTML = section.buttons.map(btn => `
  • ${btn.label}
  • `).join(''); logDev('viewbuilder Rendering Buttons Card Success', section); return `
      ${buttonsHTML}
    `; }, renderCustomCard: function (section, index) { let data = this.getValorCurrentData(section); logDev('viewbuiler Rendering Custom Card for section:', section, 'with data:', data); if (typeof section.render === 'function') { data = section.render(data); } logDev('viewbuilder Rendering Custom Card Success', section); return `
    ${data || ''}
    `; }, postRender: function () { logDev('viewbuilder postRender starting photo loads for:', this.loadPhotos); this.loadPhotos.forEach((arrVar) => { if (Array.isArray(arrVar) || typeof arrVar === 'object') { LoadPhotosCard('PhotosCard', `ButtonGo('ViewAllPhotos','${this.targetHash}');`, arrVar); } }); } }; const ListBuilder = (() => { const defaultConfig = { targetDiv: "", title: "List", dataUrl: "", method: "POST", search: true, pageName: "", cols: 6, type: "tiled", defaultback: "", renderCard: null, customCss: null, width: null, height: null, card: { imageField: null, nameField: null, descriptionField: null, priceField: null, unitField: null, onClick: null, fallbackImage: "https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/146710fe9ece.bin", } }; function build(config) { if (config.defaultback) { setDefaultbackGotoPageifNoHistory(config.defaultback, currenttarget); } config = deepMerge(structuredClone(defaultConfig), config); if (!config.targetDiv) { console.error("ListBuilder: targetDiv is required"); return; } setupUI(config); loadList(config); } function setupUI(config) { resetDynamicCSS(); let searchHTML = ""; if (config.search) { searchHTML = UIInputGroup( "Search", "text", "LB_Search", "", "", "", "https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/839d72e8ef8a.bin" ); } const body = ` ${searchHTML}
    Loading Please Wait...
    `; const mainCard = UICardSimple(config.title, body, "LB_MainCardBody"); $("#" + config.targetDiv).html(mainCard); $("#imgspanLB_Search").attr("onclick", "ListBuilder.clearSearch()"); $("#LB_Search").on("keyup", ListBuilder.filterList); } function loadList(config) { // loadDataWithCache({ // url: config.dataUrl, // currentPage: this.config.pageName, // executeFunction: function () { // this.createForm(fields, targetDiv, formClass, append); // }.bind(this), // 'requestData': requestData, // 'errorFunction': this.config.unabletoLoadFunc, // }); loadDataWithCache({ url: config.dataUrl, type: config.method, current_page: config.pageName, executeFunction: function (response) { if (config.customCss !== null) { setDynamicCSS(config.customCss); } else if (config.type === 'tiled') { setCSStoTiled(); } renderList(response, config) changeTopbarTitle(config.title); }, 'errorFunction': config.unabletoLoadFunc, }); } function setCSStoTiled() { const tiledcss = `.ListRowCard { height: 100%; display: flex; flex-direction: column; } .ListCardRow { flex: 1; } .equal-height { display: flex; }`; setDynamicCSS(tiledcss); } function renderList(data, config) { if (!Array.isArray(data)) data = []; if (data.length === 0) { $("#LB_ListContainer").html("
    No Data
    "); return; } let html = [`
    `]; data.forEach((item, index) => { html.push(renderCard(item, index, config)); }); html.push(`
    `); $("#LB_ListContainer").html(html.join("")); postLoadImages(); setupIntersectionObserver(); } function renderCard(item, index, config) { if (typeof config.renderCard === 'function') { return config.renderCard(item, index, config); } const c = config.card; let img = item[c.imageField]; if (Array.isArray(img)) img = img[0]; const imageId = `LB_photo_${index}`; queueImageLoad(imageId, img); let imageHtml = ` `; let description = item[c.descriptionField] || ""; if (description.length > 80) { description = description.substring(0, 80) + "..."; } const clickAction = c.onClick ? c.onClick(item) : "javascript:void(0)"; let width = ''; let height = ''; if (config.width) { width = ' width: ' + config.width + '; '; } if (config.height) { height = ' height: ' + config.height + '; '; } return ` `; } /* ------------------------------ IMAGE HANDLING ------------------------------ */ const preloadQueue = []; function queueImageLoad(imageId, fileHash) { preloadQueue.push([imageId, fileHash]); } function postLoadImages() { preloadQueue.forEach(([imageId, hash]) => { LoadAndCreateURLfromFileHash(hash).then(url => { const ElementIMG = document.getElementById(imageId); if (ElementIMG) { ElementIMG.src = url; } }); }); } /* ------------------------------ OBSERVER ------------------------------ */ function setupIntersectionObserver() { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (!entry.isIntersecting) return; const rowIndex = entry.target.id.split("_")[2]; const hashDiv = $("#LB_Hash_" + rowIndex).text(); if (hashDiv) { request.url('/View/Product/Details/data') .success(() => { }) .data({ target: hashDiv }) .fromVarCache(true) .type("POST") .go(); } }); }, { threshold: 0.1 }); $(".ListRowCard").each(function () { observer.observe(this); }); } /* ------------------------------ SEARCH ------------------------------ */ function filterList() { const searchTerm = $("#LB_Search").val().toLowerCase(); $("#LB_ListContainer .card").each(function () { const text = $(this).text().toLowerCase(); if (text.includes(searchTerm)) { this.style.display = "block"; if (this.parentElement.parentElement.id !== 'LB_ListContainer') { this.parentElement.parentElement.style.display = "block"; } } else { this.style.display = "none"; if (this.parentElement.parentElement.id !== 'LB_ListContainer') { this.parentElement.parentElement.style.display = "none"; } } }); } function clearSearch() { $("#LB_Search").val(""); filterList(); } /* ------------------------------ UTILS ------------------------------ */ function deepMerge(target, source) { for (const key in source) { if (source[key] && typeof source[key] === "object") { if (!target[key]) target[key] = {}; deepMerge(target[key], source[key]); } else { target[key] = source[key]; } } return target; } return { build, filterList, clearSearch, queueImageLoad, }; })(); /** * Create a searchable, paginated table using jQuery DataTables * * @param {Object} options * @param {Array} options.data - Array of objects OR array of arrays * @param {Array} [options.headers] - Optional table headers * @param {String} [options.tableId] - Table ID * @param {Number} [options.defaultSortColumn] - Column index * @param {String} [options.defaultSortDirection] - 'asc' | 'desc' * @param {String} [options.defaultSearch] - Default search text * @param {Number} [options.pageLength] - Rows per page * @param {Boolean} [options.initializeTable] * @param {Boolean} [options.placeTable] */ function createSearchableTable({ data, headers = [], tableId = "dynamicTable", defaultSortColumn = 0, defaultSortDirection = "asc", defaultSearch = "", pageLength = 10, initializeTable = true, placeTable = true, }) { if (!Array.isArray(data) || data.length === 0) { console.error("Data must be a non-empty array"); return null; } const isObjectData = data[0] !== null && typeof data[0] === "object" && !Array.isArray(data[0]); if (isObjectData && headers.length === 0) { headers = Object.keys(data[0]); } let tableHTML = ``; headers.forEach(header => { tableHTML += ``; }); tableHTML += ``; data.forEach(row => { tableHTML += ``; if (isObjectData) { headers.forEach(key => { tableHTML += ``; }); } else { row.forEach(cell => { tableHTML += ``; }); } tableHTML += ``; }); tableHTML += `
    ${header}
    ${row[key] ?? ""}${cell}
    `; let dataTable = null; if (placeTable) { $("#tableContainer").html(tableHTML); if (initializeTable) { dataTable = $(`#${tableId}`).DataTable({ pageLength, order: [[defaultSortColumn, defaultSortDirection]], search: { search: defaultSearch } }); } } return { html: tableHTML, dataTable }; }