diff --git a/bulma.html b/bulma.html new file mode 100644 index 0000000..b9f0504 --- /dev/null +++ b/bulma.html @@ -0,0 +1,112 @@ + + + + LegalForm.js demo + + + + + + + + + + + + + + + + + + + +
+

LegalForm.js demo (Bulma)

+ +
+
+
+
+ +
+ +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/css/bulma.css b/css/bulma.css new file mode 100644 index 0000000..0a79e62 --- /dev/null +++ b/css/bulma.css @@ -0,0 +1,134 @@ +.field.has-addons { + flex-wrap: wrap; +} + +.field.has-addons > label { + width: 100%; +} + +label.label { + text-align: left; +} + +.datepicker .datepicker-body { + display: block; +} + +.datetimepicker { + z-index: 2; +} + +.radio, .checkbox { + display: block; +} + +.radio + .radio { + margin-left: 0; +} + +.field:last-child { + margin-bottom: .75rem; +} + +.datetimepicker-dummy .datetimepicker-dummy-wrapper { + background-color: #fff; + border-color: #dbdbdb; + border-radius: 4px; + color: #363636; + box-shadow: inset 0 .0625em .125em rgba(10,10,10,.05); +} + +.datetimepicker-dummy .datetimepicker-dummy-wrapper:hover { + border-color: #b5b5b5; +} + +.field.has-error input:not([type="checkbox"]), +.field.has-error select, +.field.has-error textarea { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); +} + +.field.has-error label.checkbox { + color: #a94442; +} + +.field { + position: relative; +} + +[data-tooltip].shown:not(.is-disabled)::before, +[data-tooltip].shown:not(.is-disabled)::after, +[data-tooltip].shown:not(.is-loading)::before, +[data-tooltip].shown:not(.is-loading)::after, +[data-tooltip].shown:not([disabled])::before, +[data-tooltip].shown:not([disabled])::after { + opacity: 1; + visibility: visible; +} + +[data-tooltip].shown:not(.is-disabled)::before, +[data-tooltip].shown:not(.is-loading)::before, +[data-tooltip].shown:not([disabled])::before { + background: rgb(0, 0, 0); + font-size: 14px; +} + +[data-tooltip].shown.has-tooltip-right:not(.is-disabled)::after, +[data-tooltip].shown.has-tooltip-right:not(.is-loading)::after, +[data-tooltip].shown.has-tooltip-right:not([disabled])::after { + border-color: transparent rgb(0, 0, 0) transparent transparent; +} + +[data-tooltip].shown.has-tooltip-left:not(.is-disabled)::after, +[data-tooltip].shown.has-tooltip-left:not(.is-loading)::after, +[data-tooltip].shown.has-tooltip-left:not([disabled])::after { + border-color: transparent transparent transparent rgb(0, 0, 0); +} + +.wizard [data-role="wrapper"] > .help { + font-size: 20px; + opacity: 0.7; +} + +.select.with-choices:not(.is-multiple):not(.is-loading)::after { + border: none; +} + +.choices__item, .choices__list--dropdown .choices__item { + font-size: 1rem; +} + +.choices__inner { + background-color: #fff; + height: 40px; + min-height: 40px; + padding-top: 1.5px; +} + +.choices__inner:hover { + border-color: #b5b5b5; +} + +.notification-fixed-top { + position: fixed; + top: 0; + left: 0; + z-index: 1035; + width: 100%; + margin: 0; + border-radius: 0; + border-width: 0 0 1px 0; +} + +@media (min-width: 992px) { + .notification-fixed-top { + left: 50%; + width: 992px; + margin-left: -496px; + border-width: 0 1px 1px 1px; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + } +} diff --git a/css/general.css b/css/general.css index 37fd490..c1be6ed 100644 --- a/css/general.css +++ b/css/general.css @@ -22,7 +22,7 @@ position: relative; } -.wizard .form-group > .help { +.wizard [data-role="wrapper"] > .help { display: block; margin-right: 4px; position: absolute; diff --git a/css/wizard.css b/css/wizard.css new file mode 100644 index 0000000..e5c420c --- /dev/null +++ b/css/wizard.css @@ -0,0 +1,45 @@ +.wizard { + position: relative; + overflow: hidden; + width: 100%; +} +.wizard > .wizard-step { + display: none; + position: relative; + -webkit-transition: 0.3s ease-in-out left; + -o-transition: 0.3s ease-in-out left; + transition: 0.3s ease-in-out left; +} +.wizard > .active, +.wizard > .next, +.wizard > .prev { + display: block; +} +.wizard > .active { + left: 0; +} +.wizard > .next, +.wizard > .prev { + position: absolute; + top: 0; + width: 100%; +} +.wizard > .next { + left: 100%; +} +.wizard > .prev { + left: -100%; +} +.wizard > .next.left, +.wizard > .prev.right { + left: 0; +} +.wizard > .active.left { + left: -100%; +} +.wizard > .active.right { + left: 100%; +} +.wizard-hide:not(.in) { + display: none; +} diff --git a/index.html b/index.html index 52973ac..35149d8 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ - + @@ -24,7 +24,7 @@
-

LegalForm.js demo

+

LegalForm.js demo (Bootstrap)

@@ -34,9 +34,9 @@

LegalForm.js demo

- - - + + +
@@ -45,13 +45,12 @@

LegalForm.js demo

- + - - + @@ -64,16 +63,13 @@

LegalForm.js demo

- - - - - - + + + @@ -83,7 +79,6 @@

LegalForm.js demo

- @@ -92,12 +87,16 @@

LegalForm.js demo

+ + + + @@ -106,6 +105,7 @@

LegalForm.js demo

+ diff --git a/js/demo/legalform.js b/js/demo/legalform.js index d81ec5e..37f9902 100644 --- a/js/demo/legalform.js +++ b/js/demo/legalform.js @@ -55,6 +55,26 @@ "max" : "", "validation" : "" }, + { + "type" : "amount", + "label" : "Number with unit multiple", + "name" : "number_with_unit_multiple", + "value" : "", + "optionValue" : [ + "unit", + "alt_unit" + ], + "optionText" : [ + "units", + "alt_units" + ], + "helptext" : "", + "conditions" : "", + "decimals" : "0", + "min" : "", + "max" : "", + "validation" : "" + }, { "type" : "money", "label" : "Amount", @@ -733,15 +753,17 @@ ] }; - var $wizard = $('.wizard'); - var variant = getVariant($wizard); - var builder = new LegalForm(variant); + var dom = new Dom(); + var wizard = dom.findOne('.wizard'); + var variant = getVariant(); + variant.setWizard(wizard.element); + var builder = new LegalForm(variant); var template = builder.build(legalform.definition); var options = builder.calc(legalform.definition); var ractive = new RactiveLegalForm({ - el: $wizard[0], + el: wizard.element, template: template, validation: new LegalFormValidation(), defaults: options.defaults, @@ -757,23 +779,27 @@ var helptext = builder.buildHelpText(legalform.definition); new Ractive({ - el: $('#doc-help')[0], + el: dom.findOne('#doc-help').element, template: helptext }); window.ractive = ractive; - function getVariant($wizard) { + function getVariant() { var page = document.location.pathname.match(/([^\/]+)\.html?/); var pageName = (page && page[1]) || 'index'; - var variants = { - 'index': BootstrapVariant, - 'live-contract': BootstrapVariant, - 'material': BootstrapMaterialVariant, - 'nomaterial': BootstrapMaterialVariant - }; + switch(pageName) { + case 'index': + case 'live-contract': + return new BootstrapVariant($); + case 'material': + case 'nomaterial': + return new BootstrapMaterialVariant($); + case 'bulma': + return new BulmaVariant(); + } - return new variants[pageName]($, $wizard[0]); + return null; } })(); diff --git a/js/dom/dom-element.js b/js/dom/dom-element.js index 5c0134b..b5314fd 100644 --- a/js/dom/dom-element.js +++ b/js/dom/dom-element.js @@ -62,9 +62,15 @@ function DomElement(element) { return this; } + DomElement.prototype.off = function(eventName) { + if (this.element) this.element.removeEventListener(eventName); + + return this; + } + DomElement.prototype.attr = function(name, value) { if (typeof value === 'undefined') { - return this.element ? this.element.getAttribute(name) : null; + return this.element ? this.element.getAttribute(name) : ''; } if (this.element) this.element.setAttribute(name, value); @@ -72,6 +78,14 @@ function DomElement(element) { return this; } + DomElement.prototype.removeAttr = function(name) { + if (this.element) { + this.element.removeAttribute(name); + } + + return this; + } + DomElement.prototype.prop = function(name, value) { if (typeof value === 'undefined') { return this.element ? this.element[name] : null; @@ -133,10 +147,6 @@ function DomElement(element) { return this.element ? this.element.validity.valid : true; } - DomElement.prototype.hasClass = function(className) { - return this.element ? this.element.classList.contains(className) : false; - } - DomElement.prototype.setCustomValidity = function(error) { if (this.element) { this.element.setCustomValidity(error); @@ -146,7 +156,20 @@ function DomElement(element) { } DomElement.prototype.is = function(selector) { - return this.element ? this.element.matches(selector) : false; + if (!this.element) return false; + if (typeof selector === 'string') return this.element.matches(selector); + return this.element === selector.element; + } + + DomElement.prototype.next = function(selector) { + if (!this.element) return null; + + var next = this.element; + while ((next = next.nextSibling) && next.nodeType !== 1) {} + + var valid = next && (typeof selector === 'undefined' || !selector || next.matches(selector)); + + return valid ? new DomElement(next) : null; } DomElement.prototype.nextAll = function(selector) { @@ -164,6 +187,17 @@ function DomElement(element) { return new DomList(result); } + DomElement.prototype.prev = function(selector) { + if (!this.element) return null; + + var prev = this.element; + while ((prev = prev.previousSibling) && prev.nodeType !== 1) {} + + var valid = prev && (typeof selector === 'undefined' || !selector || prev.matches(selector)); + + return valid ? new DomElement(prev) : null; + } + DomElement.prototype.prevAll = function(selector) { if (!this.element) return new DomList(null); @@ -179,6 +213,10 @@ function DomElement(element) { return new DomList(result); } + DomElement.prototype.hasClass = function(className) { + return this.element ? this.element.classList.contains(className) : false; + } + DomElement.prototype.addClass = function(className) { if (this.element) { this.element.classList.add(...arguments); @@ -195,6 +233,18 @@ function DomElement(element) { return this; } + DomElement.prototype.toggleClass = function(className, state) { + if (typeof state !== 'undefined') { + state ? this.addClass(className) : this.removeClass(className); + } else { + this.hasClass(className) ? + this.removeClass(className) : + this.addClass(className); + } + + return this; + } + DomElement.prototype.parent = function() { var parent = this.element ? this.element.parentElement : null; @@ -213,7 +263,13 @@ function DomElement(element) { if (!this.element) return this; var oldDisplay = this.attr('data-olddisplay'); - this.element.style.display = oldDisplay ? oldDisplay : ''; + if (typeof oldDisplay !== 'undefined' && oldDisplay) { + this.element.style.display = oldDisplay; + } + + if (!this.isVisible()) { + this.element.style.display = 'block'; + } } DomElement.prototype.hide = function() { @@ -227,6 +283,16 @@ function DomElement(element) { return this; } + //Getter only + DomElement.prototype.css = function(name) { + if (!this.element) return ''; + + var styles = getComputedStyle(this.element); + name = toCamelCase(name); + + return typeof styles[name] !== 'undefined' ? styles[name] : ''; + } + DomElement.prototype.index = function() { if (!this.element || !this.element.parentElement) return -1; @@ -266,9 +332,22 @@ function DomElement(element) { } } - DomElement.prototype.scrollTop = function(pos) { + DomElement.prototype.offset = function() { + if (!this.element) return {top: 0, left: 0}; + + var rect = this.element.getBoundingClientRect(); + + return { + top: rect.top + window.pageYOffset, + left: rect.left + window.pageXOffset + }; + } + + DomElement.prototype.scrollTop = function(pos, duration) { if (this.element) { - this.element.scrollTop = pos; + duration ? + animateScrollTop(this.element, pos, duration) : + this.element.scrollTop = pos; } return this; @@ -324,4 +403,30 @@ function DomElement(element) { this.element.getClientRects().length ); } + + DomElement.prototype.val = function(value) { + if (typeof value !== 'undefined') { + if (this.element) this.element.value = value; + + return this; + } + + return this.element ? this.element.value : ''; + } + + DomElement.prototype.focus = function(value) { + if (this.element) { + this.element.focus(); + } + + return this; + } + + DomElement.prototype.append = function(element) { + if (!this.element || !element.element) return this; + + this.element.appendChild(element.element); + + return this; + } } diff --git a/js/dom/dom-list.js b/js/dom/dom-list.js index 2587050..50a9309 100644 --- a/js/dom/dom-list.js +++ b/js/dom/dom-list.js @@ -117,6 +117,20 @@ function DomList(list) { return new DomList(matched); } + DomList.prototype.add = function(list) { + if (!list.list) return this; + if (!this.list) { + this.list = list.list; + return this; + } + + for (var i = 0; i < list.list.length; i++) { + this.list.push(list.list[i]); + } + + return this; + } + function init(list) { if (list instanceof NodeList) { list.forEach(function(item) { diff --git a/js/legalform-html.js b/js/legalform-html.js index a60e877..419add7 100644 --- a/js/legalform-html.js +++ b/js/legalform-html.js @@ -28,6 +28,29 @@ function LegalFormHtml(variant) { this.disableRequiredFields = false; this.variant = variant; + /** + * Obtain wizard buttons html, for using custom buttons labels + * @return {string} + */ + this.getWizardButtonsHtml = function() { + if (typeof document === 'undefined') return ''; + + var dom = new Dom(); + var buttonsTemplate = '.wizards-actions.template'; + var template = dom.findOne(buttonsTemplate); + + if (!template.element) { + var ractiveTemplate = dom.findOne('#ractive-template'); + if (!ractiveTemplate) return ''; + + var tempDiv = dom.create('div'); + tempDiv.html(ractiveTemplate.html()); + template = tempDiv.findOne(buttonsTemplate); + } + + return self.variant.setWizardButtonsClasses(template.html()); + } + /** * Build form html * @param {array} definition Form definition @@ -46,13 +69,18 @@ function LegalFormHtml(variant) { for (var i = 0; i < definition.length; i++) { var step = definition[i]; var anchor = self.model.getStepAnchor(step); - var buttonsHtml = getWizardButtonsHtml(); + var buttonsHtml = self.getWizardButtonsHtml(); var stepLines = []; stepLines.push('