start of new forms implementation

This commit is contained in:
Gert
2015-06-01 21:22:56 +02:00
parent 06e8514365
commit 9971ec0291
28 changed files with 888 additions and 448 deletions

View File

@@ -583,13 +583,13 @@ form .switch-toggle label {
cursor: pointer; } cursor: pointer; }
form .switch-toggle a, form .switch-toggle label { form .switch-toggle a, form .switch-toggle label {
outline: none !important; } outline: none !important; }
form .dynfields input[type=text] { form .dynfields input[type=text], form [data-grav-field="array"] input[type=text] {
width: 40%; width: 40%;
float: left; float: left;
margin: 0 5px 5px 0; } margin: 0 5px 5px 0; }
form .dynfields .form-row { form .dynfields .form-row, form [data-grav-field="array"] .form-row {
display: inline-block; } display: inline-block; }
form .dynfields .form-row span { form .dynfields .form-row span, form [data-grav-field="array"] .form-row span {
padding: 0.5rem; padding: 0.5rem;
display: inline-block; display: inline-block;
line-height: 1.7; line-height: 1.7;

File diff suppressed because one or more lines are too long

View File

@@ -5,33 +5,33 @@ $(function () {
}); });
}; };
// selectize // // selectize
$('select.fancy:not(.create)').selectize({ // $('select.fancy:not(.create)').selectize({
createOnBlur: true, // createOnBlur: true,
}); // });
// selectize with create // // selectize with create
$('select.fancy.create').selectize({ // $('select.fancy.create').selectize({
createOnBlur: true, // createOnBlur: true,
persist: false, // persist: false,
create: function (input) { // create: function (input) {
return { // return {
value: input, // value: input,
text: input // text: input
} // }
} // }
}); // });
$('input.fancy').selectize({ // $('input.fancy').selectize({
delimiter: ',', // delimiter: ',',
persist: false, // persist: false,
create: function (input) { // create: function (input) {
return { // return {
value: input, // value: input,
text: input // text: input
} // }
} // }
}); // });
// Set Toastr defaults // Set Toastr defaults
toastr.options = { toastr.options = {

View File

@@ -1,193 +0,0 @@
(function($){
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
var GROUP = -1;
var DynFields2 = {
init: function () {
var container = $('[data-grav-array]'), blockParent, options;
DynFields2.container = container;
container.parent().on('click', '[data-grav-addfield]', DynFields2.addField.bind(DynFields2));
container.on('click', '[data-grav-remfield]', DynFields2.remField.bind(DynFields2));
$.each(DynFields2.container, function(index, block){
block = $(block);
blockParent = $(block.parents('.grav-array'));
options = DynFields2.getOptions(block);
if (options && options.sortable_root){
blockParent.nestable({
rootClass: 'grav-array',
handleClass: 'dd-root-handle',
maxDepth: 1,
expandBtnHTML: false,
collapseBtnHTML: false,
group: ++GROUP
});
blockParent.on('change', function(){
DynFields2.updateNames(block);
});
} else {
block.find('.dd-root-handle').remove();
}
if (options && options.sortable_children){
$.each(block.find('.dd3-content'), function(index, content){
DynFields2.makeSortable(content);
});
} else {
block.find('.dd3-content .dd-grav-handle').remove();
}
});
},
getOptions: function(container){
var data = container.data('grav-array'),
options;
$.each(data, function(name, values){
options = values.options;
});
return options;
},
getSchema: function(container){
var data = container.data('grav-array'),
schema;
$.each(data, function(name, values){
schema = values.schema;
});
return schema;
},
addField: function(event){
var element = $(event.target),
location = 'insertAfter',
container = element.parents('[data-grav-array]'),
parents = element.parents('li');
if (!container.length) {
container = element.next('[data-grav-array]');
location = 'appendTo';
}
if (!parents.length) parents = container.last();
var schema = DynFields2.buildSchema(container),
li = $('<li class="dd-item dd3-item" />').html(schema)[location](parents);
DynFields2.updateNames(container);
DynFields2.makeSortable(li.find('.dd3-content'));
},
remField: function(event){
var element = $(event.target),
container = element.parents('[data-grav-array]');
element.parents('li').remove();
DynFields2.updateNames(container);
},
updateNames: function(container){
var items, name;
$.each(container.children(), function(index, item){
items = $(item).find('[name]');
$.each(items, function(key, input){
input = $(input);
input.attr('name', input.attr('name').replace(/\[\w\]/, '[' + index + ']'));
});
});
},
makeSortable: function(context){
context = $(context);
context.nestable({
maxDepth: 1,
expandBtnHTML: false,
collapseBtnHTML: false,
listClass: 'dd-grav-list',
itemClass: 'dd-grav-item',
rootClass: 'dd3-content',
handleClass: 'dd-grav-handle',
group: ++GROUP
});
context.on('change', function(){
DynFields2.updateNames(context.parents('[data-grav-array]'));
});
},
buildSchema: function(container){
var data = container.data('grav-array'),
options = DynFields2.getOptions(container),
html = [],
input = '',
inputName = '',
index;
if (options && options.sortable_root) html.push(' <div class="dd-handle dd3-handle dd-root-handle"></div>');
html.push(' <div class="dd-grav-actions">');
html.push(' <span data-grav-remfield class="button fa fa-minus"></span>');
html.push(' <span data-grav-addfield class="button fa fa-plus"></span></span>');
html.push(' </div>');
html.push(' <ol class="dd3-content dd-grav-list">');
$.each(DynFields2.getSchema(container), function(key, value){
html.push('<li class="dd-grav-item">');
if (options && options.sortable_children) html.push(' <div class="dd-handle dd3-handle dd-grav-handle"></div>');
html.push(' <span class="label">' + (value.label || key.capitalize()) + '</span>');
inputName = name + '[X]' + '[' + key + ']';
switch(value.type || 'input'){
case 'text': case 'hidden':
input = '<input type="' + (value.type || 'input') + '" placeholder="' + (value.placeholder || '') + '" name="' + inputName + '" />';
break;
case 'textarea':
input = '<textarea placeholder="' + (value.placeholder || '') + '" name="' + inputName + '"></textarea>';
break;
case 'select':
input = '<select name="' + inputName + '">';
$.each(value.options || [], function(sValue, sLabel){
input += '<option value="' + sValue + '">' + sLabel + '</option>';
});
input += '</select>';
break;
case 'radio':
input = '';
index = 0;
$.each(value.options || [], function(sValue, sLabel){
input += '<label>';
input += ' <input type="' + value.type + '" name="' + inputName + '" value="' + sValue + '" ' + (!index ? 'checked' : '') + '/> ';
input += sLabel;
input += '</label> ';
index++;
});
break;
}
html.push(input);
html.push('</li>');
});
html.push(' </ol>');
return html.join("\n");
}
};
$(DynFields2.init);
})(jQuery);

View File

@@ -1,42 +0,0 @@
(function($){
var DynFields = {
init: function () {
var container = $('[data-grav-dynfields]');
DynFields.container = container;
container.on('click', '[data-grav-addfield]', DynFields.addField.bind(DynFields));
container.on('click', '[data-grav-remfield]', DynFields.remField.bind(DynFields));
container.on('keyup', 'input:not([name])', DynFields.updateFields.bind(DynFields));
},
addField: function (event, element) {
element = $(event.target);
this.container = element.closest('[data-grav-dynfields]');
var div = $('<div class="form-row" />').html(this.layout());
div.insertAfter(element.parent('div'));
},
remField: function (event, element) {
element = $(event.target);
element.parent('div').remove();
},
updateFields: function (event, element) {
element = $(event.target);
var sibling = element.next();
sibling.attr('name', this.getName() + '[' + element.val() + ']');
},
getName: function () {
return this.container.data('grav-dynfields') || 'generic';
},
layout: function () {
var name = this.getName(),
placeholder = {
key: this.container.data('grav-dynfields-key') || 'Key',
val: this.container.data('grav-dynfields-value') || 'Value'
};
return '' + ' <input type="text" value="" placeholder="' + placeholder.key + '" />' + ' <input type="text" name="' + name + '[]" value="" placeholder="' + placeholder.val + '" />' + ' <span data-grav-remfield class="fa fa-minus"></span> <span data-grav-addfield class="fa fa-plus"></span>' + '';
}
};
$(DynFields.init);
})(jQuery);

View File

@@ -1 +0,0 @@
!function(a){var b={init:function(){var c=a("[data-grav-dynfields]");b.container=c,c.on("click","[data-grav-addfield]",b.addField.bind(b)),c.on("click","[data-grav-remfield]",b.remField.bind(b)),c.on("keyup","input:not([name])",b.updateFields.bind(b))},addField:function(b,c){c=a(b.target),this.container=c.closest("[data-grav-dynfields]");var d=a('<div class="form-row" />').html(this.layout());d.insertAfter(c.parent("div"))},remField:function(b,c){c=a(b.target),c.parent("div").remove()},updateFields:function(b,c){c=a(b.target);var d=c.next();d.attr("name",this.getName()+"["+c.val()+"]")},getName:function(){return this.container.data("grav-dynfields")||"generic"},layout:function(){var a=this.getName(),b={key:this.container.data("grav-dynfields-key")||"Key",val:this.container.data("grav-dynfields-value")||"Value"};return' <input type="text" value="" placeholder="'+b.key+'" />'+' <input type="text" name="'+a+'[]" value="" placeholder="'+b.val+'" />'+' <span data-grav-remfield class="fa fa-minus"></span> <span data-grav-addfield class="fa fa-plus"></span>'}};a(b.init)}(jQuery);

20
themes/grav/js/forms.js Normal file
View File

@@ -0,0 +1,20 @@
$(function () {
if (typeof window.GravJS === 'undefined' || !window.GravJS.Form) {
console.warn('Dependencies for Grav Forms are not loaded.');
return;
}
// Register all FormFields that were loaded
if (typeof window.GravJS.FormFields === 'object') {
for (var key in window.GravJS.FormFields) { if (window.GravJS.FormFields.hasOwnProperty(key)) {
GravJS.Form.registerFactory(GravJS.FormFields[key]);
}
}
}
window.formInstances = [];
$('[data-grav-form]').each(function () {
window.formInstances.push(new GravJS.Form($(this)));
})
});

View File

@@ -0,0 +1,116 @@
(function () {
var root = window || {};
root = root.GravJS = root.GravJS || {};
root = root.FormFields = root.FormFields || {};
var ArrayField = function (el, form) {
el = $(el);
this.el = el.is('[' + form.fieldIndicator + ']') ? el : el.closest('[' + form.fieldIndicator + ']');
this.el.on('click', '[data-grav-array-action="add"]', this.add.bind(this));
this.el.on('click', '[data-grav-array-action="rem"]', this.remove.bind(this));
this.el.on('keyup', '[data-grav-array-type="key"]', this.update.bind(this));
};
ArrayField.getName = function () {
return 'array';
};
ArrayField.getTypes = function () {
return [ 'array' ];
};
ArrayField.prototype.valid = function() {
return true;
};
ArrayField.prototype.disabled = function() {
return false;
};
ArrayField.prototype.name = function(name) {
if (name) {
this.el.data('grav-array-name', name);
return name;
}
return this.el.data('grav-array-name')
};
ArrayField.prototype.value = function(val) {
if (typeof val === 'object') {
// Remove old
this.el.find('[data-grav-array-type="row"]').remove();
var container = this.el.find('[data-grav-array-type="container"]');
for (var key in val) { if (val.hasOwnProperty(key)) {
container.append(this._getNewField(key, val[key]));
}
}
return val;
}
var values = {};
this.el.find('[data-grav-array-type="value"]').each(function () {
var key = $(this).attr('name'),
value = $(this).val();
values[key] = value;
});
return values;
};
ArrayField.prototype.reset = function() {
this.value('');
};
ArrayField.prototype.formValues = function() {
var values = this.value(),
name = this.name(),
formValues = {};
for (var key in values) { if (values.hasOwnProperty(key)) {
formValues[name + '[' + key + ']'] = values[key];
}
}
return formValues;
};
ArrayField.prototype.add = function() {
$(this._getNewField()).insertAfter($(event.target).closest('[data-grav-array-type="row"]'));
};
ArrayField.prototype.remove = function() {
$(event.target).closest('[data-grav-array-type="row"]').remove();
};
ArrayField.prototype.update = function() {
var keyField = $(event.target),
valueField = keyField.closest('[data-grav-array-type="row"]').find('[data-grav-array-type="value"]');
valueField.attr('name', keyField.val());
};
ArrayField.prototype._getNewField = function(key, value) {
var name = this.name(),
placeholder = {
key: this.el.data('grav-array-keyname') || 'Key',
val: this.el.data('grav-array-valuename') || 'Value'
};
key = key || '';
value = value || '';
return '<div class="form-row" data-grav-array-type="row">' +
'<input data-grav-array-type="key" type="text" value="' + key + '" placeholder="' + placeholder.key + '" />' +
'<input data-grav-array-type="value" type="text" name="' + key + '" value="' + value + '" placeholder="' + placeholder.val + '" />' +
'<span data-grav-array-action="rem" class="fa fa-minus"></span>' +
'<span data-grav-array-action="add" class="fa fa-plus"></span>' +
'</div>';
};
root.Array = ArrayField;
})();

View File

@@ -0,0 +1,99 @@
(function () {
var root = window || {};
root = root.GravJS = root.GravJS || {};
root = root.FormFields = root.FormFields || {};
var CheckboxesField = function (el, form) {
el = $(el);
this.el = el.is('[' + form.fieldIndicator + ']') ? el : el.closest('[' + form.fieldIndicator + ']');
this.keys = this.el.data('grav-keys') || false;
this._disabled = this.el.data('grav-disabled') || false;
this._default = this.el.data('grav-default') || '';
};
CheckboxesField.getName = function () {
return 'checkboxes';
};
CheckboxesField.getTypes = function () {
return [ 'checkboxes' ];
};
CheckboxesField.prototype.valid = function() {
return true;
};
CheckboxesField.prototype.disabled = function(state) {
if (typeof state !== 'undefined') {
this._disabled = state ? true : false;
}
return this._disabled;
};
CheckboxesField.prototype.name = function(name) {
if (name) {
this.el.data('grav-field-name', name);
return name;
}
return this.el.data('grav-field-name')
};
CheckboxesField.prototype.value = function(val) {
var useKeys = this.keys,
values = useKeys ? {} : [];
if (typeof val !== 'undefined') {
this.el.find('input').each(function () {
var checked = false;
if (useKeys && typeof val[$(this).attr('name')] !== 'undefined') {
checked = val[$(this).attr('name')];
} else if (!useKeys && val.indexOf($(this).val()) !== -1) {
checked = true;
}
$(this).prop('checked', checked);
});
return val;
}
this.el.find('input').each(function () {
if (useKeys) {
values[$(this).attr('name')] = $(this).is(':checked');
} else if ($(this).is(':checked')) {
values.push($(this).val());
}
});
return values;
};
CheckboxesField.prototype.reset = function() {
this.value(this._default);
};
CheckboxesField.prototype.formValues = function() {
var values = this.value(),
name = this.name(),
formValues = {};
for (var key in values) { if (values.hasOwnProperty(key)) {
formValues[name + '[' + key + ']'] = values[key] ? '1' : '0';
}
}
return formValues;
};
CheckboxesField.prototype.onChange = function(eh) {
var self = this;
this.el.find('input').on('change', function () { eh.call(self, self.value()); });
};
root.Checkboxes = CheckboxesField;
})();

View File

@@ -0,0 +1,73 @@
(function () {
var root = window || {};
root = root.GravJS = root.GravJS || {};
root = root.FormFields = root.FormFields || {};
var Input = function (el, form) {
el = $(el);
var parent = el.is('[' + form.fieldIndicator + ']') ? el : el.closest('[' + form.fieldIndicator + ']'),
input = parent.prop('tagName').toUpperCase() === 'INPUT' ? parent : parent.find('input'),
type = parent.data(form.fieldIndicator);
this.el = parent;
this.input = input;
this._disabled = parent.data('grav-disabled') || false;
this._default = parent.data('grav-default') || '';
};
Input.getName = function () {
return 'input';
};
Input.getTypes = function () {
return [ 'text', 'hidden' ];
};
Input.prototype.valid = function() {
return true;
};
Input.prototype.disabled = function(state) {
if (typeof state !== 'undefined') {
this._disabled = state ? true : false;
}
return this._disabled;
};
Input.prototype.name = function(name) {
if (name) {
this.input.attr('name', name);
return name;
}
return this.input.attr('name')
};
Input.prototype.value = function(val) {
if (typeof val !== 'undefined') {
this.input.val(val);
}
return this.input.val();
};
Input.prototype.reset = function() {
this.value(this._default);
};
Input.prototype.formValues = function() {
var o = {};
o[this.name()] = this.value();
return o;
};
Input.prototype.onChange = function(eh) {
var self = this;
this.input.on('keyup', function () { eh.call(self, self.value()); });
};
root.Input = Input;
})();

View File

@@ -0,0 +1,71 @@
(function () {
var root = window || {};
root = root.GravJS = root.GravJS || {};
root = root.FormFields = root.FormFields || {};
var SelectizeField = function (el, form) {
el = $(el);
var parent = el.is('[' + form.fieldIndicator + ']') ? el : el.closest('[' + form.fieldIndicator + ']'),
tagName = parent.data('grav-field').toLowerCase() === 'select' ? 'SELECT' : 'INPUT',
input = parent.prop('tagName').toUpperCase() === tagName ? parent : parent.find(tagName),
type = parent.data(form.fieldIndicator);
input.selectize(parent.data('grav-selectize'));
this.el = parent;
this.input = input;
this.selectize = input[0].selectize;
};
SelectizeField.getName = function () {
return 'selectize';
};
SelectizeField.getTypes = function () {
return [ 'selectize', 'select' ];
};
SelectizeField.prototype.valid = function() {
return true;
};
SelectizeField.prototype.disabled = function() {
return false;
};
SelectizeField.prototype.name = function(name) {
if (name) {
this.input.attr('name', name);
return name;
}
return this.input.attr('name')
};
SelectizeField.prototype.value = function(val) {
if (typeof val !== 'undefined') {
val = typeof val === 'string' ? val.length ? val.split(',') : [] : val;
for (var i = val.length - 1; i >= 0; i--) {
this.selectize.addOption({ text: val[i], value: val[i] });
}
this.selectize.setValue(val);
}
return this.selectize.items;
};
SelectizeField.prototype.reset = function() {
this.value('');
};
SelectizeField.prototype.formValues = function() {
var o = {};
o[this.name()] = this.value().join(',');
return o;
};
root.Selectize = SelectizeField;
})();

View File

@@ -0,0 +1,56 @@
(function () {
var root = window || {};
root = root.GravJS = root.GravJS || {};
root = root.FormFields = root.FormFields || {};
var ToggleField = function (el, form) {
el = $(el);
this.el = el.is('[' + form.fieldIndicator + ']') ? el : el.closest('[' + form.fieldIndicator + ']');
};
ToggleField.getName = function () {
return 'toggle';
};
ToggleField.getTypes = function () {
return [ 'toggle' ];
};
ToggleField.prototype.valid = function() {
return true;
};
ToggleField.prototype.disabled = function() {
return false;
};
ToggleField.prototype.name = function(name) {
if (name) {
this.el.find('input').attr('name', name);
return name;
}
return this.el.find('input').attr('name');
};
ToggleField.prototype.value = function(val) {
if (typeof val !== 'undefined') {
this.el.find('input').prop('checked', false).filter('[value="' + val + '"]').prop('checked', true);
return val;
}
return this.el.find('input:checked').val();
};
ToggleField.prototype.reset = function() {
this.value('');
};
ToggleField.prototype.formValues = function() {
var o = {};
o[this.name()] = this.value();
return o;
};
root.Toggle = ToggleField;
})();

View File

@@ -0,0 +1,209 @@
(function () {
var root = window || {};
root = root.GravJS = root.GravJS || {};
function addTypes (form, factory) {
var name = factory.getName(),
types = factory.getTypes();
for (var i = types.length - 1; i >= 0; i--) {
form.types[types[i]] = name;
if (form.scanned) {
scan(form, type);
}
}
}
function scan (form, type) {
for (var i = form.elements.length - 1; i >= 0; i--) {
if (!type || form.elements[i].type === type) {
form.elements.splice(i, 1);
}
}
if (Object.keys(form.types).length === 0 || (type && !form.types[type])) {
return;
}
form.findElements().each(function () {
var el = $(this),
type = el.data(form.dataIndicator);
if (form.types[type]) {
var factory = form.factories[form.types[type]],
element = new factory(el, form),
name = element.name();
if (typeof form.toggleables[name] !== 'undefined') {
linkToggle(element, form.toggleables[name]);
delete form.toggleables[name];
}
el.data('grav-field-instance', element);
form.elements.push({ type: type, element: element });
}
});
}
function scanToggleable (form) {
form.toggleables = {};
form.findElements('toggleable').each(function () {
var el = $(this);
form.toggleables[el.data('grav-field-name')] = el;
});
}
function linkToggle (element, toggleable) {
element.onChange(function (value) {
toggleable.find('input').prop('checked', false).filter('[value=1]').prop('checked', true);
element.disabled(false);
});
toggleable.find('input').on('change', function () {
var el = $(this);
if (el.is(':checked')) {
var on = el.val() == '1' ? true : false;
element.disabled(!on);
if (!on) {
element.reset();
}
}
});
}
var Form = function (el, options) {
options = options || {};
this.form = $(el);
this.form.data('grav-form-instance', this);
this.form.on('submit', function (e) {
this.submit(this.ajax);
e.preventDefault();
return false;
}.bind(this));
this.scanned = false;
this.fieldIndicator = options.fieldIndicator || 'data-grav-field';
this.dataIndicator = options.dataIndicator || (this.fieldIndicator.indexOf('data-') === 0 ? this.fieldIndicator.substr(5) : 'grav-field');
this.ajax = options.ajax || false;
this.elements = [];
this.factories = {};
this.types = {};
if (typeof options.globalFactories === 'undefined' || options.globalFactories) {
for (var name in Form.factories) { if (Form.factories.hasOwnProperty(name)) {
this.registerFactory(Form.factories[name]);
}
}
}
scanToggleable(this);
scan(this);
this.scanned = true;
};
Form.factories = {};
Form.findElements = function(el, selector) {
el = $(el);
return el.find(selector).filter(function() {
var nearestMatch = $(this).parent().closest(selector);
return nearestMatch.length == 0 || el.find(nearestMatch).length == 0;
});
};
Form.registerFactory = function (factory, context) {
context = context || Form.factories;
context[factory.getName()] = factory;
return true;
};
Form.extendFactory = function (parentName, factory, context) {
context = context || Form.factories;
if (!context[parentName]) {
return false;
}
return Form.registerFactory(factory.getName(), $.extend({}, context[parentName], factory));
};
Form.prototype.findElements = function(type) {
var selector = '[' + this.fieldIndicator + (type ? '="' + type + '"' : '') + ']';
return Form.findElements(this.form, selector);
};
Form.prototype.registerFactory = function(factory) {
var registered = Form.registerFactory(factory, this.factories);
if (registered) {
addTypes(this, this.factories[factory.getName()]);
}
};
Form.prototype.extendFactory = function(parentName, factory) {
var registered = Form.extendFactory(parentN, factory, this.factories);
if (registered) {
addTypes(this, this.factories[factory.getName()]);
}
};
Form.prototype.getElements = function() {
if (!this.scanned) {
scan(this);
this.scanned = true;
}
return this.elements;
};
Form.prototype.getValues = function(all) {
var elements = this.getElements(),
values = {};
for (var i = elements.length - 1; i >= 0; i--) {
var e = elements[i].element;
if (!all && (!e.valid() || e.disabled())) {
continue;
}
$.extend(values, e.formValues());
}
return values;
};
Form.prototype.submit = function(ajax) {
var action = this.form.attr('action') || document.location,
method = this.form.attr('method') || 'POST',
values = this.getValues();
if (!values.task) {
values.task = 'save';
}
if (!ajax) {
var form = $('<form>').attr({ method: method, action: action });
for (var name in values) { if (values.hasOwnProperty(name)) {
$('<input>').attr({ type: 'hidden', name: name, value: values[name] }).appendTo(form);
}
}
return form.appendTo('body').submit();
} else {
return $.ajax({ method: method, url: action, data: values });
}
};
root.Form = Form;
})();

View File

@@ -266,7 +266,7 @@ form {
} }
} }
.dynfields { .dynfields, [data-grav-field="array"] {
input[type=text] { input[type=text] {
width: 40%; width: 40%;

View File

@@ -0,0 +1,70 @@
{% set originalValue = originalValue is defined ? originalValue : value %}
{% set value = (value is null ? field.default : value) %}
{% block field %}
<div class="form-field grid">
{% block contents %}
<div class="form-label block size-1-3">
<label>
{% block label %}
{% if field.help %}
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label }}</span>
{% else %}
{{ field.label }}
{% endif %}
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
{% endblock %}
</label>
</div>
<div class="form-data block size-2-3"
{% block global_attributes %}
data-grav-field="{{ field.type }}"
data-grav-disabled="{{ originalValue is null ? 'true' : 'false' }}"
data-grav-default="{{ field.default|json_encode()|e('html_attr') }}"
{% endblock %}
>
{% block group %}
{% block input %}
<div class="form-input-wrapper {{ field.size }}">
<input
{# required attribute structures #}
name="{{ (scope ~ field.name)|fieldName }}"
value="{{ value|join(', ') }}"
{# input attribute structures #}
{% block input_attributes %}
{% if field.classes is defined %} class="{{ field.classes }}" {% endif %}
{% if field.id is defined %} id="{{ field.id|e }}" {% endif %}
{% if field.style is defined %} style="{{ field.style|e }}" {% endif %}
{% if field.title is defined %} title="{{ field.title|e }}" {% endif %}
{% endblock %}
/>
</div>
{% endblock %}
{% endblock %}
</div>
{% if field.toggleable %}
<div class="block size-1-6">
<div class="switch-toggle switch-grav switch-2" data-grav-field="toggleable" data-grav-field-name="{{ field.name|fieldName }}">
<input
type="radio" value="1"
id="toggleable_{{ field.name }}_1"
class="highlight"
name="toggleable_{{ (scope ~ field.name)|fieldName }}"
{% if originalValue is not null %}checked="checked"{% endif %}
/>
<label for="toggleable_{{ field.name }}_1">On</label>
<input
type="radio" value="0"
id="toggleable_{{ field.name }}_0"
name="toggleable_{{ (scope ~ field.name)|fieldName }}"
{% if originalValue is null %}checked="checked"{% endif %}
/>
<label for="toggleable_{{ field.name }}_0">Off</label>
<a></a>
</div>
</div>
{% endif %}
{% endblock %}
</div>
{% endblock %}

View File

@@ -1,35 +1,30 @@
{% set value = (value is null ? field.default : value) %} {% extends "forms/field.html.twig" %}
<div class="form-field grid pure-g dynfields" data-grav-dynfields="{{ field.name|fieldName }}" data-grav-dynfields-key="{{ field.placeholder_key }}" data-grav-dynfields-value="{{ field.placeholder_value }}"> {% block global_attributes %}
<div class="form-label block size-1-3 pure-u-1-3"> data-grav-array-name="{{ field.name|fieldName }}"
<label> data-grav-array-keyname="{{ field.placeholder_key }}"
<span> data-grav-array-valuename="{{ field.placeholder_value }}"
{% if field.help %} {{ parent() }}
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label }}</span> {% endblock %}
{% else %}
{{ field.label }}
{% endif %}
</span>
</label>
</div>
<div class="form-data block size-2-3 pure-u-2-3">
{% block input %}
<div data-grav-array-type="container">
{% if value|length %} {% if value|length %}
{% for key, text in value %} {% for key, text in value %}
<div class="form-row"> <div class="form-row" data-grav-array-type="row">
<input type="text" value="{{ (scope ~ key)|fieldName }}" placeholder="{{ field.placeholder_key }}" /> <input data-grav-array-type="key" type="text" value="{{ key }}" placeholder="{{ field.placeholder_key }}" />
<input type="text" name="{{ (scope ~ field.name)|fieldName }}[{{ key }}]" value="{{ text|join(', ') }}" placeholder="{{ field.placeholder_value }}" /> <input data-grav-array-type="value" type="text" name="{{ key }}" value="{{ text|join(', ') }}" placeholder="{{ field.placeholder_value }}" />
<span data-grav-remfield class="fa fa-minus"></span> <span data-grav-array-action="rem" class="fa fa-minus"></span>
<span data-grav-addfield class="fa fa-plus"></span> <span data-grav-array-action="add" class="fa fa-plus"></span>
</div> </div>
{% endfor %} {% endfor %}
{% else %} {% else %}
<div class="form-row"> <div class="form-row" data-grav-array-type="row">
<input type="text" placeholder="{{ field.placeholder_key }}" /> <input data-grav-array-type="key" type="text" placeholder="{{ field.placeholder_key }}" />
<input type="text" placeholder="{{ field.placeholder_value }}" /> <input data-grav-array-type="value" type="text" placeholder="{{ field.placeholder_value }}" />
<span data-grav-remfield class="fa fa-minus"></span> <span data-grav-array-action="rem" class="fa fa-minus"></span>
<span data-grav-addfield class="fa fa-plus"></span> <span data-grav-array-action="add" class="fa fa-plus"></span>
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div> {% endblock %}

View File

@@ -1,11 +0,0 @@
field:
array:
node: array
key: name
fields:
name:
type: text
validation:
required: true
value:
type: text

View File

@@ -1,37 +1,34 @@
{% extends "forms/field.html.twig" %}
{% set originalValue = value %}
{% set value = (value is null ? field.default : value) %} {% set value = (value is null ? field.default : value) %}
{% if field.use == 'keys' and field.default %} {% if field.use == 'keys' and field.default %}
{% set value = field.default|merge(value) %} {% set value = field.default|merge(value) %}
{% endif %} {% endif %}
<div class="form-field grid pure-g"> {% block global_attributes %}
<div class="form-label block size-1-3 pure-u-1-3"> {{ parent() }}
<label> data-grav-keys="{{ field.use == 'keys' ? 'true' : 'false' }}"
{% if field.help %} data-grav-field-name="{{ field.name|fieldName }}"
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label|e }}</span> {% endblock %}
{% else %}
{{ field.label|e }} {% block input %}
{% endif %}
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
</label>
</div>
<div class="form-data block size-2-3 pure-u-2-3">
{% for key, text in field.options %} {% for key, text in field.options %}
{% set id = field.name ~ '-' ~ key %}
{% set name = field.use == 'keys' ? key : id %}
{% set val = field.use == 'keys' ? '1' : key %}
{% set checked = (field.use == 'keys' ? value[key] : key in value) %} {% set checked = (field.use == 'keys' ? value[key] : key in value) %}
{% set name = field.name|fieldName ~ '[' ~ (field.use == 'keys' ? key : '') ~ ']' %}
{% set key = (field.use == 'keys' ? '1' : key) %}
<span class="checkboxes"> <span class="checkboxes">
{% if (field.use == 'keys') %}
<input type="hidden" class="input" name="{{ (scope ~ name)|fieldName }}" value="0" />
{% endif %}
<input type="checkbox" <input type="checkbox"
id="{{ name|e }}{{ key|e }}" id="{{ id|e }}"
value="{{ key|e }}" value="{{ val|e }}"
name="{{ (scope ~ name)|fieldName }}" name="{{ name|fieldName }}"
{% if checked %}checked="checked"{% endif %} {% if checked %}checked="checked"{% endif %}
{% if field.validate.required %}required="required"{% endif %} {% if field.validate.required %}required="required"{% endif %}
> >
<label for="{{ name|e }}{{ key|e }}">{{ text|e }}</label> <label for="{{ id|e }}">{{ text|e }}</label>
</span> </span>
{% endfor %} {% endfor %}
</div> {% endblock %}
</div>

View File

@@ -1,3 +1,3 @@
{% set value = (value is null ? field.default : value) %} {% set value = (value is null ? field.default : value) %}
<input type="hidden" class="input" name="{{ (scope ~ field.name)|fieldName }}" value="{{ value|join(', ') }}" /> <input data-grav-field="hidden" data-grav-disabled="false" type="hidden" class="input" name="{{ (scope ~ field.name)|fieldName }}" value="{{ value|join(', ') }}" />

View File

@@ -1,17 +1,11 @@
{% set value = (value is null ? field.default : value) %} {% extends "forms/field.html.twig" %}
<div class="form-field grid pure-g"> {% block global_attributes %}
<div class="form-label block size-1-3 pure-u-1-3"> data-grav-selectize="{{ (field.selectize is defined ? field.selectize : {})|json_encode()|e('html_attr') }}"
<label> {{ parent() }}
{% if field.help %} {% endblock %}
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label }}</span>
{% else %} {% block input %}
{{ field.label }}
{% endif %}
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
</label>
</div>
<div class="form-data block size-2-3 pure-u-2-3">
<div class="form-select-wrapper {{ field.size }}"> <div class="form-select-wrapper {{ field.size }}">
<select class="{{ field.classes }}" name="{{ (scope ~ field.name)|fieldName ~ (field.multiple ? '[]' : '') }}" <select class="{{ field.classes }}" name="{{ (scope ~ field.name)|fieldName ~ (field.multiple ? '[]' : '') }}"
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %} {% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
@@ -24,5 +18,4 @@
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> {% endblock %}
</div>

View File

@@ -0,0 +1,11 @@
{% extends "forms/field.html.twig" %}
{% block global_attributes %}
data-grav-selectize="{{ (field.selectize is defined ? field.selectize|merge({'create': true}) : {'create': true})|json_encode()|e('html_attr') }}"
{{ parent() }}
{% endblock %}
{% block input_attributes %}
type="text"
{{ parent() }}
{% endblock %}

View File

@@ -4,12 +4,15 @@
{% set value = data.value('header.taxonomy.' ~ name) %} {% set value = data.value('header.taxonomy.' ~ name) %}
{% set field = { {% set field = {
type: 'text', type: 'select',
classes: 'fancy create', classes: 'fancy create',
label: name|capitalize, label: name|capitalize,
name: parentname ~ '.' ~ name, name: parentname ~ '.' ~ name,
multiple: true, multiple: true,
options: value options: value,
selectize: {
create: true
}
} %} } %}
{% include ['forms/fields/select/select.html.twig'] %} {% include ['forms/fields/select/select.html.twig'] %}

View File

@@ -1,22 +1,7 @@
{% set value = (value is null ? field.default : value) %} {% extends "forms/field.html.twig" %}
<div class="form-field grid pure-g"> {% block input_attributes %}
<div class="form-label block size-1-3 pure-u-1-3"> type="text"
<label>
{% if field.help %}
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label }}</span>
{% else %}
{{ field.label }}
{% endif %}
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
</label>
</div>
<div class="form-data block size-2-3 pure-u-2-3">
<div class="form-input-wrapper {{ field.size }}">
<input type="text"
class="{{ field.classes }}"
name="{{ (scope ~ field.name)|fieldName }}"
value="{{ value|join(', ') }}"
{% if field.placeholder %}placeholder="{{ field.placeholder }}"{% endif %} {% if field.placeholder %}placeholder="{{ field.placeholder }}"{% endif %}
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %} {% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %} {% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
@@ -24,8 +9,5 @@
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %} {% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %} {% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
{% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %} {% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %}
{{ parent() }}
/> {% endblock %}
</div>
</div>
</div>

View File

@@ -1,18 +1,14 @@
{% extends "forms/field.html.twig" %}
{% set value = (value is null ? field.default : value) %} {% set value = (value is null ? field.default : value) %}
{% set value = (value is same as(false) ? 0 : value) %} {% set value = (value is same as(false) ? 0 : value) %}
<div class="form-field grid pure-g"> {% block global_attributes %}
<div class="form-label block size-1-3 pure-u-1-3"> {{ parent() }}
<label> data-grav-field-name="{{ field.name|fieldName }}"
{% if field.help %} {% endblock %}
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label }}</span>
{% else %} {% block input %}
{{ field.label }}
{% endif %}
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
</label>
</div>
<div class="form-data block size-2-3 pure-u-2-3">
<div class="switch-toggle switch-grav switch-{{ field.options|length }}"> <div class="switch-toggle switch-grav switch-{{ field.options|length }}">
{% for key, text in field.options %} {% for key, text in field.options %}
{% set id = "toggle_" ~ field.name ~ key %} {% set id = "toggle_" ~ field.name ~ key %}
@@ -30,5 +26,4 @@
{% endfor %} {% endfor %}
<a></a> <a></a>
</div> </div>
</div> {% endblock %}
</div>

View File

@@ -41,7 +41,16 @@
{% do assets.addJs(theme_url~'/js/toastr.min.js') %} {% do assets.addJs(theme_url~'/js/toastr.min.js') %}
{% do assets.addJs(theme_url~'/js/jquery.remodal.min.js') %} {% do assets.addJs(theme_url~'/js/jquery.remodal.min.js') %}
{% do assets.addJs(theme_url~'/js/ajax.js') %} {% do assets.addJs(theme_url~'/js/ajax.js') %}
{% do assets.addJs(theme_url~'/js/admin-all.js') %} {% do assets.addJs(theme_url~'/js/admin-all.js') %}
{% do assets.addJs(theme_url~'/js/forms/form.js') %}
{% do assets.addJs(theme_url~'/js/forms/fields/input.js') %}
{% do assets.addJs(theme_url~'/js/forms/fields/array.js') %}
{% do assets.addJs(theme_url~'/js/forms/fields/selectize.js') %}
{% do assets.addJs(theme_url~'/js/forms/fields/checkboxes.js') %}
{% do assets.addJs(theme_url~'/js/forms/fields/toggle.js') %}
{% do assets.addJs(theme_url~'/js/forms.js') %}
{{ assets.js() }} {{ assets.js() }}
{% endblock %} {% endblock %}
{% endblock %} {% endblock %}

View File

@@ -1,6 +1,6 @@
{% set form_id = form_id ? form_id : 'blueprints' %} {% set form_id = form_id ? form_id : 'blueprints' %}
<form id="{{ form_id }}" method="post"> <form id="{{ form_id }}" method="post" data-grav-form="{{ form_id }}">
{% for field in blueprints.fields %} {% for field in blueprints.fields %}
{% if field.type %} {% if field.type %}
{% set value = data.value(field.name) %} {% set value = data.value(field.name) %}
@@ -20,34 +20,4 @@
{% include 'forms/fields/hidden/hidden.html.twig' %} {% include 'forms/fields/hidden/hidden.html.twig' %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{#
<div class="button-bar">
<button class="button" name="task" value="save">Save</button>
{% if context.exists %}
<button class="button" name="task" value="copy">Copy</button>
{% endif %}
{% if context.exists or context.isDir %}
<button class="button confirm-delete" name="task" value="delete" formnovalidate="formnovalidate">Delete</button>
{% endif %}
</div>
<script type="text/javascript">
$('.confirm-delete').click(function(){
var that = this;
vex.dialog.confirm({
message: 'Are you sure you want to delete the page and all content under it?',
callback: function(success) {
if (success) {
var form = $(that).closest('form');
$('<input />').attr('type', 'hidden').attr('name', 'task').attr('value', $(that).val()).appendTo(form);
form.submit();
}
}
});
return false;
});
</script>
#}
</form> </form>

View File

@@ -0,0 +1,23 @@
{% set form_id = form_id ? form_id : 'blueprints' %}
<form id="{{ form_id }}" method="post">
{% for field in blueprints.fields %}
{% if field.type %}
{% set value = data.value(field.name) %}
<div class="block block-{{ field.type }}">
{% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %}
</div>
{% endif %}
{% endfor %}
{% if data.extra %}
{% for name, value in data.extra %}
{% set field = {name: '_json.' ~ name} %}
{% set value = value|json_encode|e %}
{% include 'forms/fields/hidden/hidden.html.twig' %}
{% endfor %}
{% endif %}
</form>

View File

@@ -1,10 +1,5 @@
{% extends 'partials/base.html.twig' %} {% extends 'partials/base.html.twig' %}
{% block javascripts %}
{% do assets.addJs(theme_url~'/js/dynfields/dynfields.js') %}
{{ parent() }}
{% endblock %}
{% block titlebar %} {% block titlebar %}
<div class="button-bar"> <div class="button-bar">
<button class="button" type="submit" name="task" value="save" form="blueprints"><i class="fa fa-check"></i> Save</button> <button class="button" type="submit" name="task" value="save" form="blueprints"><i class="fa fa-check"></i> Save</button>