JavaScript/js/ui-utils/form.js
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
A helper class for building forms. |
*/ |
/** |
* The Form class which contains the properties 'el' (HTML element) and 'fields' (a map of name -> HTML input field). |
* @param id The id of the form element. |
* @constructor |
*/ |
CKCatalog.Form = function Form(id) { |
this.el = document.createElement('form'); |
this.el.setAttribute('action','#'); |
this.el.setAttribute('method','post'); |
this.el.id = id; |
this.table = this.el.appendChild(document.createElement('table')); |
var submitButton = document.createElement('input'); |
submitButton.setAttribute('type','submit'); |
submitButton.setAttribute('name','submit'); |
submitButton.style.display = 'none'; |
this.el.appendChild(submitButton); |
this.fields = []; |
this._multipleFields = 0; |
this._multipleFieldsContainer = null; |
}; |
/** |
* Sets the fields to follow to be wrapped inside a single row |
* @param {object} opts An object containing keys 'number' and 'hidden' (optional). |
*/ |
CKCatalog.Form.prototype.addMultipleFields = function(opts) { |
this._multipleFieldsContainer = this._createFieldContainer(opts); |
this._multipleFields = opts.number; |
return this; |
}; |
CKCatalog.Form.prototype._createRelativeId = function(name) { |
return this.el.id + '-' + name; |
}; |
CKCatalog.Form.prototype._createFieldContainer = function(opts) { |
if(this._multipleFields) { |
this._multipleFields--; |
return this._multipleFieldsContainer; |
} |
var tr = document.createElement('tr'); |
tr.className = 'field'; |
if(opts.hidden) { |
tr.classList.add('hide'); |
} |
if(opts.number) { |
tr.classList.add('multiple'); |
tr.classList.add('has-' + opts.number + '-fields'); |
} |
var labelContainer = document.createElement('th'); |
if(opts.label) { |
var label = document.createElement('label'); |
label.textContent = opts.label; |
if (opts.name) { |
label.setAttribute('for', this._createRelativeId(opts.name)); |
} |
labelContainer.appendChild(label); |
} |
tr.appendChild(labelContainer); |
var td = document.createElement('td'); |
return tr.appendChild(td); |
}; |
/** |
* Adds an email input field to the form object. |
* @param {object} opts An object containing keys 'name','placeholder','value','label','type','hidden' (optional). |
* @returns {CKCatalog.Form} |
*/ |
CKCatalog.Form.prototype.addInputField = function(opts) { |
var fieldContainer = this._createFieldContainer(opts); |
var inputContainer = document.createElement('div'); |
inputContainer.className = 'border'; |
var input = document.createElement('input'); |
input.setAttribute('type',opts.type); |
input.setAttribute('name',opts.name); |
input.setAttribute('placeholder',opts.placeholder); |
input.id = this._createRelativeId(opts.name); |
input.value = opts.value; |
this.fields[opts.name] = input; |
inputContainer.appendChild(input); |
fieldContainer.appendChild(inputContainer); |
this.table.appendChild(fieldContainer.parentNode); |
return this; |
}; |
/** |
* Adds a file input field that is stylable. |
* @param {object} opts An object with keys 'name', 'label', 'hidden' (optional). |
* @returns {CKCatalog.Form} |
*/ |
CKCatalog.Form.prototype.addFileInputField = function(opts) { |
var fieldContainer = this._createFieldContainer(opts); |
var inputContainer = document.createElement('div'); |
inputContainer.className = 'border'; |
var input = document.createElement('input'); |
input.setAttribute('type','file'); |
input.setAttribute('name',opts.name); |
input.id = this._createRelativeId(opts.name); |
var fakeInput = document.createElement('div'); |
fakeInput.className = 'fake-file-input'; |
var selectFileButton = document.createElement('button'); |
selectFileButton.className = 'link'; |
selectFileButton.textContent = 'Choose File…'; |
var span = document.createElement('span'); |
span.className = 'file-name'; |
input.addEventListener('change', function() { |
var file = input.files[0]; |
span.textContent = file ? file.name : ''; |
}); |
fakeInput.appendChild(selectFileButton); |
fakeInput.appendChild(span); |
inputContainer.appendChild(fakeInput); |
inputContainer.appendChild(input); |
fieldContainer.appendChild(inputContainer); |
this.fields[opts.name] = input; |
this.table.appendChild(fieldContainer.parentNode); |
return this; |
}; |
/** |
* Adds a select dropdown field to the form object. |
* @param {object} opts An object containing keys 'name','options','label','hidden' (optional) |
* where options is an array of objects containing keys |
* 'title', 'value', and 'selected' (optional). |
* @returns {CKCatalog.Form} |
*/ |
CKCatalog.Form.prototype.addSelectField = function(opts) { |
var fieldContainer = this._createFieldContainer(opts); |
var selectContainer = document.createElement('div'); |
selectContainer.className = 'border select'; |
var select = document.createElement('select'); |
select.setAttribute('name',opts.name); |
select.id = this._createRelativeId(opts.name); |
opts.options.forEach(function(opt) { |
var option = document.createElement('option'); |
option.textContent = opt.title || opt.value; |
option.setAttribute('value',opt.value); |
if(opt.selected) { |
option.setAttribute('selected',''); |
} |
select.appendChild(option); |
}); |
this.fields[opts.name] = select; |
selectContainer.appendChild(select); |
fieldContainer.appendChild(selectContainer); |
this.table.appendChild(fieldContainer.parentNode); |
return this; |
}; |
/** |
* Adds a row of checkboxes. |
* @param {object} opts An object containing keys 'checkboxes', 'hidden' (optional) |
* where checkboxes is an array of objects containing keys |
* 'label','name','value','checked' (optional). |
* @returns {CKCatalog.Form} |
*/ |
CKCatalog.Form.prototype.addCheckboxes = function(opts) { |
var fieldContainer = this._createFieldContainer(opts); |
var checkboxesContainer = document.createElement('div'); |
checkboxesContainer.className = 'checkboxes'; |
var fields = this.fields; |
var that = this; |
opts.checkboxes.forEach(function(checkbox) { |
var checkboxContainer = document.createElement('div'); |
checkboxContainer.className = 'checkbox'; |
var label = document.createElement('label'); |
label.setAttribute('for',that._createRelativeId(checkbox.name)); |
label.textContent = checkbox.label; |
var input = document.createElement('input'); |
input.setAttribute('type','checkbox'); |
input.setAttribute('name',checkbox.name); |
input.setAttribute('value',checkbox.value); |
input.id = that._createRelativeId(checkbox.name); |
if(checkbox.checked) { |
input.setAttribute('checked',''); |
} |
fields[checkbox.name] = input; |
checkboxContainer.appendChild(label); |
checkboxContainer.appendChild(input); |
checkboxesContainer.appendChild(checkboxContainer); |
}); |
fieldContainer.appendChild(checkboxesContainer); |
this.table.appendChild(fieldContainer.parentNode); |
return this; |
}; |
/** |
* Attaches a submit handler to the form. |
* @param {function} handler |
*/ |
CKCatalog.Form.prototype.onSubmit = function(handler) { |
this.el.onsubmit = function(e) { |
e.preventDefault(); |
handler(); |
}; |
}; |
/** |
* Gets the row container element for an input field by name. |
* @param {string} fieldName |
* @returns {Node | null} |
*/ |
CKCatalog.Form.prototype.getFieldRowForFieldName = function(fieldName) { |
var field = this.fields[fieldName]; |
if(field) { |
var el = field; |
while(el.parentNode) { |
el = el.parentNode; |
if(el.classList.contains('field')) { |
return el; |
} |
} |
} |
return null; |
}; |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13