UNPKG

globular-mvc

Version:

Generic template to create web-application that made use of globular as backend and materialize as css (wrap in web-component's)

451 lines (352 loc) 14.4 kB
import '@polymer/iron-icons/iron-icons.js'; import '@polymer/paper-icon-button/paper-icon-button.js'; import '@polymer/paper-input/paper-input.js'; import '@polymer/paper-card/paper-card.js'; import '@polymer/paper-button/paper-button.js'; import '@polymer/paper-checkbox/paper-checkbox.js'; import '@polymer/paper-badge/paper-badge.js'; import '@polymer/paper-tooltip/paper-tooltip.js'; import '@polymer/paper-radio-button/paper-radio-button.js'; import '@polymer/paper-radio-group/paper-radio-group.js'; import '@polymer/paper-toggle-button/paper-toggle-button.js'; import '@polymer/paper-spinner/paper-spinner.js'; import { Model } from '../Model'; import { ApplicationView } from '../ApplicationView'; import { fireResize } from './utility'; /** * Search Box */ export class Wizard extends HTMLElement { // attributes. // Create the applicaiton view. constructor(width) { super() // Set the shadow dom. this.attachShadow({ mode: 'open' }); // The list of page. this.pages = []; // The list of steps buttons. this.stepsButton = []; // the page content. this.content = null; // the div where action are listed. this.stepsDiv = null; // the last page to display before closing the wizard this.summaryPage = null; // the initial width this.width = width; if (width > screen.width) { // the initial width this.width = screen.width } // the current index. this.index = 0; // A function pointer call we the all is done this.ondone = null; // A function call before close the wizard this.onclose = null; // Innitialisation of the layout. this.shadowRoot.innerHTML = ` <style> paper-card h3 { margin-block-end: 0px; } paper-input iron-icon{ margin-right: 10px; } paper-tooltip p{ min-width:200px; font-size: 1.35em; } .step-number{ position: relative; display: flex; justify-content: center; align-items: center; margin: 5px 10px 5px 10px; width: 30px; height: 30px; border-radius: 17px; border: 2px solid var(--palette-action-disabled); color: var(--palette-action-disabled); } .step-number paper-ripple { display: none; } .step-number paper-ripple:hover { cursor: pointer; } .step-number.disable{ border: 2px solid var(--palette-action-disabled); background-color: var(--palette-action-disabledBackground); } .step-number.active{ border-color: var(--palette-action-active); color: var(--palette-text-primary); background-color: var(--palette-background-paper); } .step-number.active paper-ripple { display: block; } .step-number.disable paper-ripple { display: block; } #container{ overflow: hidden; background-color: var(--palette-background-paper); } #pages{ display: flex; transition: transform .6666s; } .content { padding: 0px; margin: 0px; font-size: 1.1rem; } .step-number:hover{ cursor: pointer; } .card-actions{ display: flex; width: 100%; justify-content: flex-end; } paper-button { font-size: 1rem; } @media(max-width: 500px){ #content{ height: calc(100vh - 84px); } } </style> <div id="container"> <div class="content" id="content"> <div id="pages"> <slot></slot> </div> <slot name="summary_page"></slot> </div> <div class="card-actions" id="card-actions"> <div id="step-numbers" style="display: flex; flex-grow: 1; flex-wrap: wrap;"></div> <paper-button id="previous_btn" style="display:none">previous</paper-button> <paper-button id="next_btn">next</paper-button> <paper-button id="done_btn" style="display:none">Done</paper-button> <paper-button id="close_btn" style="display:none">Close</paper-button> </div> </div> ` this.container = this.shadowRoot.getElementById("container") this.content = this.shadowRoot.getElementById("content") this.pagesDiv = this.shadowRoot.getElementById("pages") this.stepsDiv = this.shadowRoot.getElementById("card-actions") this.stepsNumberDiv = this.shadowRoot.getElementById("step-numbers") this.container.style.width = this.width + "px" this.container.style.overflow = "hidden" // Action this.nexBtn = this.shadowRoot.getElementById("next_btn") this.previousBtn = this.shadowRoot.getElementById("previous_btn") this.doneBtn = this.shadowRoot.getElementById("done_btn") this.closeBtn = this.shadowRoot.getElementById("close_btn") // go to next page. this.nexBtn.onclick = () => { this.next() } this.previousBtn.onclick = () => { this.previous() } this.doneBtn.onclick = () => { // hide the content. this.nexBtn.style.display = "none" this.previousBtn.style.display = "none" this.doneBtn.style.display = "none" this.stepsNumberDiv.style.display = "none" this.pagesDiv.style.display = "none" this.pagesDiv.style.transform = `translate(0px)` // Show the close btn. this.closeBtn.style.display = "block" // append the summary page. let summaryPage = this.querySelector("#summary_page") if (summaryPage) { summaryPage.style.display = "block" } if (this.ondone != null) { this.ondone(summaryPage) } } // Close the wizard. this.closeBtn.onclick = () => { this.parentNode.removeChild(this) if (this.onclose != null) { this.onclose() } } window.addEventListener("resize", (evt) => { let w = ApplicationView.layout.width(); // TODO try to set it in the css propertie instead... if (w < 500) { this.container.style.width = screen.width + "px" if (this.summaryPage) this.summaryPage.style.maxWidth = this.summaryPage.style.minWidth = this.width + "px" this.pages.forEach(p => { p.parentNode.style.maxWidth = p.parentNode.style.minWidth = this.width + "px" }) } else { this.container.style.width = width + "px" if (this.summaryPage) this.summaryPage.style.maxWidth = this.summaryPage.style.minWidth = width + "px" this.pages.forEach(p => { p.parentNode.style.maxWidth = p.parentNode.style.minWidth = width + "px" }) } }) } connectedCallback() { fireResize() } // The first page of the wizard to explain what will follow. getPage(index) { return this.pages[index]; } // Use it to get elment from inside wizard dom. getElementById(id) { return this.shadowRoot.getElementById(id) } // Return list of element by their classname. getElementsByClassName(className) { return this.shadowRoot.querySelectorAll("." + className) } // Set the summary page. setSummaryPage(content) { content.style.padding = "15px" this.summaryPage = document.createElement("div") this.summaryPage.id = "summary_page" this.summaryPage.style.width = this.width + "px" this.summaryPage.style.display = "none" this.summaryPage.slot = "summary_page" this.summaryPage.appendChild(content) this.appendChild(this.summaryPage) } // Append a configuration page. appendPage(content) { // Create the page div. let page = document.createElement("div") content.style.padding = "15px" page.id = "page_" + this.pages.length + 1 page.style.maxWidth = page.style.minWidth = this.width + "px" page.appendChild(content) // Append the content to the slot... this.appendChild(page) let stepNumberBtn = document.createElement("div") stepNumberBtn.className = "step-number" stepNumberBtn.innerHTML = ` ${this.pages.length + 1} <paper-ripple class="circle" recenters></paper-ripple>` stepNumberBtn.index = this.pages.length this.stepsNumberDiv.appendChild(stepNumberBtn) if (stepNumberBtn.index == 0) { stepNumberBtn.classList.add("active") } this.pages.push(this.content.lastElementChild) this.stepsButton.push(stepNumberBtn) // set the step number button action. stepNumberBtn.onclick = () => { if (!stepNumberBtn.classList.contains("active") && !stepNumberBtn.classList.contains("disable")) { return; } this.index = stepNumberBtn.index for (var i = 0; i < this.pages.length; i++) { if (this.stepsButton[i].classList.contains("active") || this.stepsButton[i].classList.contains("disable")) { this.stepsButton[i].classList.remove("active") this.stepsButton[i].classList.add("disable") } } this.stepsButton[this.index].classList.add("active") this.pagesDiv.style.transform = `translate(${this.index * this.width * -1}px)` // show the next button. if (this.index < this.pages.length - 1 && this.pages.length > 1) { this.nexBtn.style.display = "block" } else { this.nexBtn.style.display = "none" } // show the close button if (this.index == this.pages.length - 1) { this.nexBtn.style.display = "none" this.doneBtn.style.display = "block" } else { this.doneBtn.style.display = "none" } // show the previous button if (this.index > 0 && this.pages.length > 1) { this.previousBtn.style.display = "block"; } else { this.previousBtn.style.display = "none"; } } } disableNextBtn() { this.nexBtn.setAttribute("disabled") } enableNextBtn() { this.nexBtn.removeAttribute("disabled") } /** * Display the next page. */ next() { if (this.index < this.pages.length - 1) { this.index++ this.nexBtn.style.display = "block" this.pagesDiv.style.transform = `translate(${this.index * this.width * -1}px)` } // show the close button if (this.index == this.pages.length - 1) { this.nexBtn.style.display = "none" this.doneBtn.style.display = "block" } // show the previous button if (this.pages.length > 1) { this.previousBtn.style.display = "block"; } // Now the steps button. for (var i = 0; i < this.pages.length; i++) { if (this.stepsButton[i].classList.contains("active") || this.stepsButton[i].classList.contains("disable")) { this.stepsButton[i].classList.remove("active") this.stepsButton[i].classList.add("disable") } } if (this.stepsButton.length > 0) { this.stepsButton[this.index].classList.add("active") // publish local event. if (!this.stepsButton[this.index].classList.contains("disable")) { Model.eventHub.publish("wizard_next_page_evt", { index: this.index, nextBtn: this.stepsButton[this.index] }, true) } } } previous() { if (this.index > 0) { this.index-- this.pagesDiv.style.transform = `translate(${this.index * this.width * -1}px)` } if (this.index == 0) { this.previousBtn.style.display = "none"; } if (this.pages.length > 1 && this.index < this.pages.length - 1) { this.nexBtn.style.display = "block"; this.doneBtn.style.display = "none" } else { this.doneBtn.style.display = "block" } for (var i = 0; i < this.pages.length; i++) { if (this.stepsButton[i].classList.contains("active") || this.stepsButton[i].classList.contains("disable")) { this.stepsButton[i].classList.remove("active") this.stepsButton[i].classList.add("disable") } } this.enableNextBtn() this.stepsButton[this.index].classList.add("active") } } customElements.define('globular-wizard', Wizard)