diff --git a/frappe/public/build.json b/frappe/public/build.json index dd1ff3c24b..8e04fbf48a 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -368,6 +368,7 @@ "js/web_form.min.js": [ "public/js/frappe/misc/datetime.js", "public/js/frappe/web_form/web_form_class.js", + "public/js/frappe/web_form/web_form_list_class.js", "public/js/frappe/web_form/web_form.js", "public/js/lib/datepicker/datepicker.min.js", "public/js/lib/datepicker/datepicker.en.js" diff --git a/frappe/public/js/frappe/web_form/web_form_class.js b/frappe/public/js/frappe/web_form/web_form_class.js index 79f303ccc4..3e527c7138 100644 --- a/frappe/public/js/frappe/web_form/web_form_class.js +++ b/frappe/public/js/frappe/web_form/web_form_class.js @@ -1,8 +1,7 @@ frappe.provide("frappe.ui"); -frappe.provide("frappe.views"); window.web_form = null; -window.web_form_list = null; + frappe.ui.WebForm = class WebForm extends frappe.ui.FieldGroup { constructor(opts) { @@ -44,7 +43,7 @@ frappe.ui.WebForm = class WebForm extends frappe.ui.FieldGroup { const delete_button = document.createElement("button"); delete_button.classList.add( "btn", - "btn-danger", + "btn-secondary", "button-delete", "btn-sm", "ml-2" @@ -120,261 +119,5 @@ frappe.ui.WebForm = class WebForm extends frappe.ui.FieldGroup { success_dialog.set_message(success_message); success_dialog.show(); } + }; - -frappe.views.WebFormList = class WebFormList { - constructor(opts) { - Object.assign(this, opts); - window.web_form_list = this; - this.wrapper = document.getElementById("datatable"); - this.refresh(); - this.make_actions(); - } - - refresh() { - this.table && this.table.remove() && delete this.table; - this.rows = []; - this.page_length = 20; - this.web_list_start = 0; - - frappe.run_serially([ - () => this.get_list_view_fields(), - () => this.get_data(), - () => this.make_table(), - ]); - } - - get_list_view_fields() { - return frappe - .call({ - method: - "frappe.website.doctype.web_form.web_form.get_in_list_view_fields", - args: { doctype: this.doctype } - }) - .then(response => (this.fields_list = response.message)); - } - - fetch_data() { - return frappe.call({ - method: "frappe.www.list.get_list_data", - args: { - doctype: this.doctype, - fields: this.fields_list.map(df => df.fieldname), - limit_start: this.web_list_start, - web_form_name: this.web_form_name - } - }); - } - - async get_data() { - let response = await this.fetch_data(); - this.data = await response.message; - } - - more() { - this.web_list_start += this.page_length - this.fetch_data().then((res) => { - if (res.message.length === 0) { - frappe.msgprint("No more items to display") - } - this.append_rows(res.message) - }) - - } - - make_table() { - this.table = document.createElement("table"); - this.table.classList.add("table"); - - this.make_table_head(); - this.append_rows(this.data); - - this.wrapper.appendChild(this.table); - } - - make_table_head() { - // Create Heading - let thead = this.table.createTHead(); - thead.style.backgroundColor = "#f7fafc"; - thead.style.color = "#8d99a6"; - let row = thead.insertRow(); - this.columns = this.fields_list.map(df => { - return { - label: df.label, - fieldname: df.fieldname - }; - }); - - let th = document.createElement("th"); - - let checkbox = document.createElement("input"); - checkbox.type = "checkbox"; - checkbox.onclick = event => - this.toggle_select_all(event.target.checked); - - th.appendChild(checkbox); - row.appendChild(th); - - add_heading(row, "Sr."); - this.columns.forEach(col => { - let th = document.createElement("th"); - let text = document.createTextNode(col.label); - th.appendChild(text); - row.appendChild(th); - }); - - function add_heading(row, label) { - let th = document.createElement("th"); - th.innerText = label; - row.appendChild(th); - } - } - - append_rows(row_data) { - const tbody = this.table.childNodes[1] || this.table.createTBody(); - row_data.forEach((data_item) => { - let row_element = tbody.insertRow(); - row_element.setAttribute("id", data_item.name); - - let row = new frappe.ui.WebFromListRow({ - row: row_element, - doc: data_item, - columns: this.columns, - serial_number: web_form_list.rows.length + 1, - events: { - onEdit: () => this.open_form(data_item.name), - onSelect: () => this.toggle_delete() - } - }); - - this.rows.push(row); - }); - } - - make_actions() { - const actions = document.querySelector(".list-view-actions"); - const footer = document.querySelector(".list-view-footer"); - - addButton(actions, "delete-rows", "danger", true, "Delete", () => - this.delete_rows() - ); - - addButton( - actions, - "new", - "primary", - false, - "New", - () => (window.location.href = window.location.pathname + "?new=1") - ); - - if (this.rows.length >= this.page_length) addButton(footer, "more", "secondary", false, "More", () => - this.more() - ); - - function addButton(wrapper, id, type, hidden, name, action) { - const button = document.createElement("button"); - button.classList.add("btn", "btn-primary", "btn-sm", "ml-2"); - if (type == "secondary") - button.classList.add( - "btn", - "btn-secondary", - "btn-sm", - "ml-2", - "text-white" - ); - if (type == "danger") - button.classList.add( - "btn", - "btn-danger", - "button-delete", - "btn-sm", - "ml-2" - ); - - button.id = id; - button.innerText = name; - button.hidden = hidden; - - button.onclick = action; - wrapper.appendChild(button); - } - } - - toggle_select_all(checked) { - this.rows.forEach(row => row.toggle_select(checked)); - } - - open_form(name) { - window.location.href = window.location.pathname + "?name=" + name; - } - - get_selected() { - return this.rows.filter(row => row.is_selected()); - } - - toggle_delete() { - let btn = document.getElementById("delete-rows"); - btn.hidden = !this.get_selected().length; - } - - delete_rows() { - frappe - .call({ - type: "POST", - method: - "frappe.website.doctype.web_form.web_form.delete_multiple", - args: { - web_form_name: this.web_form_name, - docnames: this.get_selected().map(row => row.doc.name) - } - }) - .then(() => { - this.refresh() - this.toggle_delete() - }); - } -}; - -frappe.ui.WebFromListRow = class WebFromListRow { - constructor({ row, doc, columns, serial_number, events, options }) { - Object.assign(this, { row, doc, columns, serial_number, events }); - this.make_row(); - } - - make_row() { - // Add Checkboxes - let cell = this.row.insertCell(); - - this.checkbox = document.createElement("input"); - this.checkbox.type = "checkbox"; - this.checkbox.onclick = event => { - this.toggle_select(event.target.checked); - event.stopImmediatePropagation(); - } - - cell.appendChild(this.checkbox); - - // Add Serial Number - let serialNo = this.row.insertCell(); - serialNo.innerText = this.serial_number; - - this.columns.forEach(field => { - let cell = this.row.insertCell(); - let text = document.createTextNode(this.doc[field.fieldname] || ""); - cell.appendChild(text); - }); - - this.row.onclick = () => this.events.onEdit(); - this.row.style.cursor = "pointer"; - } - - toggle_select(checked) { - this.checkbox.checked = checked; - this.events.onSelect(checked); - } - - is_selected() { - return this.checkbox.checked; - } -}; \ No newline at end of file diff --git a/frappe/public/js/frappe/web_form/web_form_list_class.js b/frappe/public/js/frappe/web_form/web_form_list_class.js new file mode 100644 index 0000000000..0b0437d242 --- /dev/null +++ b/frappe/public/js/frappe/web_form/web_form_list_class.js @@ -0,0 +1,269 @@ +frappe.provide("frappe.ui"); +frappe.provide("frappe.views"); + +window.web_form_list = null; + +frappe.views.WebFormList = class WebFormList { + constructor(opts) { + Object.assign(this, opts); + window.web_form_list = this; + this.wrapper = document.getElementById("datatable"); + this.refresh(); + this.make_actions(); + this.make_filters(); + } + + refresh() { + this.table && Array.from(this.table.tBodies).forEach(o_o => o_o.remove()); + this.rows = []; + this.page_length = 20; + this.web_list_start = 0; + + frappe.run_serially([ + () => this.get_list_view_fields(), + () => this.get_data(), + () => this.make_table(), + ]); + } + + make_filters() { + console.log("making_filters"); + } + + get_list_view_fields() { + return frappe + .call({ + method: + "frappe.website.doctype.web_form.web_form.get_in_list_view_fields", + args: { doctype: this.doctype } + }) + .then(response => (this.fields_list = response.message)); + } + + fetch_data() { + return frappe.call({ + method: "frappe.www.list.get_list_data", + args: { + doctype: this.doctype, + fields: this.fields_list.map(df => df.fieldname), + limit_start: this.web_list_start, + web_form_name: this.web_form_name + } + }); + } + + async get_data() { + let response = await this.fetch_data(); + this.data = await response.message; + } + + more() { + this.web_list_start += this.page_length + this.fetch_data().then((res) => { + if (res.message.length === 0) { + frappe.msgprint("No more items to display") + } + this.append_rows(res.message) + }) + + } + + make_table() { + this.columns = this.fields_list.map(df => { + return { + label: df.label, + fieldname: df.fieldname + }; + }); + + if (! this.table) { + this.table = document.createElement("table"); + this.table.classList.add("table"); + this.make_table_head(); + } + + this.append_rows(this.data); + + this.wrapper.appendChild(this.table); + } + + make_table_head() { + // Create Heading + let thead = this.table.createTHead(); + thead.style.backgroundColor = "#f7fafc"; + thead.style.color = "#8d99a6"; + let row = thead.insertRow(); + + let th = document.createElement("th"); + + let checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.onclick = event => + this.toggle_select_all(event.target.checked); + + th.appendChild(checkbox); + row.appendChild(th); + + add_heading(row, "Sr."); + this.columns.forEach(col => { + let th = document.createElement("th"); + let text = document.createTextNode(col.label); + th.appendChild(text); + row.appendChild(th); + }); + + function add_heading(row, label) { + let th = document.createElement("th"); + th.innerText = label; + row.appendChild(th); + } + } + + append_rows(row_data) { + const tbody = this.table.childNodes[1] || this.table.createTBody(); + row_data.forEach((data_item) => { + let row_element = tbody.insertRow(); + row_element.setAttribute("id", data_item.name); + + let row = new frappe.ui.WebFromListRow({ + row: row_element, + doc: data_item, + columns: this.columns, + serial_number: web_form_list.rows.length + 1, + events: { + onEdit: () => this.open_form(data_item.name), + onSelect: () => this.toggle_delete() + } + }); + + this.rows.push(row); + }); + } + + make_actions() { + const actions = document.querySelector(".list-view-actions"); + const footer = document.querySelector(".list-view-footer"); + + addButton(actions, "delete-rows", "danger", true, "Delete", () => + this.delete_rows() + ); + + addButton( + actions, + "new", + "primary", + false, + "New", + () => (window.location.href = window.location.pathname + "?new=1") + ); + + if (this.rows.length >= this.page_length) addButton(footer, "more", "secondary", false, "More", () => + this.more() + ); + + function addButton(wrapper, id, type, hidden, name, action) { + const button = document.createElement("button"); + button.classList.add("btn", "btn-primary", "btn-sm", "ml-2"); + if (type == "secondary") + button.classList.add( + "btn", + "btn-secondary", + "btn-sm", + "ml-2", + "text-white" + ); + if (type == "danger") + button.classList.add( + "btn", + "btn-danger", + "button-delete", + "btn-sm", + "ml-2" + ); + + button.id = id; + button.innerText = name; + button.hidden = hidden; + + button.onclick = action; + wrapper.appendChild(button); + } + } + + toggle_select_all(checked) { + this.rows.forEach(row => row.toggle_select(checked)); + } + + open_form(name) { + window.location.href = window.location.pathname + "?name=" + name; + } + + get_selected() { + return this.rows.filter(row => row.is_selected()); + } + + toggle_delete() { + let btn = document.getElementById("delete-rows"); + btn.hidden = !this.get_selected().length; + } + + delete_rows() { + frappe + .call({ + type: "POST", + method: + "frappe.website.doctype.web_form.web_form.delete_multiple", + args: { + web_form_name: this.web_form_name, + docnames: this.get_selected().map(row => row.doc.name) + } + }) + .then(() => { + this.refresh() + this.toggle_delete() + }); + } +}; + +frappe.ui.WebFromListRow = class WebFromListRow { + constructor({ row, doc, columns, serial_number, events, options }) { + Object.assign(this, { row, doc, columns, serial_number, events }); + this.make_row(); + } + + make_row() { + // Add Checkboxes + let cell = this.row.insertCell(); + + this.checkbox = document.createElement("input"); + this.checkbox.type = "checkbox"; + this.checkbox.onclick = event => { + this.toggle_select(event.target.checked); + event.stopImmediatePropagation(); + } + + cell.appendChild(this.checkbox); + + // Add Serial Number + let serialNo = this.row.insertCell(); + serialNo.innerText = this.serial_number; + + this.columns.forEach(field => { + let cell = this.row.insertCell(); + let text = document.createTextNode(this.doc[field.fieldname] || ""); + cell.appendChild(text); + }); + + this.row.onclick = () => this.events.onEdit(); + this.row.style.cursor = "pointer"; + } + + toggle_select(checked) { + this.checkbox.checked = checked; + this.events.onSelect(checked); + } + + is_selected() { + return this.checkbox.checked; + } +}; \ No newline at end of file diff --git a/frappe/website/doctype/web_form/templates/web_form.html b/frappe/website/doctype/web_form/templates/web_form.html index f8d5b6f179..bce669f412 100644 --- a/frappe/website/doctype/web_form/templates/web_form.html +++ b/frappe/website/doctype/web_form/templates/web_form.html @@ -21,8 +21,13 @@ {% block page_content %}