//ver 1 class WiseHubJson2Form extends HTMLElement { //system keeps here somme data - like uploaded files #attachments; constructor() { super(); this.uniqId = this.generateCode(64); this.#attachments = {}; try { this.user = getUserFromStorage(); } catch (ex) { this.user = null; } } connectedCallback() { this.endPoint = this.getAttribute("endpoint"); this.guid = this.getAttribute("guid"); var tmp = this.getAttribute("save-dispatch"); if (tmp && (tmp.toLowerCase() == "true" || tmp.toLowerCase() == "1" || tmp.toLowerCase() == "yes")) this.saveDispatch = true; else this.saveDispatch = false; if (this.endPoint) this.loadData(); } addToAttachments(key, value) { if (key.startsWith("ATTACHMENT_FOR_FIELD_")) key = key.replace("ATTACHMENT_FOR_FIELD_", ""); this.#attachments[key] = value; this.redrawAttachments(); } removeFromAttachments(key) { delete this.#attachments[key]; this.redrawAttachments(); //this.#attachments[key] = null; } getAttachment(key) { var tmp = this.#attachments[key]; return tmp; } getConfirmationCaption(v) { if (v == null || v == "") { return "Kliknij, aby potwierdzić"; } else { return "Potwierdzone: " + v; } } redrawAttachments() { console.log("redrawing attachemnts") const redraw=(key, obj) => { console.log(key, obj); }; document.querySelectorAll(`.attachment-container`).forEach(x=>{ x.style.display = "none"; }); Object.keys(this.#attachments).forEach(key => { console.log("key", key); document.querySelectorAll(`.${this.uniqId}-file-info`).forEach(x=>{ redraw(key, x); }); document.querySelectorAll(`.${this.uniqId}-file-action`).forEach(x=>{ if (x.getAttribute("data-ref")==key) { x.style.display = "inline"; } }); }); } loadData() { var url = this.endPoint; if (url.includes("?")) url += "&"; else url += "?"; url += "action=load&code=" + this.guid; fetch(url) .then((response) => response.json()) .then((data) => { //console.log(data); this.formData = JSON.parse(data.data[0].frd_definition); var loaded = data.data[0].data; if (loaded == null || loaded == "") loaded = "[]"; loaded = loaded.replace(/\n/g, '\\n'); this.formLoaded = JSON.parse(loaded); this.render(); this.setLoaded(); this.redrawAttachments(); }) .catch((ex) => { console.log('Error:', ex); }); } setData(formDefinition, formUserData) { this.formLoaded = formUserData; this.formData = formDefinition; this.render(); this.setLoaded(); } getUniqId() { return this.uniqId; } getData() { let response = { "guid": this.guid }; let formResponse = []; let error = false; let errorInfo = ""; var parent = document.querySelector(`#${this.uniqId}`); this.formData.sections.forEach(section => { section.fields.forEach(field => { var fid = field.id; if (fid == null || fid == "") { fid = field.name; } var fieldDom = parent.querySelector(`#${fid}`); if (fieldDom==null) { console.log("Trying to find (failed) dom id=" + fid); } this.removeClass(fieldDom, 'border-danger'); if (fid != null && fid != "") { field.value = fieldDom.value; } if (field.required == 1 && field.value == "" && fieldDom.style.display != 'none') { error = true; console.log("error field",field, fieldDom); errorInfo += field.caption + "(" + field.id + "); "; this.addClass(fieldDom, 'border-danger'); } //console.log(fieldDom); formResponse.push({ "id": fid, "value": field.value }); }); }); Object.keys(this.#attachments).forEach(key => { formResponse.push({ "id": "ATTACHMENT_FOR_FIELD_" + key, "value": this.#attachments[key] }); }); this.error = error; this.errorInfo = errorInfo; response["questions"] = this.formFlat; response["answers"] = formResponse; return response; } save() { var response = this.getData(); if (this.saveDispatch == false) { var postUrl = this.endPoint + "?action=save&code=" + this.guid; fetch(postUrl, { method: 'POST', // or 'PUT' credentials: 'include', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(response), }) .then((res) => res.json()) .then((data) => { //if (success != null) success(data); }) .catch((ex) => { console.error('Error:', ex); //if (error != null) error(ex); }); } else { response["id"] = this.uniqId; response["error"] = this.error; response["errorInfo"] = this.errorInfo; let event = new CustomEvent("json2form", { bubbles: true, composed: false, detail: response }); // (2) this.dispatchEvent(event); } } render() { var form = this.formData; this.formFlat = []; var html = `

${form['title']}

${form['lead']}

`; var sectionId = ""; for (var s = 0; s < form['sections'].length; s++) { var section = form['sections'][s]; sectionId = section["id"]; var cap = section['title']; html += "

" + cap + "

";// for (var a = 0; a < section['fields'].length; a++) { var o = section['fields'][a]; var id = o['id']; var css = o['domClass']; var cap = o["caption"]; var name = o["name"]; var hint = o["hint"]; if (css == "") { css = "w-100"; } var info = ""; if (o["required"] == 1) { info = " *"; } var type = o["type"]; if (type == "header") { html += "

" + cap + "

"; } else if (type != "section") { var bold = ""; if (type == "label") bold = "fw-bold font-weight-bold"; html += "
" + cap + " " + info + "
"; if (hint != null && hint != "") { html += "
" + hint + "
"; } if (type == "select") { html += ""; } else if (type == "wh-confirmation") { html += ``; html += ``; this.formFlat.push({ "id:": id, "question": cap, "possibleId": "", "possibleTxt": "" }); } else if (type == 'textarea') { //field.value - previus html += ``; this.formFlat.push({ "id:": id, "question": cap, "possibleId": "", "possibleTxt": "" }); } else if (type == 'label') { html += ``; this.formFlat.push({ "id:": id, "question": cap, "possibleId": "", "possibleTxt": "" }); } else if (type == 'file') { var oldId = id; //id = id+"xx"; html += ""; html += ""; html += "
"; html += "pobierz"; html += "usuń"; html += "
"; html += ""; //html += ""; } else { html += ""; this.formFlat.push({ "id:": id, "question": cap, "possibleId": "", "possibleTxt": "" }); } } } html += "
"; } html += "
"; html += "
"; html += ``; html += "
"; this.innerHTML = html; this.redrawAttachments(); //binfing confiormation document.querySelectorAll(`.${this.uniqId}-btn-confirmation`).forEach(confirmBtn => { confirmBtn.addEventListener("click", btn => { if (this.user != null) { $(`#${this.uniqId}`).find(`#${confirmBtn.getAttribute("data-ref")}`).val(this.user.userSymbol); confirmBtn.value = this.getConfirmationCaption(this.user.userSymbol); } else { showPopup("Użytkownik nie jest zalogowany", false) } }); }); //binding file document.querySelectorAll(`.${this.uniqId}-file-action`).forEach(btnInput => { btnInput.addEventListener("click", (b) => { var ref = b.target.getAttribute("data-ref"); var action = b.target.getAttribute("data-action"); var att = this.getAttachment(ref); if (att == null) { alert('Nie wgrano załącznika'); } else { if (action == "delete") { this.removeFromAttachments(ref); document.getElementById(ref).value = "wybierz"; } else { const byteCharacters = atob(this.getAttachment(ref)); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += 512) { const slice = byteCharacters.slice(offset, offset + 512); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } const blob = new Blob(byteArrays, { type: 'application/octet-stream' }); // Create temporary anchor element const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = document.getElementById(ref).value; // Trigger the download a.click(); } } console.log(this.#attachments); }); }); document.querySelectorAll(`.${this.uniqId}-file-upload-button`).forEach(btnInput => { btnInput.addEventListener("click", (b) => { console.log(b.target.getAttribute("data-ref")); var ref = b.target.getAttribute("data-ref"); document.getElementById(ref).click(); }); }); document.querySelectorAll(`.${this.uniqId}-file`).forEach(fileInput => { fileInput.addEventListener('change', (event) => { // Get the file from the input element const file = event.target.files[0]; const parentId = fileInput.getAttribute("data-ref"); if (file) { // Create a new FileReader instance const reader = new FileReader(); var that = this; // Define the onload callback function reader.onload = function (e) { // The file's content will be available as a Base64 encoded string in e.target.result const base64String = e.target.result.split(',')[1]; // Remove the data URL prefix console.log('File Name:', file.name); document.getElementById(parentId).value = file.name; that.addToAttachments(parentId, base64String); // You can now use the file.name and base64String variables as needed }; // Read the file content as a Data URL (Base64 encoded string) reader.readAsDataURL(file); } }); }); //bingind save button document.querySelector(`#${this.uniqId}-save`).onclick = () => { this.save(); }; this.prepareVisibility(form); this.dispatchReady(); } dispatchReady() { let event = new CustomEvent("wh-json-form-ready", { bubbles: true, composed: false, detail: { "status": "ready", "uniqId": this.uniqId } }); // (2) document.dispatchEvent(event); } prepareVisibility(form) { this.conds = []; for (var a = 0; a < form['visibility'].length; a++) { var vis = form['visibility'][a]; var ifArr = vis["if"].split(":"); var show = vis["show"]; if (ifArr.length > 1) { this.conds.push({ 'if': ifArr[0], 'eq': ifArr[1], 'show': show }); this.formsSetVisibilityItems(show, 'none'); } } var items = document.querySelector(`#${this.uniqId}`).querySelectorAll(`select`); items.forEach(i => { var that = this; i.addEventListener('change', function () { that.conds.forEach(item => {//hide all that.formsSetVisibilityItems(item.show, 'none'); }); that.conds.forEach(item => {//show if equal var obj = document.getElementById(item['if']) if (obj != null && obj.value != null && item.eq == obj.value) { //console.log("if", item['if'], "==", obj.value, ' show', item['show']); that.formsSetVisibilityItems(item.show, 'block'); } }); }); }); } setLoaded() { let changeEvent = new Event('change'); this.formLoaded.forEach(l => { if (!l.id.startsWith("ATTACHMENT_FOR_FIELD_")) { var item = document.querySelector(`#${this.uniqId}`).querySelector(`#${l.id}`); if (item) { item.value = l.value; item.dispatchEvent(changeEvent); } } else {//convert fields with attachments as this.#attachment this.addToAttachments(l.id, l.value); } }); document.querySelectorAll(`.${this.uniqId}-btn-confirmation`).forEach(x => { var l = $(`#${this.uniqId}`).find(`#${x.getAttribute("data-ref")}`).val(); x.value = this.getConfirmationCaption(l); }); } formsSetVisibilityItems(elementId, display) { var field = document.getElementById(elementId); if (field != null) field.style.display = display; var divsToHide = document.getElementsByClassName(elementId); //divsToHide is an array for (var i = 0; i < divsToHide.length; i++) { divsToHide[i].style.display = display; } } generateCode(len) { var c = "qwertyuiopasdfhgjhkjlzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"; var s = ""; for (var a = 0; a < len; a++) { var idx = Math.floor(Math.random() * c.length); s = s + c[idx]; } return s; } addClass(element, className) { if (element && !element.classList.contains(className)) { element.classList.add(className); } } removeClass(element, className) { if (element && element.classList.contains(className)) { element.classList.remove(className); } } } customElements.define("wh-json2form", WiseHubJson2Form);