123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- <!DOCTYPE HTML>
- <html lang="pt-BR">
- <head>
- <title>{title}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="author" content="LInE" />
- <link rel="stylesheet" href="../assets/foundation.min.css">
- <style>
- body {
- margin-left: 2rem;
- margin-right: 2rem;
- margin-top:1.5rem;
- }
- .rotulo {
- font-weight: bold;
- background-color: #e4f1fa;
- margin: 2px;
- }
- .required::before {
- content: '* ';
- color: red;
- }
- .condicional {
- visibility: hidden;
- }
- .page {
- display: none;
- }
- #btn_submit {
- display: none;
- }
- legend, #current_page, #max_page {
- font-weight: bold;
- }
- #current_page {
- font-family: monospace;
- font-size: 1rem;
- }
- </style>
- </head>
- <body>
- <div class="callout" >
- <p class="paragrafo lead text-justify">
- <span style="font-weight: bold;">{title}</span></br>{description}</br>
- <span class="required" style="color:red">Obrigatório</span>
- </p>
- </div>
- <div class="formulario">
- <form class="form" method="POST" action="../app/post.php">
- <input type="hidden" name="form" value="{form_id}" />
- <input type="hidden" name="uuid" value="" />
- <input type="hidden" name="page" value="1" />
- <input type="hidden" name="status" value="" />
- <div class="grid-container">
- <div class="grid-x grid-padding-x">
- <div class="large-5">
- Página <span id="current_page"></span> de <span id="max_page"></span>
- </div>
- {pages}
- <fieldset class="fieldset float-center">
- <button id="btn_back" class="button primary">Anterior</button>
- <button id="btn_next" class="button primary">Próximo</button>
- <button id="btn_submit" class="button success" type="submit">Finalizar</button>
- </fieldset>
- </div>
- </div>
- </form>
- </div>
- <script src="../assets/populatejs.min.js"></script>
- <script>
- (function () {
- const form = document.forms[0];
- const MAX_PAGE = document.querySelectorAll("fieldset.page").length;
- const KEY_NAME = form['form'].value;
- const STATUS = {
- PARTIAL: "PARTIAL",
- COMPLETED: "COMPLETED"
- }
- const btnBack = document.querySelector("#btn_back");
- const header = document.querySelector('.callout > p.paragrafo');
- const btnNext = document.querySelector("#btn_next");
- const btnSubmit = document.querySelector("#btn_submit");
- const currentPageSpan = document.querySelector("#current_page");
- const maxPageSpan = document.querySelector("#max_page");
- let page = 1;
- let isValid = false;
- const getLocalStorage = function () {
- const test = 'test';
- try {
- localStorage.setItem(test, test);
- localStorage.removeItem(test);
- return localStorage;
- } catch(e) {
- return {
- setItem: () => null,
- removeItem: () => null,
- getItem: () => null
- };
- }
- }
- const storePartialForm = function (formData) {
- const obj = {};
- formData.forEach((value, key) => {
- obj[key] = value;
- });
- getLocalStorage().setItem(KEY_NAME, JSON.stringify(obj));
- }
- const loadFromStorage = function () {
- const storage = getLocalStorage();
- const oldForm = storage.getItem(KEY_NAME);
- if (oldForm != null) {
- const formDict = JSON.parse(oldForm);
- populatejs(formDict);
- page = +formDict['page'];
- }
- }
- const sendPartialForm = function (formData) {
- const xhr = new XMLHttpRequest();
- xhr.open("POST", form.action);
- formData.set("status", STATUS.PARTIAL);
- xhr.send(formData);
- }
- const updateCurrentPageSpan = function () {
- currentPageSpan.innerHTML = page;
- form['page'].value = page;
- }
- const getPage = function (pageID) {
- const page = document.querySelector(`.page[data-page='${pageID}']`);
- return page;
- }
- const showPage = function (pageID) {
- const page = getPage(pageID);
- page.style.display = 'block';
- header.scrollIntoView({behavior: 'smooth', inline:'start'})
- }
- const hidePage = function (pageID) {
- const page = getPage(pageID);
- page.style.display = 'none';
- }
- const nextPage = function () {
- let next = page + 1;
- next = next > MAX_PAGE ? MAX_PAGE : next;
- hidePage(page);
- showPage(next);
- page = next;
- updateCurrentPageSpan()
- }
- const prevPage = function () {
- let last = page - 1;
- last = last < 1 ? 1 : last;
- hidePage(page);
- showPage(last);
- page = last;
- updateCurrentPageSpan()
- }
- // Manage back button
- btnBack.disabled = true;
- btnBack.addEventListener('click', function (event) {
- event.preventDefault();
- if (page === 1) {
- return;
- }
- prevPage();
- validateConditionals();
- validateFormPage();
- btnSubmit.style.display = 'none';
- btnNext.style.display = 'inline-block';
- if (page === 1)
- btnBack.disabled = true;
- })
- // Manage next button
- btnNext.disabled = true;
- btnNext.addEventListener('click', function (event) {
- event.preventDefault();
- if (!isValid) {
- return;
- } else if(page === MAX_PAGE) {
- btnNext.style.display = 'none';
- return;
- }
- nextPage();
- validateConditionals();
- validateFormPage();
- const formData = new FormData(form);
- sendPartialForm(formData);
- storePartialForm(formData);
- btnBack.disabled = false;
- if(page === MAX_PAGE) {
- btnSubmit.style.display = 'inline-block';
- btnNext.style.display = 'none';
- }
- });
- // validate form
- const validateFormPage = function () {
- const pageElement = getPage(page);
- const requiredList = Array.prototype.slice.call(pageElement.querySelectorAll('label.required'))
- .filter(e => {
- const style = window.getComputedStyle(e);
- return e.offsetParent != null && style.visibility != 'hidden';
- })
- .map(e => e.attributes.for.value);
- //requiredList.forEach(x => console.log(form[x]));
- isValid = !requiredList.some( field => {
- const value = form[field].value;
- return value == "" || value == null;
- });
- btnNext.disabled = !isValid;
- btnSubmit.disabled = !isValid;
- btnBack.disabled = page === 1;
- }
- // validate conditional fields
- const validateConditionals = function () {
- const pageElement = getPage(page);
- const conditionals = Array.prototype.slice.call(pageElement.querySelectorAll('.condicional'))
- .filter(e => {
- const style = window.getComputedStyle(e);
- return e.offsetParent != null;
- });
- //console.log(conditionals);
- conditionals.forEach(cond => {
- const field = cond.dataset.cond;
- const valuesList = cond.dataset.values.split("|");
- const value = form[field].value;
- const shouldEnable = valuesList.some( v => v == value);
- cond.style.visibility = shouldEnable ? 'visible' : 'hidden';
- });
- }
- // Hook document change event to validate the form and conditions
- document.addEventListener('change', () => {
- validateConditionals();
- validateFormPage();
- });
- // Intercept form submit
- form.addEventListener('submit' ,() => {
- getLocalStorage().removeItem(KEY_NAME);
- form["status"].value = STATUS.COMPLETED;
- });
- // set uuid
- const createUUID = function () {
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
- const r = Math.random() * 16 | 0;
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
- return v.toString(16);
- });
- }
- form['uuid'].value = createUUID();
- // set max page span
- maxPageSpan.innerHTML = MAX_PAGE;
- //load from stogage if available
- loadFromStorage();
- if(page === MAX_PAGE) {
- btnSubmit.style.display = 'inline-block';
- btnNext.style.display = 'none';
- }
- // Always show page 1
- showPage(page);
- updateCurrentPageSpan();
- validateConditionals();
- validateFormPage();
- })()
- </script>
- </body>
- </html>
|