This is an automated email from the git hooks/post-receive script. ross-guest pushed a commit to branch master in repository node-leaflet-formbuilder.
commit fbc16f67d1dfe400f6841aed47013cc46fbceaf5 Author: Ross Gammon <rossgam...@mail.dk> Date: Sat Feb 6 15:21:08 2016 +0100 Imported Upstream version 0.2.1 --- .eslintrc | 15 ++ .gitignore | 1 + Leaflet.FormBuilder.js | 464 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 29 ++++ package.json | 18 ++ 5 files changed, 527 insertions(+) diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..b63c9dd --- /dev/null +++ b/.eslintrc @@ -0,0 +1,15 @@ +{ + "env": { + "browser": true + }, + "rules": { + "quotes": "single", + "no-underscore-dangle": false, + "curly": false, + "consistent-return": false, + "new-cap": false, + "strict": "global", + "global-strict": 0 + }, + "globals": {L: true} +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c8f50f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +npm-debug.log diff --git a/Leaflet.FormBuilder.js b/Leaflet.FormBuilder.js new file mode 100644 index 0000000..2e32f08 --- /dev/null +++ b/Leaflet.FormBuilder.js @@ -0,0 +1,464 @@ + +L.FormBuilder = L.Class.extend({ + includes: [L.Mixin.Events], + + options: { + className: 'leaflet-form' + }, + + defaultOptions: { + // Eg.: + // name: {label: L._('name')}, + // description: {label: L._('description'), handler: 'Textarea'}, + // opacity: {label: L._('opacity'), helpText: L._('Opacity, from 0.1 to 1.0 (opaque).')}, + }, + + initialize: function (obj, fields, options) { + L.setOptions(this, options); + this.obj = obj; + this.form = L.DomUtil.create('form', this.options.className); + this.setFields(fields); + if (this.options.id) { + this.form.id = this.options.id; + } + if (this.options.className) { + L.DomUtil.addClass(this.form, this.options.className); + } + }, + + setFields: function (fields) { + this.fields = fields || []; + this.helpers = {}; + }, + + build: function () { + this.form.innerHTML = ''; + for (var idx in this.fields) { + this.buildField(this.fields[idx]); + } + return this.form; + }, + + buildField: function (field) { + // field can be either a string like "option.name" or a full definition array, + // like ['options.tilelayer.tms', {handler: 'CheckBox', helpText: 'TMS format'}] + var type, helper, options; + if (field instanceof Array) { + options = field[1] || {}; + field = field[0]; + } else { + options = this.defaultOptions[this.getName(field)] || {}; + } + type = options.handler || 'Input'; + if (typeof type === "string" && L.FormBuilder[type]) { + helper = new L.FormBuilder[type](this, field, options); + } else { + helper = new type(this, field, options); + } + this.helpers[field] = helper; + this.on('postsync', this.onPostSync); + return helper; + }, + + getter: function (field) { + var path = field.split('.'), + value = this.obj; + for (var i = 0, l = path.length; i < l; i++) { + value = value[path[i]]; + } + return value; + }, + + setter: function (field, value) { + var path = field.split('.'), + obj = this.obj, + what; + for (var i = 0, l = path.length; i < l; i++) { + what = path[i]; + if (what === path[l - 1]) { + if (typeof value === 'undefined') { + delete obj[what]; + } else { + obj[what] = value; + } + } else { + obj = obj[what]; + } + } + }, + + resetField: function (field) { + var backup = this.backup[field], + input = this.inputs[field]; + input.value = backup; + this.setter(field, backup); + }, + + getName: function (field) { + var fieldEls = field.split('.'); + return fieldEls[fieldEls.length - 1]; + }, + + fetchAll: function () { + for (var key in this.helpers) { + if (this.helpers.hasOwnProperty(key)) { + this.helpers[key].fetch(); + } + } + }, + + syncAll: function () { + for (var key in this.helpers) { + if (this.helpers.hasOwnProperty(key)) { + this.helpers[key].sync(); + } + } + }, + + onPostSync: function (e) { + if (e.helper.options.callback) { + e.helper.options.callback.call(e.helper.options.callbackContext || this.obj, e); + } + if (this.options.callback) { + this.options.callback.call(this.options.callbackContext || this.obj, e); + } + } + +}); + +L.FormBuilder.Element = L.Class.extend({ + includes: [L.Mixin.Events], + + initialize: function (builder, field, options) { + this.builder = builder; + this.obj = this.builder.obj; + this.form = this.builder.form; + this.field = field; + this.options = options; + this.fieldEls = this.field.split('.'); + this.name = this.builder.getName(field); + this.parentNode = this.options.wrapper ? L.DomUtil.create(this.options.wrapper, this.options.wrapperClass || '', this.form) : this.form; + this.buildLabel(); + this.build(); + this.buildHelpText(); + this.fireAndForward('helper:init'); + }, + + fireAndForward: function (type, e) { + e = e || {}; + e.helper = this; + this.fire(type, e); + this.builder.fire(type, e); + if (this.obj.fire) this.obj.fire(type, e); + }, + + get: function () { + return this.builder.getter(this.field); + }, + + toHTML: function () { + return this.get(); + }, + + toJS: function () { + return this.value(); + }, + + sync: function () { + this.fireAndForward('presync'); + this.set(); + this.fireAndForward('postsync'); + }, + + set: function () { + this.builder.setter(this.field, this.toJS()); + }, + + buildLabel: function () { + if (this.options.label) { + this.label = L.DomUtil.create('label', '', this.parentNode); + this.label.innerHTML = this.options.label; + } + }, + + buildHelpText: function () { + if (this.options.helpText) { + var container = L.DomUtil.create('small', 'help-text', this.parentNode); + container.innerHTML = this.options.helpText; + } + }, + + fetch: function () {}, + + finish: function () { + this.fireAndForward('finish'); + } + +}); + +L.FormBuilder.Textarea = L.FormBuilder.Element.extend({ + + build: function () { + this.input = L.DomUtil.create('textarea', this.options.className || '', this.parentNode); + if (this.options.placeholder) { + this.input.placeholder = this.options.placeholder; + } + this.fetch(); + L.DomEvent.on(this.input, 'input', this.sync, this); + L.DomEvent.on(this.input, 'keypress', this.onKeyPress, this); + }, + + fetch: function () { + var value = this.backup = this.toHTML(); + if (value) { + this.input.value = value; + } + }, + + value: function () { + return this.input.value; + }, + + onKeyPress: function (e) { + var key = e.keyCode, + ENTER = 13; + if (key === ENTER && (e.shiftKey || e.ctrlKey)) { + L.DomEvent.stop(e); + this.finish(); + } + } + +}); + +L.FormBuilder.Input = L.FormBuilder.Element.extend({ + + build: function () { + this.input = L.DomUtil.create('input', this.options.className || '', this.parentNode); + this.input.type = this.type(); + this.input.name = this.name; + this.input._helper = this; + this.fetch(); + if (this.options.placeholder) { + this.input.placeholder = this.options.placeholder; + } + if (this.options.min !== undefined) { + this.input.min = this.options.min; + } + if (this.options.max !== undefined) { + this.input.max = this.options.max; + } + if (this.options.step) { + this.input.step = this.options.step; + } + L.DomEvent.on(this.input, this.getSyncEvent(), this.sync, this); + L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this); + }, + + fetch: function () { + this.input.value = this.backup = (typeof this.toHTML() !== 'undefined' ? this.toHTML() : null); + }, + + getSyncEvent: function () { + return 'input'; + }, + + type: function () { + return 'text'; + }, + + value: function () { + return this.input.value || undefined; + }, + + onKeyDown: function (e) { + var key = e.keyCode, + ENTER = 13; + if (key === ENTER) { + L.DomEvent.stop(e); + this.finish(); + } + } + +}); + +L.FormBuilder.BlurInput = L.FormBuilder.Input.extend({ + + getSyncEvent: function () { + return 'blur'; + }, + + finish: function () { + this.sync(); + L.FormBuilder.Input.prototype.finish.call(this); + }, + + sync: function () { + if (this.backup !== this.value()) { + L.FormBuilder.Input.prototype.sync.call(this); + } + } + +}); + +L.FormBuilder.IntegerMixin = { + + value: function () { + return !isNaN(this.input.value) && this.input.value !== '' ? parseInt(this.input.value, 10): undefined; + }, + + type: function () { + return 'number'; + } + +}; + +L.FormBuilder.IntInput = L.FormBuilder.Input.extend({ + includes: [L.FormBuilder.IntegerMixin] +}); + + +L.FormBuilder.BlurIntInput = L.FormBuilder.BlurInput.extend({ + includes: [L.FormBuilder.IntegerMixin] +}); + + +L.FormBuilder.FloatMixin = { + + value: function () { + return !isNaN(this.input.value) && this.input.value !== '' ? parseFloat(this.input.value): undefined; + }, + + type: function () { + return 'number'; + } + +}; + +L.FormBuilder.FloatInput = L.FormBuilder.Input.extend({ + includes: [L.FormBuilder.FloatMixin] +}); + +L.FormBuilder.BlurFloatInput = L.FormBuilder.BlurInput.extend({ + includes: [L.FormBuilder.FloatMixin] +}); + +L.FormBuilder.CheckBox = L.FormBuilder.Element.extend({ + + build: function () { + var container = L.DomUtil.create('div', 'formbox', this.parentNode); + this.input = L.DomUtil.create('input', this.options.className || '', container); + this.input.type = 'checkbox'; + this.input.name = this.name; + this.input._helper = this; + this.fetch(); + L.DomEvent.on(this.input, 'change', this.sync, this); + }, + + fetch: function () { + this.backup = this.toHTML(); + this.input.checked = this.backup === true; + }, + + value: function () { + return this.input.checked; + }, + + toHTML: function () { + return [1, true].indexOf(this.get()) !== -1; + } + +}); + +L.FormBuilder.Select = L.FormBuilder.Element.extend({ + + selectOptions: [ + ['value', 'label'] + ], + + build: function () { + this.select = L.DomUtil.create('select', '', this.parentNode); + this.select.name = this.name; + this.validValues = []; + this.buildOptions(); + L.DomEvent.on(this.select, 'change', this.sync, this); + }, + + getOptions: function () { + return this.options.selectOptions || this.selectOptions; + }, + + fetch: function () { + this.buildOptions(); + }, + + buildOptions: function () { + this.select.innerHTML = ''; + var options = this.getOptions(); + for (var i = 0, l = options.length; i < l; i++) { + this.buildOption(options[i][0], options[i][1]); + } + }, + + buildOption: function (value, label) { + this.validValues.push(value); + var option = L.DomUtil.create('option', '', this.select); + option.value = value; + option.innerHTML = label; + if (this.toHTML() === value) { + option.selected = 'selected'; + } + }, + + value: function () { + return this.select[this.select.selectedIndex].value; + }, + + getDefault: function () { + return this.getOptions()[0][0]; + }, + + toJS: function () { + var value = this.value(); + if (this.validValues.indexOf(value) !== -1) { + return value; + } else { + return this.getDefault(); + } + } + + +}); + +L.FormBuilder.IntSelect = L.FormBuilder.Select.extend({ + + value: function () { + return parseInt(L.FormBuilder.Select.prototype.value.apply(this), 10); + } + +}); + +L.FormBuilder.NullableBoolean = L.FormBuilder.Select.extend({ + selectOptions: [ + [undefined, 'inherit'], + [true, 'yes'], + [false, 'no'] + ], + + toJS: function () { + var value = this.value(); + switch (value) { + case 'true': + case true: + value = true; + break; + case 'false': + case false: + value = false; + break; + default: + value = undefined; + } + return value; + } + +}); diff --git a/README.md b/README.md new file mode 100644 index 0000000..f1517a3 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Leaflet.FormBuilder + +Helpers to build forms synchronized with Leaflet objects. + + +# Usage + +``` +var tilelayerFields = [ + ['options.tilelayer.name', {handler: 'BlurInput', placeholder: 'display name'}], + ['options.tilelayer.url_template', {handler: 'BlurInput', helpText: 'Supported scheme: http://{s}.domain.com/{z}/{x}/{y}.png', placeholder: 'url'}], + ['options.tilelayer.maxZoom', {handler: 'BlurIntInput', placeholder: 'max zoom'}], + ['options.tilelayer.minZoom', {handler: 'BlurIntInput', placeholder: 'min zoom'}], + ['options.tilelayer.attribution', {handler: 'BlurInput', placeholder: 'attribution'}], + ['options.tilelayer.tms', {handler: 'CheckBox', helpText: 'TMS format'}] +]; +var builder = new L.FormBuilder(myObject, tilelayerFields, { + callback: myCallback, + callbackContext: this +}); +myContainer.appendChild(builder.build()); +``` + + +See more examples of usage: + +- https://github.com/yohanboniface/Leaflet.Storage/blob/master/src/js/leaflet.storage.forms.js +- https://github.com/kosmtik/kosmtik/blob/master/src/front/FormBuilder.js +- https://github.com/kosmtik/kosmtik/blob/master/src/front/Core.js#L102-L114 diff --git a/package.json b/package.json new file mode 100644 index 0000000..06cde4a --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "leaflet-formbuilder", + "version": "0.2.1", + "description": "Helpers to build forms in Leaflet", + "main": "Leaflet.FormBuilder.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "leaflet" + ], + "repository": { + "type": "git", + "url": "git://github.com/yohanboniface/Leaflet.FormBuilder.git" + }, + "author": "Yohan Boniface", + "license": "WTFPL" +} -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/node-leaflet-formbuilder.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel