Initial commit
This commit is contained in:
commit
65e0da7e11
1397 changed files with 596542 additions and 0 deletions
13
site/OFF_plugins/field-engineer/.github/contributing.md
vendored
Normal file
13
site/OFF_plugins/field-engineer/.github/contributing.md
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# How to contribute
|
||||
|
||||
Issue reports and pull requests are very valuable to improve this project.
|
||||
|
||||
## Issue reporting
|
||||
|
||||
If you find something that does not work, add a new issue. Explain the problem as well as you can. Make sure the issue does not already exists. Provide the blueprint code if needed.
|
||||
|
||||
## Pull requests
|
||||
|
||||
Pull requests are allowed and we are very thankful for them!
|
||||
|
||||
Be aware that this project is on a commercial license. The code you send will then also be a part of this commercial project.
|
||||
50
site/OFF_plugins/field-engineer/assets/js/add.js
Normal file
50
site/OFF_plugins/field-engineer/assets/js/add.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
var EgrAdd = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.add = function(obj, this_obj) {
|
||||
var fieldset_name = fn.name(this_obj);
|
||||
var row = fn.row(this_obj);
|
||||
var fieldsets = fn.fieldsets(row);
|
||||
|
||||
fieldsets.append(fn.matchFieldset(row, fieldset_name, obj).clone());
|
||||
EgrId.replace(fieldsets.children('.egr-fieldset').last());
|
||||
|
||||
EgrSort.sort(this_obj);
|
||||
EgrCount.trigger(obj, this_obj);
|
||||
EgrTrigger.trigger(row);
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.name = function(this_obj) {
|
||||
return this_obj.attr('data-add');
|
||||
};
|
||||
|
||||
fn.row = function(this_obj) {
|
||||
return this_obj.closest('.egr-row');
|
||||
};
|
||||
|
||||
fn.id = function(row) {
|
||||
return row.attr('data-id');
|
||||
};
|
||||
|
||||
fn.fieldsets = function(row) {
|
||||
return row.children('.egr-fieldsets');
|
||||
};
|
||||
|
||||
fn.matchRow = function(row, obj) {
|
||||
var id = fn.id(row);
|
||||
return $('.egr-outline[data-id="' + obj.attr('data-name') + '"] .egr-row[data-id="' + id + '"]');
|
||||
};
|
||||
|
||||
fn.matchFieldsets = function(row, obj) {
|
||||
var match_row = fn.matchRow(row, obj);
|
||||
return match_row.children('.egr-fieldsets');
|
||||
};
|
||||
|
||||
fn.matchFieldset = function(row, fieldset_name, obj) {
|
||||
var match_fieldsets = fn.matchFieldsets(row, obj);
|
||||
return match_fieldsets.children('[data-fieldset-name="' + fieldset_name + '"]');
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
41
site/OFF_plugins/field-engineer/assets/js/clone.js
Normal file
41
site/OFF_plugins/field-engineer/assets/js/clone.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
var EgrClone = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.clone = function(obj, this_obj) {
|
||||
var fieldset = this_obj.closest('.egr-fieldset');
|
||||
var cloned = fn.duplicate(fieldset);
|
||||
|
||||
fn.setSelects(cloned, fn.getSelects(fieldset));
|
||||
EgrId.replace(cloned);
|
||||
EgrCount.trigger(obj, this_obj);
|
||||
EgrTrigger.trigger(this_obj.closest('.egr-row'));
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.duplicate = function(fieldset) {
|
||||
var cloned = fieldset.clone(true);
|
||||
fieldset.after(cloned);
|
||||
return fieldset.next();
|
||||
};
|
||||
|
||||
fn.getSelects = function(fieldset) {
|
||||
var array = [];
|
||||
var i = 0;
|
||||
fieldset.find('select').each(function(index) {
|
||||
$(this).val();
|
||||
array[i] = $(this).val();
|
||||
i++;
|
||||
});
|
||||
return array;
|
||||
};
|
||||
|
||||
fn.setSelects = function(next, select_values) {
|
||||
var i = 0;
|
||||
next.find('select').each(function(index) {
|
||||
$(this).val(select_values[i]);
|
||||
i++;
|
||||
});
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
13
site/OFF_plugins/field-engineer/assets/js/count.js
Normal file
13
site/OFF_plugins/field-engineer/assets/js/count.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
var EgrCount = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.trigger = function(obj, this_obj) {
|
||||
var row = this_obj.closest('.egr-row');
|
||||
var fieldsets = row.children('.egr-fieldsets');
|
||||
var fieldset = fieldsets.children('.egr-fieldset');
|
||||
var count = fieldset.length;
|
||||
row.attr('data-count', count);
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
26
site/OFF_plugins/field-engineer/assets/js/delete.js
Normal file
26
site/OFF_plugins/field-engineer/assets/js/delete.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
var EgrDelete = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.deleteMessage = function(obj, this_obj) {
|
||||
var delete_message = $(document).find('.egr-outline .egr-element-delete').first();
|
||||
fn.deleteCancel(obj, this_obj);
|
||||
obj.find('.egr-actions').hide();
|
||||
this_obj.closest('.egr-fieldset').addClass('egr-delete-active');
|
||||
this_obj.closest('.egr-fieldset').append(delete_message.clone());
|
||||
};
|
||||
|
||||
fn.deleteAction = function(obj, this_obj) {
|
||||
var fieldsets = this_obj.closest('.egr-fieldsets');
|
||||
this_obj.closest('.egr-fieldset').remove();
|
||||
EgrSort.sort(obj);
|
||||
EgrCount.trigger(obj, fieldsets);
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.deleteCancel = function(obj, this_obj) {
|
||||
obj.find('.egr-element-delete').remove();
|
||||
obj.find('.egr-delete-active').removeClass('egr-delete-active');
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
64
site/OFF_plugins/field-engineer/assets/js/id.js
Normal file
64
site/OFF_plugins/field-engineer/assets/js/id.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
var EgrId = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.replace = function(fieldset) {
|
||||
var time = new Date().getTime();
|
||||
|
||||
fn.replaceIds(fieldset, time);
|
||||
fn.replaceFors(fieldset, time);
|
||||
fn.replaceClasses(fieldset, time);
|
||||
fn.replaceNames(fieldset, time);
|
||||
fn.replacePrefixes(fieldset, time);
|
||||
|
||||
fn.addFieldsetCount(fieldset);
|
||||
};
|
||||
|
||||
fn.replaceIds = function(fieldset, time) {
|
||||
var matches = fieldset.find('[id^="form-field-"]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('id').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('id', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replaceFors = function(fieldset, time) {
|
||||
var matches = fieldset.find('[for^="form-field-"]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('for').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('for', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replaceClasses = function(fieldset, time) {
|
||||
var matches = fieldset.find('[data-field-name][class^="field "]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('class').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('class', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replaceNames = function(fieldset, time) {
|
||||
var matches = fieldset.find('[name]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('name').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('name', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replacePrefixes = function(fieldset, time) {
|
||||
var matches = fieldset.find('[data-prefix]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('data-prefix').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('data-prefix', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.addFieldsetCount = function(fieldset) {
|
||||
var row = fieldset.closest('.egr-row');
|
||||
var fieldset_count = row.children('.egr-row-actions').find('.egr-add-select').length;
|
||||
fieldset_count = (fieldset_count == 0) ? 1 : fieldset_count;
|
||||
row.attr('data-fieldset-count', fieldset_count);
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
13
site/OFF_plugins/field-engineer/assets/js/outline.js
Normal file
13
site/OFF_plugins/field-engineer/assets/js/outline.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
var EgrOutline = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.set = function(obj) {
|
||||
var outline = obj.find('.egr-outline');
|
||||
var name = obj.attr('data-name');
|
||||
|
||||
$('.mainbar').children('.section').prepend('<div class="egr-outline" data-id="' + name + '">' + outline.html() + "</div>");
|
||||
outline.remove();
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
215
site/OFF_plugins/field-engineer/assets/js/render.js
Normal file
215
site/OFF_plugins/field-engineer/assets/js/render.js
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
EgrRender = (function () {
|
||||
var fn = {};
|
||||
var level = 1;
|
||||
|
||||
fn.render = function(obj) {
|
||||
var output = '';
|
||||
var fields = obj.find('.egr-presentation').children();
|
||||
var out = '';
|
||||
var textarea = obj.find('.egr-output').find('textarea');
|
||||
out = fn.renderLoop(fields, out, level, true);
|
||||
textarea.val(out);
|
||||
textarea.blur();
|
||||
};
|
||||
|
||||
fn.renderLoop = function(fields, out, root_field) {
|
||||
fields.each(function(field_index) {
|
||||
var field = $(this);
|
||||
var field_name = field.attr('data-field-name');
|
||||
var depth = field.parents('.egr-row').length;
|
||||
var tab = ' '.repeat(depth);
|
||||
|
||||
if(field.hasClass('egr-row')) {
|
||||
if(!root_field) {
|
||||
out += tab + field_name + ":\n";
|
||||
}
|
||||
var fieldsets = $(this).children('.egr-fieldsets').children();
|
||||
if(depth > 0) tab += ' ';
|
||||
fieldsets.each(function(fieldset_index) {
|
||||
var fieldset = $(this);
|
||||
var subfields = fieldset.children('.egr-fields').children();
|
||||
|
||||
if(fieldset.attr('data-fieldset-name') != undefined) {
|
||||
out += tab + "-\n";
|
||||
out += fn.setFieldsetName(tab, field, fieldset);
|
||||
}
|
||||
out = fn.renderLoop(subfields, out, false);
|
||||
});
|
||||
} else {
|
||||
var fieldset = field.parent().parent();
|
||||
var selector = fn.getSelector(field_name, field);
|
||||
var element = fn.findFormElement(selector, field);
|
||||
var content = fn.getElement(element, field_name, tab);
|
||||
|
||||
if(content) {
|
||||
out += tab + content;
|
||||
}
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
fn.getSelector = function(field_name, field) {
|
||||
var selector = field_name + field.attr('data-prefix');
|
||||
return selector;
|
||||
};
|
||||
|
||||
fn.findFormElement = function(selector, field) {
|
||||
var single = '[name="' + selector + '"]:not(label)';
|
||||
var multiple = '[name^="' + selector + '["]:not(label)';
|
||||
var element = field.find(single + ',' + multiple);
|
||||
return element;
|
||||
};
|
||||
|
||||
fn.getElement = function(element, field_name, tab) {
|
||||
var elementType = element.prop('nodeName');
|
||||
var is_single = (element.length < 2) ? true : false;
|
||||
var output = '';
|
||||
|
||||
switch(elementType) {
|
||||
case 'TEXTAREA':
|
||||
output += fn.textarea(element, field_name, tab);
|
||||
break;
|
||||
case 'INPUT':
|
||||
switch(element.attr('type')) {
|
||||
case 'radio':
|
||||
output += fn.radio(element, field_name, tab);
|
||||
break;
|
||||
case 'checkbox':
|
||||
if(is_single) {
|
||||
output += fn.checkbox(element, field_name, tab);
|
||||
} else {
|
||||
output += fn.checkboxes(element, field_name, tab);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(element.hasClass('images')) {
|
||||
output += fn.textarea(element, field_name, tab);
|
||||
} else {
|
||||
if(is_single) {
|
||||
output += fn.input(element, field_name, is_single, tab);
|
||||
} else {
|
||||
if(field_name == 'datetime') {
|
||||
output += fn.input(element, field_name);
|
||||
} else {
|
||||
output += fn.inputs(element, field_name, tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'SELECT':
|
||||
output += fn.select(element, field_name, tab);
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
fn.setFieldsetName = function(tab, field, fieldset) {
|
||||
var fieldset_name = fieldset.attr('data-fieldset-name');
|
||||
var fieldset_count = field.attr('data-fieldset-count');
|
||||
if(fieldset_count == 1 && fieldset_name == 'default') {
|
||||
return '';
|
||||
}
|
||||
return tab + " _fieldset: " + fieldset_name + "\n";
|
||||
};
|
||||
|
||||
fn.inputs = function(element, field_name, tab) {
|
||||
var value = '';
|
||||
var indent = tab + ' ';
|
||||
|
||||
element.each(function( index ) {
|
||||
var val = $(this).val();
|
||||
val = val.replace(/"/g, '\\"');
|
||||
value += indent + '- "' + val + '"' + "\n";
|
||||
|
||||
});
|
||||
|
||||
value = value.slice(0, -1);
|
||||
return field_name + ": \n" + value + "\n";
|
||||
};
|
||||
|
||||
/* Input */
|
||||
fn.input = function(element, field_name) {
|
||||
var value = '';
|
||||
|
||||
element.each(function( index ) {
|
||||
value += $(this).val() + ' ';
|
||||
});
|
||||
value = value.slice(0, -1);
|
||||
value = value.replace(/"/g, '\\"');
|
||||
return field_name + ': "' + value + '"' + "\n";
|
||||
};
|
||||
|
||||
/* Textarea */
|
||||
fn.textarea = function(element, field_name, tab) {
|
||||
var value = element.val();
|
||||
var match = value.indexOf("\n");
|
||||
var indent = tab + ' ';
|
||||
|
||||
if(match > -1) {
|
||||
value = value.replace(/(?:\r\n|\r|\n)/g, "\n" + indent);
|
||||
if(value != '') {
|
||||
return field_name + ": |\n" + indent + value + "\n";
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return fn.input(element, field_name);
|
||||
};
|
||||
|
||||
/* Select */
|
||||
fn.select = function(element, field_name) {
|
||||
var value = element.val();
|
||||
value = value.replace(/"/g, '\\"');
|
||||
return field_name + ': "' + value + '"' + "\n";
|
||||
};
|
||||
|
||||
/* Radio */
|
||||
fn.radio = function(element, field_name) {
|
||||
out = '';
|
||||
element.each(function(index) {
|
||||
if($(this).is(':checked')) {
|
||||
var value = $(this).val();
|
||||
if(value == 'true' || value == 'false') {
|
||||
value = "'" + value + "'";
|
||||
}
|
||||
out += field_name + ": " + value + "\n";
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
/* Checkbox */
|
||||
fn.checkbox = function(element, field_name) {
|
||||
out = '';
|
||||
element.each(function(index) {
|
||||
if($(this).is(':checked')) {
|
||||
var value = $(this).val();
|
||||
if(value == 'on') {
|
||||
value = 'true';
|
||||
}
|
||||
out += field_name + ': ' + value + "\n";
|
||||
} else {
|
||||
out += field_name + ": false\n";
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
/* Checkboxes */
|
||||
fn.checkboxes = function(element, field_name, tab) {
|
||||
out = '';
|
||||
element.each(function(index) {
|
||||
if($(this).is(':checked')) {
|
||||
out += tab + ' - ' + $(this).val() + "\n";
|
||||
}
|
||||
});
|
||||
if(out != '') {
|
||||
out = field_name + ":\n" + out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
return fn;
|
||||
})();
|
||||
71
site/OFF_plugins/field-engineer/assets/js/script.js
Normal file
71
site/OFF_plugins/field-engineer/assets/js/script.js
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
(function($) {
|
||||
$.fn.engineer = function() {
|
||||
return this.each(function() {
|
||||
var field = $(this);
|
||||
var fieldname = 'engineer';
|
||||
|
||||
if(field.data( fieldname )) {
|
||||
return true;
|
||||
} else {
|
||||
field.data( fieldname, true );
|
||||
}
|
||||
|
||||
EgrOutline.set(field);
|
||||
|
||||
field.on('click', '.egr [data-add]', function() {
|
||||
EgrAdd.add(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-delete-apply', function() {
|
||||
EgrDelete.deleteAction(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-delete-cancel', function() {
|
||||
EgrDelete.deleteCancel(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-clone', function() {
|
||||
EgrClone.clone(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-fieldset', function(e) {
|
||||
if(!$(e.target).closest('.egr-fieldset').not(this).length){
|
||||
EgrToggleActive.toggle(field, $(this));
|
||||
}
|
||||
});
|
||||
|
||||
field.on('click', '.egr-delete', function() {
|
||||
EgrDelete.deleteMessage(field, $(this));
|
||||
});
|
||||
|
||||
$(document).on('click', function(e) {
|
||||
if(!$(e.target).closest('.egr-add-button').not(this).length) {
|
||||
$(document).find('.egr-dropdown-active').removeClass('egr-dropdown-active');
|
||||
}
|
||||
if(!$(e.target).closest('.egr-fieldset').not(this).length) {
|
||||
EgrToggleActive.remove(field, $(this));
|
||||
}
|
||||
});
|
||||
|
||||
field.on('click', '.egr-sort-up', function(e) {
|
||||
EgrSort.sortUp(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-sort-down', function(e) {
|
||||
EgrSort.sortDown(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-add-button', function(e) {
|
||||
if(!$(e.target).closest('.egr-add-button').not(this).length){
|
||||
EgrToggleDropdown.toggle(field, $(this));
|
||||
}
|
||||
});
|
||||
|
||||
EgrSort.sort(field);
|
||||
|
||||
field.find('.egr-presentation').on('input click change', 'input, select, textarea', function() {
|
||||
EgrRender.render(field, $(this));
|
||||
});
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
58
site/OFF_plugins/field-engineer/assets/js/sort.js
Normal file
58
site/OFF_plugins/field-engineer/assets/js/sort.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
var EgrSort = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.sort = function(obj) {
|
||||
var items = obj.find('.egr');
|
||||
var firstSort = true;
|
||||
items.sortable({
|
||||
items: '.egr-sorted-fieldset',
|
||||
handle: '.egr-sort',
|
||||
start: function(e, ui) {
|
||||
if(firstSort) {
|
||||
items.sortable('refreshPositions');
|
||||
firstSort = false;
|
||||
}
|
||||
},
|
||||
update: function( event, ui ) {
|
||||
EgrRender.render(obj);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
fn.removeClasses = function(obj, this_obj) {
|
||||
obj.find('.egr-sorted-row').removeClass('egr-sorted-row');
|
||||
obj.find('.egr-sorted-fieldsets').removeClass('egr-sorted-fieldsets');
|
||||
obj.find('.egr-sorted-fieldset').removeClass('egr-sorted-fieldset');
|
||||
};
|
||||
|
||||
fn.toggle = function(obj, this_obj) {
|
||||
var row = this_obj.closest('.egr-row');
|
||||
var fieldsets = row.children('.egr-fieldsets');
|
||||
var fieldset = fieldsets.children('.egr-fieldset');
|
||||
fn.removeClasses(obj, this_obj);
|
||||
row.addClass('egr-sorted-row');
|
||||
fieldsets.addClass('egr-sorted-fieldsets');
|
||||
fieldset.addClass('egr-sorted-fieldset');
|
||||
EgrSort.sort(obj);
|
||||
};
|
||||
|
||||
fn.sortUp = function(obj, this_obj) {
|
||||
var current = this_obj.closest('.egr-fieldset');
|
||||
var prev = current.prev();
|
||||
var cloned = prev.clone(true);
|
||||
current.after(cloned);
|
||||
prev.remove();
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.sortDown = function(obj, this_obj) {
|
||||
var current = this_obj.closest('.egr-fieldset');
|
||||
var next = current.next();
|
||||
var cloned = next.clone(true);
|
||||
current.before(cloned);
|
||||
next.remove();
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
17
site/OFF_plugins/field-engineer/assets/js/toggleActive.js
Normal file
17
site/OFF_plugins/field-engineer/assets/js/toggleActive.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
var EgrToggleActive = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.toggle = function(obj, this_obj) {
|
||||
if(this_obj.hasClass('egr-delete-active')) return;
|
||||
|
||||
obj.find('.egr-actions').hide();
|
||||
this_obj.children('.egr-actions').css('display', 'flex');
|
||||
EgrSort.toggle(obj, this_obj);
|
||||
};
|
||||
|
||||
fn.remove = function(obj, this_obj) {
|
||||
obj.find('.egr-actions').hide();
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
20
site/OFF_plugins/field-engineer/assets/js/toggleDropdown.js
Normal file
20
site/OFF_plugins/field-engineer/assets/js/toggleDropdown.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
var EgrToggleDropdown = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.toggle = function(obj, this_obj) {
|
||||
if(fn.count(this_obj) > 1) {
|
||||
if(this_obj.parent().hasClass('egr-dropdown-active')) {
|
||||
this_obj.parent().removeClass('egr-dropdown-active');
|
||||
} else {
|
||||
obj.find('.egr-dropdown-active').removeClass('egr-dropdown-active');
|
||||
this_obj.parent().addClass('egr-dropdown-active');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fn.count = function(this_obj) {
|
||||
return this_obj.find('.egr-add-select').length;
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
58
site/OFF_plugins/field-engineer/assets/js/trigger.js
Normal file
58
site/OFF_plugins/field-engineer/assets/js/trigger.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
var EgrTrigger = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.trigger = function(row) {
|
||||
fn.triggerFields(row);
|
||||
fn.triggerPlugins(row);
|
||||
|
||||
fn.checkDuplicates(row);
|
||||
};
|
||||
|
||||
fn.triggerFields = function(row) {
|
||||
row.find('[data-field="urlfield"]').removeData('urlfield').off('click').urlfield();
|
||||
row.find('[data-field="date"]').removeData('date').off('change').date();
|
||||
row.find('[data-field="imagefield"]').removeData('imagefield').imagefield();
|
||||
row.find('[data-field="autocomplete"]').removeData('autocomplete').off('keydown keyup').autocomplete();
|
||||
row.find('[data-field="editor"]').removeData('editor').off('keydown click').editor();
|
||||
row.find('[data-field="counter"]').removeData('counter').counter();
|
||||
};
|
||||
|
||||
fn.triggerPlugins = function(row) {
|
||||
if ( row.find('[data-field="images"]').length ) {
|
||||
row.find('[data-field="images"]').removeData('images').images();
|
||||
}
|
||||
if ( row.find('[data-field="hero"]').length ) {
|
||||
row.find('[data-field="hero"]').removeData('hero').hero();
|
||||
}
|
||||
if ( row.find('[data-field="quickselect"]').length ) {
|
||||
row.find('[data-field="quickselect"]').removeData('quickselect').quickselect();
|
||||
}
|
||||
if ( row.find('[data-field="list"]').length ) {
|
||||
row.find('[data-field="list"]').removeData('list').list();
|
||||
}
|
||||
};
|
||||
|
||||
fn.checkDuplicates = function(row) {
|
||||
var i = 0;
|
||||
var values = [];
|
||||
row.closest('.egr').find('.field').each(function( index ) {
|
||||
var classes = $(this).attr('class').split(" ");
|
||||
|
||||
$.each(classes, function( index, value ) {
|
||||
if(value.endsWith("_egr__")) {
|
||||
values[i] = value;
|
||||
i++;
|
||||
}
|
||||
});
|
||||
});
|
||||
if(fn.hasDuplicates(values)) {
|
||||
console.log('Error: There are duplicates!');
|
||||
}
|
||||
};
|
||||
|
||||
fn.hasDuplicates = function(array) {
|
||||
return (new Set(array)).size !== array.length;
|
||||
}
|
||||
|
||||
return fn;
|
||||
})();
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
.egr-actions {
|
||||
width: calc(100% + 1.5em);
|
||||
display: none;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #ddd;
|
||||
|
||||
> * {
|
||||
height: 2.5em;
|
||||
line-height: 2.5em;
|
||||
cursor: pointer;
|
||||
padding-right: 1.5em;
|
||||
padding-left: 1.5em;
|
||||
user-select: none;
|
||||
border-right: 1px solid #ddd;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.egr-even .egr-actions {
|
||||
border-top: 1px solid #ccc;
|
||||
|
||||
> * {
|
||||
border-right: 1px solid #ccc;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
.egr-element-delete {
|
||||
width: calc(100% + 1.5em);
|
||||
z-index: 100;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
|
||||
.egr-delete-message {
|
||||
padding: 1.5em;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-delete-buttons {
|
||||
max-width: 20em;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
margin-top: .5em;
|
||||
|
||||
>* {
|
||||
cursor: pointer;
|
||||
line-height: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-delete-cancel {
|
||||
padding: 0 .5em;
|
||||
color: #777;
|
||||
border: 2px solid transparent;
|
||||
|
||||
span {
|
||||
border-bottom: 2px solid #eee;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #000;
|
||||
|
||||
span {
|
||||
border-bottom: 2px solid #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.egr-delete-apply {
|
||||
border-radius: .3em;
|
||||
padding: 0 1em;
|
||||
color: #b3000a;
|
||||
border: 2px solid #b3000a;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background: #b3000a;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-delete-active {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.egr-delete-active .egr-fields:before{
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: #b3000a;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
opacity: .2;
|
||||
}
|
||||
34
site/OFF_plugins/field-engineer/assets/scss/dropdown.scss
Normal file
34
site/OFF_plugins/field-engineer/assets/scss/dropdown.scss
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
.egr-dropdown {
|
||||
position: absolute;
|
||||
background: #000;
|
||||
border-radius: 4px;
|
||||
right: 0;
|
||||
z-index: 10000;
|
||||
display: none;
|
||||
margin-top: .4em;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
border-left: .4em solid transparent;
|
||||
border-right: .4em solid transparent;
|
||||
border-bottom: .4em solid #000;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
margin-top: -.3em;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-empty .egr-dropdown:before {
|
||||
left: 2em;
|
||||
}
|
||||
.egr-row-actions .egr-dropdown:before {
|
||||
left: calc(100% - 2.4em);
|
||||
}
|
||||
|
||||
.egr-dropdown-active .egr-dropdown {
|
||||
display: block;
|
||||
}
|
||||
.egr-dropdown-active .egr-add-button .icon {
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
17
site/OFF_plugins/field-engineer/assets/scss/empty.scss
Normal file
17
site/OFF_plugins/field-engineer/assets/scss/empty.scss
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
.egr-empty {
|
||||
padding: 1.5em;
|
||||
background: #ddd;
|
||||
display: none;
|
||||
|
||||
.egr-add-button {
|
||||
border-bottom: 2px solid #aaa;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.egr-dropdown {
|
||||
right: auto;
|
||||
margin-top: .7em;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
site/OFF_plugins/field-engineer/assets/scss/grid.scss
Normal file
35
site/OFF_plugins/field-engineer/assets/scss/grid.scss
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
.egr-grid-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.egr-fieldset {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 60em) {
|
||||
.egr-grid-item {
|
||||
width: calc(100% + 1.5em);
|
||||
}
|
||||
|
||||
.egr-fieldset {
|
||||
margin-right: 1.5em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.egr-grid-item-1-2 > .egr-fieldset {
|
||||
width: calc(100% / 2 - 1.5em);
|
||||
}
|
||||
.egr-grid-item-1-3 > .egr-fieldset {
|
||||
width: calc(100% / 3 - 1.5em);
|
||||
}
|
||||
.egr-grid-item-1-4 > .egr-fieldset {
|
||||
width: calc(100% / 4 - 1.5em);
|
||||
}
|
||||
.egr-grid-item-1-5 > .egr-fieldset {
|
||||
width: calc(100% / 5 - 1.5em);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.egr-row[data-count="0"] > .egr-empty {
|
||||
display: block;
|
||||
}
|
||||
.egr-row[data-count="0"] > .egr-row-actions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.egr-dropdown-active .egr-add-button:before {
|
||||
display: block;
|
||||
}
|
||||
3
site/OFF_plugins/field-engineer/assets/scss/outline.scss
Normal file
3
site/OFF_plugins/field-engineer/assets/scss/outline.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.egr-outline {
|
||||
opacity: .5;
|
||||
}
|
||||
15
site/OFF_plugins/field-engineer/assets/scss/output.scss
Normal file
15
site/OFF_plugins/field-engineer/assets/scss/output.scss
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
.egr-output {
|
||||
margin-left: 1.5em;
|
||||
width: calc(100% - 1.5em);
|
||||
padding-bottom: 1.5em;
|
||||
display: none;
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
border: 2px solid #ddd;
|
||||
padding: .5em;
|
||||
font-size: .9em;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
0
site/OFF_plugins/field-engineer/assets/scss/plugins.scss
Normal file
0
site/OFF_plugins/field-engineer/assets/scss/plugins.scss
Normal file
49
site/OFF_plugins/field-engineer/assets/scss/row-actions.scss
Normal file
49
site/OFF_plugins/field-engineer/assets/scss/row-actions.scss
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
.egr-row-actions {
|
||||
margin-top: .5em;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-add-button {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
|
||||
span {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
&:hover span {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-add {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.egr-add-select {
|
||||
padding: .75em 1.5em .75em 1.5em;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #222;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.egr-dropdown-active .egr-add-button:before {
|
||||
display: block;
|
||||
}
|
||||
34
site/OFF_plugins/field-engineer/assets/scss/skeleton.scss
vendored
Normal file
34
site/OFF_plugins/field-engineer/assets/scss/skeleton.scss
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
.egr {
|
||||
margin-left: -1.5em;
|
||||
margin-bottom: -1.5em;
|
||||
}
|
||||
|
||||
.egr-row {
|
||||
margin-left: 1.5em;
|
||||
width: calc(100% - 1.5em);
|
||||
padding-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.egr-fieldsets {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.egr-fieldset {
|
||||
padding-top: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
border: 2px solid #ddd;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.egr-even > .egr-fieldsets > .egr-fieldset {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.egr-outline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.egr-fields {
|
||||
flex: 1;
|
||||
}
|
||||
16
site/OFF_plugins/field-engineer/assets/scss/sort.scss
Normal file
16
site/OFF_plugins/field-engineer/assets/scss/sort.scss
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
.egr .ui-sortable-helper {
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
|
||||
.egr-presentation .egr-fieldset:first-child > .egr-actions > .egr-sort-up {
|
||||
display: none;
|
||||
}
|
||||
.egr-presentation .egr-fieldset:last-child > .egr-actions > .egr-sort-down {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.egr-presentation .egr-fieldset:only-child > .egr-actions > .egr-sort-up,
|
||||
.egr-presentation .egr-fieldset:only-child > .egr-actions > .egr-sort-down,
|
||||
.egr-presentation .egr-fieldset:only-child > .egr-actions > .egr-sorting {
|
||||
display: none;
|
||||
}
|
||||
13
site/OFF_plugins/field-engineer/assets/scss/style.scss
Normal file
13
site/OFF_plugins/field-engineer/assets/scss/style.scss
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
@import 'skeleton';
|
||||
@import 'action-items';
|
||||
@import 'has-fieldsets';
|
||||
@import 'dropdown';
|
||||
@import 'empty';
|
||||
@import 'output';
|
||||
@import 'outline';
|
||||
@import 'sort';
|
||||
@import 'row-actions';
|
||||
@import 'plugins';
|
||||
@import 'grid';
|
||||
@import 'delete-message';
|
||||
@import 'table';
|
||||
63
site/OFF_plugins/field-engineer/assets/scss/table.scss
Normal file
63
site/OFF_plugins/field-engineer/assets/scss/table.scss
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
$lp: 1em;
|
||||
|
||||
.egr-style-table {
|
||||
> .egr-fieldsets {
|
||||
border: 2px solid #ddd;
|
||||
> .egr-fieldset {
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
padding-top: .5em;
|
||||
padding-right: .5em;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
|
||||
> .egr-actions {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .egr-fields {
|
||||
> .field {
|
||||
padding-left: .5em;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
}
|
||||
> .egr-actions {
|
||||
width: calc(100% + .5em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.egr-odd {
|
||||
> .egr-fieldsets {
|
||||
> .egr-labels {
|
||||
background: #fff;
|
||||
}
|
||||
> .egr-fieldset > .egr-actions {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.egr-even {
|
||||
> .egr-fieldsets {
|
||||
> .egr-labels {
|
||||
background: #eee;
|
||||
}
|
||||
> .egr-fieldset > .egr-actions {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.egr-labels {
|
||||
padding-top: $lp;
|
||||
padding-right: $lp;
|
||||
border-bottom: 1px solid #ddd;
|
||||
|
||||
> .field {
|
||||
margin-bottom: $lp / 2;
|
||||
padding-left: $lp !important;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# Advanced - For plugin developers
|
||||
|
||||
#### Field controllers and field routes
|
||||
|
||||
Fields using a field controller or a field route might get into trouble because the subfields of Engineer does not have a field controller or a field route of their own. It's more like a virtual field.
|
||||
|
||||
#### Add and field javascript DOM
|
||||
|
||||
Fields sometimes uses javascript to show a preview when the field changes. When a new field is added in engineer, it's done with javascript. Therefor the field not yet aware of that the DOM has been updated. In order to make it work well you need to save it first. Then it will load everything again with PHP and the field will be aware of the DOM again.
|
||||
|
||||
For the built in fields, Engineer will solve it by forcing the fields to update themselves when adding a new item. The same thing can be done for plugins as well, but at the moment it needs to be triggered from inside Engineer.
|
||||
|
||||
### The results class
|
||||
|
||||
If you use the results class to manipulate the data before it's saved, it can cause troubles with Engineer because it uses pure javascript to get the data.
|
||||
165
site/OFF_plugins/field-engineer/docs/blueprint.md
Normal file
165
site/OFF_plugins/field-engineer/docs/blueprint.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# Blueprint
|
||||
|
||||
Most of the engineer options are the same as the [structure field](https://getkirby.com/docs/cheatsheet/panel-fields/structure).
|
||||
|
||||
## Engineer field
|
||||
|
||||
### Basic example
|
||||
|
||||
A basic example with two fields, one text field and one image field.
|
||||
|
||||
**Blueprint**
|
||||
|
||||
```text
|
||||
fields:
|
||||
my_engineer:
|
||||
type: engineer
|
||||
fields:
|
||||
first:
|
||||
label: Text
|
||||
type: text
|
||||
second:
|
||||
label: Image
|
||||
type: image
|
||||
```
|
||||
|
||||
**Content**
|
||||
|
||||
```text
|
||||
My_engineer:
|
||||
|
||||
-
|
||||
first: "My first text"
|
||||
second: "flowers.jpg"
|
||||
-
|
||||
first: "Another text"
|
||||
second: "nature.jpg"
|
||||
```
|
||||
|
||||
### Advanced example
|
||||
|
||||
A more advanced example where multiple fieldsets are used. Also it uses nested engineer fields.
|
||||
|
||||
**Blueprint**
|
||||
|
||||
```text
|
||||
fields:
|
||||
my_engineer:
|
||||
type: engineer
|
||||
fieldsets:
|
||||
set1:
|
||||
fields:
|
||||
first:
|
||||
label: Engineer
|
||||
type: engineer
|
||||
fields:
|
||||
my_text:
|
||||
type: text
|
||||
my_image:
|
||||
type: image
|
||||
second:
|
||||
label: Image
|
||||
type: image
|
||||
set2:
|
||||
fields:
|
||||
first:
|
||||
type: text
|
||||
second:
|
||||
type: toggle
|
||||
```
|
||||
|
||||
**Content**
|
||||
|
||||
```text
|
||||
My_engineer:
|
||||
|
||||
-
|
||||
_fieldset: set1
|
||||
second: "flowers.jpg"
|
||||
first:
|
||||
-
|
||||
my_text: "First row inside"
|
||||
my_image: "nature.jpg"
|
||||
-
|
||||
my_text: "Second row inside"
|
||||
my_image: "nature.jpg"
|
||||
-
|
||||
_fieldset: set2
|
||||
first: "A set with a toggle field"
|
||||
second: 'false'
|
||||
```
|
||||
|
||||
### Engineer field options
|
||||
|
||||
**label**
|
||||
|
||||
It's optional but you can give the Engineer field a label if you like.
|
||||
|
||||
**type**
|
||||
|
||||
The `type` option needs to be set to `engineer`.
|
||||
|
||||
**style**
|
||||
|
||||
Set `style: table` to use a tabular layout. It does not work exactly as the structure field. With this field it's required to set a `width` of every sub field. Look at the built in `table.yml` blueprint to get inspiration.
|
||||
|
||||
For a normal layout, just skip this option.
|
||||
|
||||
**width**
|
||||
|
||||
*Changed behavior from v0.6 to v0.7*
|
||||
|
||||
The width of the engineer container.
|
||||
|
||||
**rowWidth**
|
||||
|
||||
The `rowWidth` works similar to field `width`. This option set the width of the fields or fieldset rows.
|
||||
|
||||
In the example below, the field container will take `1/2` of the total width. Each added row take `1/3` of the container width.
|
||||
|
||||
```text
|
||||
my_engineer:
|
||||
type: engineer
|
||||
width: 1/2
|
||||
rowWidth: 1/3
|
||||
fields:
|
||||
text:
|
||||
type: text
|
||||
image:
|
||||
type: image
|
||||
```
|
||||
|
||||
**fields**
|
||||
|
||||
It works very similar to the [structure field](https://getkirby.com/docs/cheatsheet/panel-fields/structure). The best way to understand it is to look at the basic example.
|
||||
|
||||
**fieldsets**
|
||||
|
||||
Instead of fields you can use fieldsets. Then you can choose which set to use. To learn it, see the advanced example.
|
||||
|
||||
**style**
|
||||
|
||||
This option is similar to the structure field, but with Engineer the only style that can be set is `style: table`, or non at all.
|
||||
|
||||
Keep these things in mind:
|
||||
|
||||
- The sub field option `width` is required, leaving you in control.
|
||||
- Only use 1 `fieldset` or use `fields`. Else you will get the wrong table headings.
|
||||
- It's generates a table, so let the sub fields be on the same row.
|
||||
|
||||
**buttons**
|
||||
|
||||
If you don't use this option it will fallback to the following buttons:
|
||||
|
||||
```text
|
||||
buttons:
|
||||
- delete
|
||||
- clone
|
||||
- sort-up
|
||||
- sort-down
|
||||
- sort
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[Read about supported fields](fields.md)
|
||||
91
site/OFF_plugins/field-engineer/docs/changelog.md
Normal file
91
site/OFF_plugins/field-engineer/docs/changelog.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# Changelog
|
||||
|
||||
**v0.9**
|
||||
|
||||
- **Feature** - `style: table` reimplemented.
|
||||
- **Enhancement** - Removed some html classes that was not needed for table labels.
|
||||
- **Bug fix** - Fixed error if table fieldset could not be found.
|
||||
- **Bug fix** - Engineer blueprints are now only registered if `engineer.debug` is on.
|
||||
- **Bug fix** - `style: table` label issue fixed. Thanks [Dreytac](https://github.com/Dreytac).
|
||||
|
||||
**v0.8**
|
||||
|
||||
- **Test** - Blueprint `panel-fields.yml` that tests all supported native fields built into the Panel.
|
||||
- **Test** - Blueprint `supported-fields.yml` that tests custom made fields that are supported by Engineer.
|
||||
- **Test** - Blueprint `working-fields.yml` that tests custom made fields that should work out of the box.
|
||||
- **Test** - Blueprint `grid.yml` that tests `width`, `rowWidth` and `buttons` on multiple levels.
|
||||
- **Test** - Blueprint `nesting.yml` that tests nesting on multiple levels.
|
||||
- **Test** - Blueprint `fieldsets.yml` that tests `fields`, `fieldsets` and empty sets on multiple levels.
|
||||
- **Test** - Blueprint `options.yml` that tests field options `default`, `icon`, `readonly`, `help`, `placeholder` and `required`.
|
||||
- **Enhancement** - It's now possible to click outside a field to hide the action bar.
|
||||
|
||||
**v0.7**
|
||||
|
||||
- **Feature** - Delete warning message.
|
||||
- **Feature** - Delete area preview.
|
||||
- **Feature** - Tests added. Blueprints are registered if `engineer.debug` is set to `true`.
|
||||
- **Breaking change** - The `width` option for rows is renamed `rowWidth` instead. It will make it more future proof and prevent collisions with `width` on the root of the engineer field.
|
||||
- **Breaking change** - The option `engineer.label.fallback` is removed. No good reason for a label fallback.
|
||||
- **Bug fixes** - Minor issues.
|
||||
- **Docs** - Because of some recent Panel bugs I pushed the requirement to Kirby 2.5.2.
|
||||
- ~~**Field** - [Kirby list field](https://github.com/TimOetting/kirby-list-field) is now supported.~~ (a dom bug remains)
|
||||
|
||||
**v0.6**
|
||||
|
||||
- Feature - Blueprint option to choose which buttons to use.
|
||||
- Feature - Blueprint option `width` can now be set to engineer fields.
|
||||
- Improved the dropdown arrow position.
|
||||
- Improved the trash icon to look like the Panel trash icon.
|
||||
- Improved the action button bar ui.
|
||||
- Improved "Add the first entry" with icons to show if it's containing fields or fieldsets.
|
||||
- Removed labels from the action buttons to save space for small fields.
|
||||
- Removed border for [Kirby Images](https://github.com/medienbaecker/kirby-images). The css is now handled by Kirby Images instead.
|
||||
- Field [Kirby date field](https://github.com/iksi/KirbyDateField) works with Engineer.
|
||||
- Field [Kirby time field](https://github.com/iksi/KirbyTimeField) works with Engineer.
|
||||
- Field [Kirby country field](https://github.com/iksi/KirbyCountryField) works with Engineer.
|
||||
- Field [Kirby decimal field](https://github.com/iksi/KirbyDecimalField) works with Engineer.
|
||||
- Docs - Separated [field plugins](fields.md#plugin-fields) that works "out of the box" from the "supported" ones.
|
||||
- Docs - [Troubleshooting](troubleshooting.md) steps added.
|
||||
|
||||
**v0.5**
|
||||
|
||||
- Added requirement: PHP7+
|
||||
- Support for multi language setup
|
||||
- Support for Kirby 2.5.1
|
||||
- Support for [Controlled list](https://github.com/rasteiner/controlledlist)
|
||||
- Support for [Kirby Images](https://github.com/medienbaecker/kirby-images)
|
||||
- Support for [Kirby Hero Field](https://github.com/jenstornell/kirby-hero-field)
|
||||
- Support for [Kirby Logic Field](https://github.com/jenstornell/kirby-logic-field)
|
||||
- Support for [Kirby Quickselect](https://github.com/medienbaecker/kirby-quickselect)
|
||||
- Support for [Select a structure](https://github.com/CalebGrove/select-a-structure)
|
||||
- Support for [Switch field](https://github.com/distantnative/field-switch)
|
||||
|
||||
**rc-0.4**
|
||||
|
||||
- Complete rewrite
|
||||
- Feature - Nesting with unlimted levels
|
||||
- Feature - Sorting arrows
|
||||
- Feature - Fieldsets
|
||||
- Feature - Clone
|
||||
- Feature - Debug option `c::set('engineer.debug')`
|
||||
- Feature - Label fallback option `c::set('engineer.label.fallback')`
|
||||
- Fix - Default value
|
||||
- Fix - Counter for min/max
|
||||
- Fix - Headline
|
||||
- On hold - `style: table` does not work in this version
|
||||
|
||||
**beta v0.3**
|
||||
|
||||
- Fixed bug with th position
|
||||
- Fixed bug with table sort jumping
|
||||
- Fixed bug with checkboxes `option: children`
|
||||
- Fixed bug with textarea autosize after adding new item
|
||||
- Fixed bug frontend crasch. Only run plugin in the panel.
|
||||
|
||||
**beta v0.2**
|
||||
|
||||
- Lots of big changes
|
||||
|
||||
**beta v0.1**
|
||||
|
||||
- Initial release
|
||||
45
site/OFF_plugins/field-engineer/docs/compare.md
Normal file
45
site/OFF_plugins/field-engineer/docs/compare.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Comparation
|
||||
|
||||
To know what field you should use you can use this comparation table.
|
||||
|
||||
| Feature | Engineer | [Builder](https://github.com/TimOetting/kirby-builder) | [Structure](https://getkirby.com/docs/cheatsheet/panel-fields/structure)
|
||||
| -------------------------------------------------------- | ---------- | -------- | ---------
|
||||
| Inline editing (no modal) | Yes | - | -
|
||||
| Nesting without limit | Yes | - | -
|
||||
| Fieldsets | Yes | Yes | -
|
||||
| Show images in the output | Yes | Yes | -
|
||||
| Built in field support | Partly | - | Yes
|
||||
| Plugin field support | Partly | - | Yes
|
||||
| Custom validators | - | Yes | Yes
|
||||
| Row limit | - | - | Yes
|
||||
| **Price** | **50 EUR** | **Free** | **Free**
|
||||
|
||||
*If the information above is no longer accurate, just add an issue about it*
|
||||
|
||||
## Custom validators
|
||||
|
||||
*Not supported - Here is the reason behind it:*
|
||||
|
||||
[Custom validators](https://getkirby.com/docs/developer-guide/objects/validators) does not work with Engineer. The are a few reasons why it's not supported. Speed and usability are two of the reasons.
|
||||
|
||||
Engineer uses an inline approach with pure javascript. It has no delay when adding new fields, so you can add many fields very quickly.
|
||||
|
||||
Even if Engineer does not support custom validators, it does support html5 form validation. For example, a number field will warn you if it's not a number. Engineer also escapes the data when needed before saving it.
|
||||
|
||||
## Built in field support
|
||||
|
||||
Engineer has some limitations but it supports almost every built in field. Read more about the [field support](docs/fields.md).
|
||||
|
||||
## Plugin field support
|
||||
|
||||
Most plugins will probably work out of the box, but there are some limitations. You need to try it out and see if it works. In the future I will probably add a list with supported plugin fields as well.
|
||||
|
||||
## Row limit
|
||||
|
||||
It's a planned feature but is not implemented in the current version.
|
||||
|
||||
## License needed
|
||||
|
||||
If you already bought a Kirby license, then the Structure field is free to use, because it's built in.
|
||||
|
||||
Engineer field have been taken some time to develop so I made the decision to take a license fee for it. That way I can continue to maintain it.
|
||||
43
site/OFF_plugins/field-engineer/docs/examples.md
Normal file
43
site/OFF_plugins/field-engineer/docs/examples.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Example from `readme.md`
|
||||
|
||||
If you want to recreate the example from the `readme.md`, here you go...
|
||||
|
||||
**Screenshot**
|
||||
|
||||

|
||||
|
||||
**Blueprint**
|
||||
|
||||
```text
|
||||
fields:
|
||||
my_engineer:
|
||||
type: engineer
|
||||
fields:
|
||||
my_image:
|
||||
label: Image
|
||||
type: image
|
||||
my_engineer:
|
||||
label: Engineer
|
||||
type: engineer
|
||||
fieldsets:
|
||||
set1:
|
||||
label: Set 1
|
||||
fields:
|
||||
my_image:
|
||||
type: image
|
||||
width: 1/2
|
||||
my_text:
|
||||
type: text
|
||||
width: 1/2
|
||||
set2:
|
||||
label: Set 2
|
||||
fields:
|
||||
my_toggle:
|
||||
label: Toggle
|
||||
type: toggle
|
||||
width: 1/2
|
||||
my_date:
|
||||
label: Date
|
||||
type: date
|
||||
width: 1/2
|
||||
```
|
||||
81
site/OFF_plugins/field-engineer/docs/fields.md
Normal file
81
site/OFF_plugins/field-engineer/docs/fields.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Fields
|
||||
|
||||
## Table of contents
|
||||
|
||||
1. [Subfields](#subfields)
|
||||
1. [Subfield options](#subfields)
|
||||
1. [Plugin fields](#plugin-fields)
|
||||
|
||||
### Subfields
|
||||
|
||||
Most of the built in Kirby fields will work as subfields to Engineer.
|
||||
|
||||
| Type | Supported | Comment
|
||||
| ---------------------------------------------------------------------------- | --------- | -------
|
||||
| [`checkbox`](https://getkirby.com/docs/cheatsheet/panel-fields/checkbox) | Yes |
|
||||
| [`checkboxes`](https://getkirby.com/docs/cheatsheet/panel-fields/checkboxes) | Yes |
|
||||
| [`date`](https://getkirby.com/docs/cheatsheet/panel-fields/date) | Yes |
|
||||
| [`datetime`](https://getkirby.com/docs/cheatsheet/panel-fields/datetime) | Yes |
|
||||
| [`email`](https://getkirby.com/docs/cheatsheet/panel-fields/email) | Yes |
|
||||
| [`headline`](https://getkirby.com/docs/cheatsheet/panel-fields/headline) | Yes |
|
||||
| [`hidden`](https://getkirby.com/docs/cheatsheet/panel-fields/hidden) | - |
|
||||
| [`image`](https://getkirby.com/docs/cheatsheet/panel-fields/image) | Yes |
|
||||
| [`info`](https://getkirby.com/docs/cheatsheet/panel-fields/info) | Yes |
|
||||
| [`line`](https://getkirby.com/docs/cheatsheet/panel-fields/line) | Yes |
|
||||
| [`number`](https://getkirby.com/docs/cheatsheet/panel-fields/number) | Yes |
|
||||
| [`page`](https://getkirby.com/docs/cheatsheet/panel-fields/page) | Yes |
|
||||
| [`radio`](https://getkirby.com/docs/cheatsheet/panel-fields/radiobuttons) | Yes |
|
||||
| [`select`](https://getkirby.com/docs/cheatsheet/panel-fields/select) | Yes |
|
||||
| [`structure`](https://getkirby.com/docs/cheatsheet/panel-fields/structure) | - |
|
||||
| [`tags`](https://getkirby.com/docs/cheatsheet/panel-fields/tags) | - | DOM issues
|
||||
| [`tel`](https://getkirby.com/docs/cheatsheet/panel-fields/tel) | Yes |
|
||||
| [`text`](https://getkirby.com/docs/cheatsheet/panel-fields/text) | Yes |
|
||||
| [`textarea`](https://getkirby.com/docs/cheatsheet/panel-fields/textarea) | Yes | Without help buttons
|
||||
| [`time`](https://getkirby.com/docs/cheatsheet/panel-fields/time) | Yes |
|
||||
| [`toggle`](https://getkirby.com/docs/cheatsheet/panel-fields/toggle) | Yes |
|
||||
| [`url`](https://getkirby.com/docs/cheatsheet/panel-fields/url) | Yes |
|
||||
| [`user`](https://getkirby.com/docs/cheatsheet/panel-fields/user) | Yes |
|
||||
|
||||
### Subfield options
|
||||
|
||||
Most of the Kirby field options will work. Be aware that these are the options of an Engineer subfield, not of the Engineer itself.
|
||||
|
||||
| Option | Supported | Comment
|
||||
| ------------------------------------------------------------------------------------------------------------------- | --------- | --------
|
||||
| [`default`](https://getkirby.com/docs/panel/blueprints/form-fields#default-values) | Yes |
|
||||
| [`help`](https://getkirby.com/docs/panel/blueprints/form-fields#field-instructions) | Yes |
|
||||
| [`icon`](https://getkirby.com/docs/panel/blueprints/form-fields#custom-icons) | Yes |
|
||||
| [`label`](https://getkirby.com/docs/panel/blueprints/form-fields) | Yes |
|
||||
| [`placeholder`](https://getkirby.com/docs/panel/blueprints/form-fields#placeholders) | Yes |
|
||||
| [`readonly`](https://getkirby.com/docs/panel/blueprints/form-fields#readonly-fields) | Yes |
|
||||
| [`required`](https://getkirby.com/docs/panel/blueprints/form-fields#required-fields) | Yes |
|
||||
| [`translate`](https://getkirby.com/docs/panel/blueprints/form-fields#prevent-field-values-in-non-default-languages) | - |
|
||||
| [`translations`](https://getkirby.com/docs/panel/blueprints/form-fields#translating-form-fields) | - |
|
||||
| [`type`](https://getkirby.com/docs/panel/blueprints/form-fields) | Yes |
|
||||
| [`validate`](https://getkirby.com/docs/panel/blueprints/form-fields#validation) | - | Only min / max with js
|
||||
| [`width`](https://getkirby.com/docs/panel/blueprints/form-fields#creating-grids) | Yes |
|
||||
|
||||
## Plugin fields
|
||||
|
||||
Many fields will work out of the box with Engineer. Here are a few of the most popular relevant fields that works.
|
||||
|
||||
### Works out of the box
|
||||
|
||||
| Plugin field | Tested | Has blueprint test
|
||||
| ----------------------------------------------------------------------- | ---------------------------
|
||||
| [Controlled list](https://github.com/rasteiner/controlledlist) | Yes | Yes
|
||||
| [Kirby date field](https://github.com/iksi/KirbyDateField) | Yes | -
|
||||
| [Kirby country field](https://github.com/iksi/KirbyCountryField) | Yes | Tes
|
||||
| [Kirby decimal field](https://github.com/iksi/KirbyDecimalField) | Yes | Yes
|
||||
| [Kirby Logic Field](https://github.com/jenstornell/kirby-logic-field) | Yes | Yes
|
||||
| [Kirby time field](https://github.com/iksi/KirbyTimeField) | Yes | -
|
||||
| [Select a structure](https://github.com/CalebGrove/select-a-structure) | Yes | Yes
|
||||
| [Switch field](https://github.com/distantnative/field-switch) | Yes | Yes
|
||||
|
||||
### Supported by Engineer
|
||||
|
||||
| Plugin field | Supported | Has blueprint test
|
||||
| ----------------------------------------------------------------------- | ------------------------------
|
||||
| [Kirby Hero Field](https://github.com/jenstornell/kirby-hero-field) | Yes | Yes
|
||||
| [Kirby Images](https://github.com/medienbaecker/kirby-images) | Yes | Yes
|
||||
| [Kirby Quickselect](https://github.com/medienbaecker/kirby-quickselect) | Yes | Yes
|
||||
BIN
site/OFF_plugins/field-engineer/docs/fieldsets.png
Normal file
BIN
site/OFF_plugins/field-engineer/docs/fieldsets.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
BIN
site/OFF_plugins/field-engineer/docs/hero.png
Normal file
BIN
site/OFF_plugins/field-engineer/docs/hero.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
32
site/OFF_plugins/field-engineer/docs/install.md
Normal file
32
site/OFF_plugins/field-engineer/docs/install.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Installation
|
||||
|
||||
Use **one** of the alternatives below.
|
||||
|
||||
## Kirby CLI
|
||||
|
||||
If you are using the [Kirby CLI](https://github.com/getkirby/cli) you can install this plugin by running the following commands in your shell:
|
||||
|
||||
```text
|
||||
$ cd path/to/kirby
|
||||
$ kirby plugin:install jenstornell/field-engineer
|
||||
```
|
||||
|
||||
## Clone or download
|
||||
|
||||
1. [Clone](https://github.com/jenstornell/field-engineer.git) or [download](https://github.com/jenstornell/field-engineer/archive/master.zip) this repository.
|
||||
2. Unzip the archive if needed and rename the folder to `field-engineer`.
|
||||
|
||||
**Make sure that the plugin folder structure looks like this:**
|
||||
|
||||
```text
|
||||
site/plugins/field-engineer/
|
||||
```
|
||||
|
||||
## Git Submodule
|
||||
|
||||
If you know your way around Git, you can download this plugin as a submodule:
|
||||
|
||||
```text
|
||||
$ cd path/to/kirby
|
||||
$ git submodule add https://github.com/jenstornell/field-engineer site/plugins/field-engineer
|
||||
```
|
||||
39
site/OFF_plugins/field-engineer/docs/license.md
Normal file
39
site/OFF_plugins/field-engineer/docs/license.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# License
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/jenstornell/field-engineer/issues/new).
|
||||
|
||||
## Try it out first
|
||||
|
||||
Try it out on a development environment before you buy. You don't need to pay before you are happy with the plugin.
|
||||
|
||||
## When you need a license
|
||||
|
||||
When you are using it for a live project, you need to pay a license for it. You need one license for each domain.
|
||||
|
||||
## When you don't need a license
|
||||
|
||||
- Test environments for trying the plugin
|
||||
- Development and staging enviroments, which are not ment for public use
|
||||
- Backups
|
||||
|
||||
## Support
|
||||
|
||||
No support are included in the license. However, I try to always be helpful. You can [create a new issue](https://github.com/jenstornell/field-engineer/issues/new) if you get into some kind of trouble.
|
||||
|
||||
## Refunds
|
||||
|
||||
Refunds are not supported.
|
||||
|
||||
## License code
|
||||
|
||||
You will not get a license code for this plugin, at least not with this version.
|
||||
|
||||
## Purchase
|
||||
|
||||
Buying licenses is a good way to support this project.
|
||||
|
||||
***The purchase button is temporary disabled***
|
||||
|
||||
**Price:** 50 EUR (on each project/domain)
|
||||
BIN
site/OFF_plugins/field-engineer/docs/nesting.png
Normal file
BIN
site/OFF_plugins/field-engineer/docs/nesting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
9
site/OFF_plugins/field-engineer/docs/options.md
Normal file
9
site/OFF_plugins/field-engineer/docs/options.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Options
|
||||
|
||||
```php
|
||||
c::set('engineer.debug', false);
|
||||
```
|
||||
|
||||
### engineer.debug
|
||||
|
||||
If this option is set to `true`, it's possible to see the pre-generated outline, as well as an output textarea. It can be useful for debugging.
|
||||
BIN
site/OFF_plugins/field-engineer/docs/presentation.png
Normal file
BIN
site/OFF_plugins/field-engineer/docs/presentation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
site/OFF_plugins/field-engineer/docs/screenshot.png
Normal file
BIN
site/OFF_plugins/field-engineer/docs/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
27
site/OFF_plugins/field-engineer/docs/screenshots.md
Normal file
27
site/OFF_plugins/field-engineer/docs/screenshots.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Screenshots
|
||||
|
||||
Here are some different examples of what you can do.
|
||||
|
||||
**Field rows**
|
||||
|
||||
Add an unlimted number of rows with fields.
|
||||
|
||||
[](docs/presentation.png)
|
||||
|
||||
**Fieldsets**
|
||||
|
||||
If needed, you can use a set of fields to output different kind of field rows.
|
||||
|
||||
[](docs/fieldsets.png)
|
||||
|
||||
**Nesting**
|
||||
|
||||
It's possible nest Engineer fields in the blueprint. There is no depth limit.
|
||||
|
||||
[](docs/nesting.png)
|
||||
|
||||
**Sorting**
|
||||
|
||||
Sort the rows by drag and drop or by the sort arrows.
|
||||
|
||||
[](docs/sorting.png)
|
||||
BIN
site/OFF_plugins/field-engineer/docs/sorting.png
Normal file
BIN
site/OFF_plugins/field-engineer/docs/sorting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
11
site/OFF_plugins/field-engineer/docs/templates-snippets.md
Normal file
11
site/OFF_plugins/field-engineer/docs/templates-snippets.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Templates and snippets
|
||||
|
||||
Engineer saved the data similar to the [structure](https://getkirby.com/docs/cheatsheet/panel-fields/structure) field.
|
||||
|
||||
### toStructure
|
||||
|
||||
If you only use one level in depth and don't use multiple fieldsets you should be fine using [toStructure](https://getkirby.com/docs/cheatsheet/field-methods/toStructure).
|
||||
|
||||
### yaml
|
||||
|
||||
If you use a more complex structure you can use [yaml as a custom field method](https://getkirby.com/docs/cheatsheet/field-methods/yaml) or the [yaml method](https://getkirby.com/docs/toolkit/api/helpers/yaml).
|
||||
42
site/OFF_plugins/field-engineer/docs/troubleshooting.md
Normal file
42
site/OFF_plugins/field-engineer/docs/troubleshooting.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Troubleshooting
|
||||
|
||||
## Why an error can appear
|
||||
|
||||
### Blueprint has changed
|
||||
|
||||
The most common reason for an error is by my experience when you have saved data in the Engineer field and then change the blueprint. Maybe a field type is changed or something structural. That can make Engineer confused on how to read the data and in some cases throw an error.
|
||||
|
||||
## Prevent errors
|
||||
|
||||
First of all, in most cases you can change things in the blueprint without breaking Engineer, even when you have data saved.
|
||||
|
||||
- The provent errors from happening, set up the blueprint structure first and add things to it after that.
|
||||
- If you need to change something, it's often safer to add something new than to edit the field type when the field already has content.
|
||||
|
||||
## On error
|
||||
|
||||
If you are experience an error, there are some things you can do.
|
||||
|
||||
### Logout
|
||||
|
||||
In some cases the data is stored in the session. You can try to logout and then login again. That way the session is cleaned up.
|
||||
|
||||
### Reset content
|
||||
|
||||
If the logout solution does not work, the problem might be that the content does no longer match the blueprint. Try to manually delete the rows in the content text file that has to do with the Engineer field.
|
||||
|
||||
### Turn debug on
|
||||
|
||||
To see more of what the Engineer field does, turn debug mode on by adding this line to your `config.php`:
|
||||
|
||||
```php
|
||||
c::set('engineer.debug', true);
|
||||
```
|
||||
|
||||
### Ask the forum
|
||||
|
||||
If it's a support question, you can ask it on https://forum.getkirby.com. You can tag me with @jenstornell to make me aware of the question.
|
||||
|
||||
### Add an issue
|
||||
|
||||
Maybe it's not your fault at all, but you have actually found a bug. In that case [create a new issue](https://github.com/jenstornell/field-engineer/issues/new) and I will look into it.
|
||||
41
site/OFF_plugins/field-engineer/docs/usage.md
Normal file
41
site/OFF_plugins/field-engineer/docs/usage.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Usage
|
||||
|
||||
## Edit an item
|
||||
|
||||
As you can see on the screenshot below there is only one row containing the buttons delete, clone etc. That's because you first need to click on the item you want to edit.
|
||||
|
||||
In this case I've clicked on the "nature" item. You could for example instead have clicked on the "toggle" item, or the whole white block which is an item as well.
|
||||
|
||||

|
||||
|
||||
## Buttons explained
|
||||
|
||||
### Delete
|
||||
|
||||
Deletes the current item. Be aware! This can NOT be undone!
|
||||
|
||||
### Clone
|
||||
|
||||
It will make a clone/copy of the current item including it's sub items and will place it directly after the original.
|
||||
|
||||
### Sorting
|
||||
|
||||
**Sort down**
|
||||
|
||||
In the screenshot, there is an arrow down. Clicking on it will make the item move one step down in the current level. On this item there is no arrow up because we are already on the first item.
|
||||
|
||||
**Sort up**
|
||||
|
||||
The arrow up will do the same thing but up one step and it will be shown on items that have at least one item above.
|
||||
|
||||
**Drag & Drop**
|
||||
|
||||
With the arrow move cross you can drag and drop an item to sort it. It's only possible to sort an item to other items within the same level.
|
||||
|
||||
### Add - With an arrow down icon
|
||||
|
||||
The arrow down icon next to the "Add" button indicates that there are more than one fieldset. Clicking it will bring a dropdown list for you to select the fieldset you want.
|
||||
|
||||
### Add - With a plus icon
|
||||
|
||||
The plus icon next to the "Add" button indicates that there is only one fieldset. Clicking it will add a new set with fields.
|
||||
38
site/OFF_plugins/field-engineer/field-engineer.php
Normal file
38
site/OFF_plugins/field-engineer/field-engineer.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
if(class_exists('Panel') && site()->user()) {
|
||||
require_once __DIR__ . DS . 'lib' . DS . 'form.php';
|
||||
require_once __DIR__ . DS . 'lib' . DS . 'field.php';
|
||||
require_once __DIR__ . DS . 'lib' . DS . 'tpl.php';
|
||||
require_once __DIR__ . DS . 'lib' . DS . 'presentation.php';
|
||||
require_once __DIR__ . DS . 'lib' . DS . 'presentation-array.php';
|
||||
require_once __DIR__ . DS . 'lib' . DS . 'outline.php';
|
||||
|
||||
if(c::get('engineer.debug', false)) {
|
||||
c::set('plugin.logic.field', function($field, $page) {
|
||||
return '<p><strong>Field name:</strong> ' . $field->name() . '<br><strong>Panel page</strong>: ' . $page->title() . '</p>';
|
||||
});
|
||||
|
||||
foreach(glob(__DIR__ . DS . 'tests' . DS . 'blueprints' . DS . '*') as $filename) {
|
||||
$parts = pathinfo($filename);
|
||||
$kirby->set('blueprint', $parts['filename'], $filename);
|
||||
}
|
||||
|
||||
class MyPlugin {
|
||||
static function userlist($field) {
|
||||
$kirby = kirby();
|
||||
$site = $kirby->site();
|
||||
$users = $site->users();
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($users as $user) {
|
||||
$result[$user->username] = $user->firstName() . ' ' . $user->lastName();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$kirby->set('field', 'engineer', __DIR__ . DS . 'fields' . DS . 'engineer');
|
||||
}
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
.egr {
|
||||
margin-left: -1.5em;
|
||||
margin-bottom: -1.5em; }
|
||||
|
||||
.egr-row {
|
||||
margin-left: 1.5em;
|
||||
width: calc(100% - 1.5em);
|
||||
padding-bottom: 1.5em; }
|
||||
|
||||
.egr-fieldsets {
|
||||
position: relative; }
|
||||
|
||||
.egr-fieldset {
|
||||
padding-top: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
border: 2px solid #ddd;
|
||||
background: #fff;
|
||||
position: relative; }
|
||||
|
||||
.egr-even > .egr-fieldsets > .egr-fieldset {
|
||||
background: #eee; }
|
||||
|
||||
.egr-outline {
|
||||
display: none; }
|
||||
|
||||
.egr-fields {
|
||||
flex: 1; }
|
||||
|
||||
.egr-actions {
|
||||
width: calc(100% + 1.5em);
|
||||
display: none;
|
||||
justify-content: center;
|
||||
border-top: 1px solid #ddd; }
|
||||
.egr-actions > * {
|
||||
height: 2.5em;
|
||||
line-height: 2.5em;
|
||||
cursor: pointer;
|
||||
padding-right: 1.5em;
|
||||
padding-left: 1.5em;
|
||||
user-select: none;
|
||||
border-right: 1px solid #ddd; }
|
||||
.egr-actions > *:last-child {
|
||||
border-right: none; }
|
||||
|
||||
.egr-even .egr-actions {
|
||||
border-top: 1px solid #ccc; }
|
||||
.egr-even .egr-actions > * {
|
||||
border-right: 1px solid #ccc; }
|
||||
.egr-even .egr-actions > *:last-child {
|
||||
border-right: none; }
|
||||
|
||||
.egr-row[data-count="0"] > .egr-empty {
|
||||
display: block; }
|
||||
|
||||
.egr-row[data-count="0"] > .egr-row-actions {
|
||||
display: none; }
|
||||
|
||||
.egr-dropdown-active .egr-add-button:before {
|
||||
display: block; }
|
||||
|
||||
.egr-dropdown {
|
||||
position: absolute;
|
||||
background: #000;
|
||||
border-radius: 4px;
|
||||
right: 0;
|
||||
z-index: 10000;
|
||||
display: none;
|
||||
margin-top: .4em; }
|
||||
.egr-dropdown:before {
|
||||
content: '';
|
||||
border-left: .4em solid transparent;
|
||||
border-right: .4em solid transparent;
|
||||
border-bottom: .4em solid #000;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
margin-top: -.3em; }
|
||||
|
||||
.egr-empty .egr-dropdown:before {
|
||||
left: 2em; }
|
||||
|
||||
.egr-row-actions .egr-dropdown:before {
|
||||
left: calc(100% - 2.4em); }
|
||||
|
||||
.egr-dropdown-active .egr-dropdown {
|
||||
display: block; }
|
||||
|
||||
.egr-dropdown-active .egr-add-button .icon {
|
||||
transform: rotateX(180deg); }
|
||||
|
||||
.egr-empty {
|
||||
padding: 1.5em;
|
||||
background: #ddd;
|
||||
display: none; }
|
||||
.egr-empty .egr-add-button {
|
||||
border-bottom: 2px solid #aaa;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
display: inline-block; }
|
||||
.egr-empty .egr-add-button .egr-dropdown {
|
||||
right: auto;
|
||||
margin-top: .7em; }
|
||||
|
||||
.egr-output {
|
||||
margin-left: 1.5em;
|
||||
width: calc(100% - 1.5em);
|
||||
padding-bottom: 1.5em;
|
||||
display: none; }
|
||||
.egr-output textarea {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
border: 2px solid #ddd;
|
||||
padding: .5em;
|
||||
font-size: .9em;
|
||||
outline: none; }
|
||||
|
||||
.egr-outline {
|
||||
opacity: .5; }
|
||||
|
||||
.egr .ui-sortable-helper {
|
||||
border-bottom: 2px solid #ddd; }
|
||||
|
||||
.egr-presentation .egr-fieldset:first-child > .egr-actions > .egr-sort-up {
|
||||
display: none; }
|
||||
|
||||
.egr-presentation .egr-fieldset:last-child > .egr-actions > .egr-sort-down {
|
||||
display: none; }
|
||||
|
||||
.egr-presentation .egr-fieldset:only-child > .egr-actions > .egr-sort-up,
|
||||
.egr-presentation .egr-fieldset:only-child > .egr-actions > .egr-sort-down,
|
||||
.egr-presentation .egr-fieldset:only-child > .egr-actions > .egr-sorting {
|
||||
display: none; }
|
||||
|
||||
.egr-row-actions {
|
||||
margin-top: .5em; }
|
||||
.egr-row-actions:after {
|
||||
clear: both;
|
||||
content: '';
|
||||
display: table; }
|
||||
|
||||
.egr-add-button {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
user-select: none; }
|
||||
.egr-add-button span {
|
||||
color: #777; }
|
||||
.egr-add-button:hover span {
|
||||
color: #000; }
|
||||
|
||||
.egr-add {
|
||||
float: right; }
|
||||
|
||||
.egr-add-select {
|
||||
padding: .75em 1.5em .75em 1.5em;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #222;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
user-select: none; }
|
||||
.egr-add-select:hover {
|
||||
color: #999; }
|
||||
.egr-add-select:last-child {
|
||||
border-bottom: 0; }
|
||||
|
||||
.egr-dropdown-active .egr-add-button:before {
|
||||
display: block; }
|
||||
|
||||
.egr-grid-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap; }
|
||||
|
||||
.egr-fieldset {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between; }
|
||||
|
||||
@media screen and (min-width: 60em) {
|
||||
.egr-grid-item {
|
||||
width: calc(100% + 1.5em); }
|
||||
.egr-fieldset {
|
||||
margin-right: 1.5em;
|
||||
margin-bottom: 1.5em; }
|
||||
.egr-grid-item-1-2 > .egr-fieldset {
|
||||
width: calc(100% / 2 - 1.5em); }
|
||||
.egr-grid-item-1-3 > .egr-fieldset {
|
||||
width: calc(100% / 3 - 1.5em); }
|
||||
.egr-grid-item-1-4 > .egr-fieldset {
|
||||
width: calc(100% / 4 - 1.5em); }
|
||||
.egr-grid-item-1-5 > .egr-fieldset {
|
||||
width: calc(100% / 5 - 1.5em); } }
|
||||
|
||||
.egr-element-delete {
|
||||
width: calc(100% + 1.5em);
|
||||
z-index: 100;
|
||||
background: #fff;
|
||||
display: flex; }
|
||||
.egr-element-delete .egr-delete-message {
|
||||
padding: 1.5em;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin: 0 auto; }
|
||||
|
||||
.egr-delete-buttons {
|
||||
max-width: 20em;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
margin-top: .5em; }
|
||||
.egr-delete-buttons > * {
|
||||
cursor: pointer;
|
||||
line-height: 2em; }
|
||||
|
||||
.egr-delete-cancel {
|
||||
padding: 0 .5em;
|
||||
color: #777;
|
||||
border: 2px solid transparent; }
|
||||
.egr-delete-cancel span {
|
||||
border-bottom: 2px solid #eee; }
|
||||
.egr-delete-cancel:hover {
|
||||
color: #000; }
|
||||
.egr-delete-cancel:hover span {
|
||||
border-bottom: 2px solid #ccc; }
|
||||
|
||||
.egr-delete-apply {
|
||||
border-radius: .3em;
|
||||
padding: 0 1em;
|
||||
color: #b3000a;
|
||||
border: 2px solid #b3000a;
|
||||
font-weight: bold; }
|
||||
.egr-delete-apply:hover {
|
||||
color: #fff;
|
||||
background: #b3000a; }
|
||||
|
||||
.egr-delete-active {
|
||||
position: relative; }
|
||||
|
||||
.egr-delete-active .egr-fields:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: #b3000a;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
opacity: .2; }
|
||||
|
||||
.egr-style-table > .egr-fieldsets {
|
||||
border: 2px solid #ddd; }
|
||||
.egr-style-table > .egr-fieldsets > .egr-fieldset {
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
padding-top: .5em;
|
||||
padding-right: .5em; }
|
||||
.egr-style-table > .egr-fieldsets > .egr-fieldset:last-child {
|
||||
border-bottom: 0; }
|
||||
.egr-style-table > .egr-fieldsets > .egr-fieldset:last-child > .egr-actions {
|
||||
border-bottom: 0; }
|
||||
.egr-style-table > .egr-fieldsets > .egr-fieldset > .egr-fields > .field {
|
||||
padding-left: .5em;
|
||||
margin-bottom: .5em; }
|
||||
.egr-style-table > .egr-fieldsets > .egr-fieldset > .egr-actions {
|
||||
width: calc(100% + .5em); }
|
||||
|
||||
.egr-style-table.egr-odd > .egr-fieldsets > .egr-labels {
|
||||
background: #fff; }
|
||||
|
||||
.egr-style-table.egr-odd > .egr-fieldsets > .egr-fieldset > .egr-actions {
|
||||
border-bottom: 1px solid #ddd; }
|
||||
|
||||
.egr-style-table.egr-even > .egr-fieldsets > .egr-labels {
|
||||
background: #eee; }
|
||||
|
||||
.egr-style-table.egr-even > .egr-fieldsets > .egr-fieldset > .egr-actions {
|
||||
border-bottom: 1px solid #ccc; }
|
||||
|
||||
.egr-labels {
|
||||
padding-top: 1em;
|
||||
padding-right: 1em;
|
||||
border-bottom: 1px solid #ddd; }
|
||||
.egr-labels > .field {
|
||||
margin-bottom: 0.5em;
|
||||
padding-left: 1em !important; }
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
site/OFF_plugins/field-engineer/fields/engineer/assets/css/style.min.css
vendored
Normal file
1
site/OFF_plugins/field-engineer/fields/engineer/assets/css/style.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,646 @@
|
|||
var EgrAdd = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.add = function(obj, this_obj) {
|
||||
var fieldset_name = fn.name(this_obj);
|
||||
var row = fn.row(this_obj);
|
||||
var fieldsets = fn.fieldsets(row);
|
||||
|
||||
fieldsets.append(fn.matchFieldset(row, fieldset_name, obj).clone());
|
||||
EgrId.replace(fieldsets.children('.egr-fieldset').last());
|
||||
|
||||
EgrSort.sort(this_obj);
|
||||
EgrCount.trigger(obj, this_obj);
|
||||
EgrTrigger.trigger(row);
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.name = function(this_obj) {
|
||||
return this_obj.attr('data-add');
|
||||
};
|
||||
|
||||
fn.row = function(this_obj) {
|
||||
return this_obj.closest('.egr-row');
|
||||
};
|
||||
|
||||
fn.id = function(row) {
|
||||
return row.attr('data-id');
|
||||
};
|
||||
|
||||
fn.fieldsets = function(row) {
|
||||
return row.children('.egr-fieldsets');
|
||||
};
|
||||
|
||||
fn.matchRow = function(row, obj) {
|
||||
var id = fn.id(row);
|
||||
return $('.egr-outline[data-id="' + obj.attr('data-name') + '"] .egr-row[data-id="' + id + '"]');
|
||||
};
|
||||
|
||||
fn.matchFieldsets = function(row, obj) {
|
||||
var match_row = fn.matchRow(row, obj);
|
||||
return match_row.children('.egr-fieldsets');
|
||||
};
|
||||
|
||||
fn.matchFieldset = function(row, fieldset_name, obj) {
|
||||
var match_fieldsets = fn.matchFieldsets(row, obj);
|
||||
return match_fieldsets.children('[data-fieldset-name="' + fieldset_name + '"]');
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrClone = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.clone = function(obj, this_obj) {
|
||||
var fieldset = this_obj.closest('.egr-fieldset');
|
||||
var cloned = fn.duplicate(fieldset);
|
||||
|
||||
fn.setSelects(cloned, fn.getSelects(fieldset));
|
||||
EgrId.replace(cloned);
|
||||
EgrCount.trigger(obj, this_obj);
|
||||
EgrTrigger.trigger(this_obj.closest('.egr-row'));
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.duplicate = function(fieldset) {
|
||||
var cloned = fieldset.clone(true);
|
||||
fieldset.after(cloned);
|
||||
return fieldset.next();
|
||||
};
|
||||
|
||||
fn.getSelects = function(fieldset) {
|
||||
var array = [];
|
||||
var i = 0;
|
||||
fieldset.find('select').each(function(index) {
|
||||
$(this).val();
|
||||
array[i] = $(this).val();
|
||||
i++;
|
||||
});
|
||||
return array;
|
||||
};
|
||||
|
||||
fn.setSelects = function(next, select_values) {
|
||||
var i = 0;
|
||||
next.find('select').each(function(index) {
|
||||
$(this).val(select_values[i]);
|
||||
i++;
|
||||
});
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrCount = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.trigger = function(obj, this_obj) {
|
||||
var row = this_obj.closest('.egr-row');
|
||||
var fieldsets = row.children('.egr-fieldsets');
|
||||
var fieldset = fieldsets.children('.egr-fieldset');
|
||||
var count = fieldset.length;
|
||||
row.attr('data-count', count);
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrDelete = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.deleteMessage = function(obj, this_obj) {
|
||||
var delete_message = $(document).find('.egr-outline .egr-element-delete').first();
|
||||
fn.deleteCancel(obj, this_obj);
|
||||
obj.find('.egr-actions').hide();
|
||||
this_obj.closest('.egr-fieldset').addClass('egr-delete-active');
|
||||
this_obj.closest('.egr-fieldset').append(delete_message.clone());
|
||||
};
|
||||
|
||||
fn.deleteAction = function(obj, this_obj) {
|
||||
var fieldsets = this_obj.closest('.egr-fieldsets');
|
||||
this_obj.closest('.egr-fieldset').remove();
|
||||
EgrSort.sort(obj);
|
||||
EgrCount.trigger(obj, fieldsets);
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.deleteCancel = function(obj, this_obj) {
|
||||
obj.find('.egr-element-delete').remove();
|
||||
obj.find('.egr-delete-active').removeClass('egr-delete-active');
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrId = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.replace = function(fieldset) {
|
||||
var time = new Date().getTime();
|
||||
|
||||
fn.replaceIds(fieldset, time);
|
||||
fn.replaceFors(fieldset, time);
|
||||
fn.replaceClasses(fieldset, time);
|
||||
fn.replaceNames(fieldset, time);
|
||||
fn.replacePrefixes(fieldset, time);
|
||||
|
||||
fn.addFieldsetCount(fieldset);
|
||||
};
|
||||
|
||||
fn.replaceIds = function(fieldset, time) {
|
||||
var matches = fieldset.find('[id^="form-field-"]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('id').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('id', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replaceFors = function(fieldset, time) {
|
||||
var matches = fieldset.find('[for^="form-field-"]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('for').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('for', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replaceClasses = function(fieldset, time) {
|
||||
var matches = fieldset.find('[data-field-name][class^="field "]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('class').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('class', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replaceNames = function(fieldset, time) {
|
||||
var matches = fieldset.find('[name]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('name').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('name', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.replacePrefixes = function(fieldset, time) {
|
||||
var matches = fieldset.find('[data-prefix]');
|
||||
matches.each(function(index) {
|
||||
var element = $(this).attr('data-prefix').replace(/_egr__/g, '_' + time + '_egr__');
|
||||
$(this).attr('data-prefix', element);
|
||||
});
|
||||
};
|
||||
|
||||
fn.addFieldsetCount = function(fieldset) {
|
||||
var row = fieldset.closest('.egr-row');
|
||||
var fieldset_count = row.children('.egr-row-actions').find('.egr-add-select').length;
|
||||
fieldset_count = (fieldset_count == 0) ? 1 : fieldset_count;
|
||||
row.attr('data-fieldset-count', fieldset_count);
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrOutline = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.set = function(obj) {
|
||||
var outline = obj.find('.egr-outline');
|
||||
var name = obj.attr('data-name');
|
||||
|
||||
$('.mainbar').children('.section').prepend('<div class="egr-outline" data-id="' + name + '">' + outline.html() + "</div>");
|
||||
outline.remove();
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
EgrRender = (function () {
|
||||
var fn = {};
|
||||
var level = 1;
|
||||
|
||||
fn.render = function(obj) {
|
||||
var output = '';
|
||||
var fields = obj.find('.egr-presentation').children();
|
||||
var out = '';
|
||||
var textarea = obj.find('.egr-output').find('textarea');
|
||||
out = fn.renderLoop(fields, out, level, true);
|
||||
textarea.val(out);
|
||||
textarea.blur();
|
||||
};
|
||||
|
||||
fn.renderLoop = function(fields, out, root_field) {
|
||||
fields.each(function(field_index) {
|
||||
var field = $(this);
|
||||
var field_name = field.attr('data-field-name');
|
||||
var depth = field.parents('.egr-row').length;
|
||||
var tab = ' '.repeat(depth);
|
||||
|
||||
if(field.hasClass('egr-row')) {
|
||||
if(!root_field) {
|
||||
out += tab + field_name + ":\n";
|
||||
}
|
||||
var fieldsets = $(this).children('.egr-fieldsets').children();
|
||||
if(depth > 0) tab += ' ';
|
||||
fieldsets.each(function(fieldset_index) {
|
||||
var fieldset = $(this);
|
||||
var subfields = fieldset.children('.egr-fields').children();
|
||||
|
||||
if(fieldset.attr('data-fieldset-name') != undefined) {
|
||||
out += tab + "-\n";
|
||||
out += fn.setFieldsetName(tab, field, fieldset);
|
||||
}
|
||||
out = fn.renderLoop(subfields, out, false);
|
||||
});
|
||||
} else {
|
||||
var fieldset = field.parent().parent();
|
||||
var selector = fn.getSelector(field_name, field);
|
||||
var element = fn.findFormElement(selector, field);
|
||||
var content = fn.getElement(element, field_name, tab);
|
||||
|
||||
if(content) {
|
||||
out += tab + content;
|
||||
}
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
fn.getSelector = function(field_name, field) {
|
||||
var selector = field_name + field.attr('data-prefix');
|
||||
return selector;
|
||||
};
|
||||
|
||||
fn.findFormElement = function(selector, field) {
|
||||
var single = '[name="' + selector + '"]:not(label)';
|
||||
var multiple = '[name^="' + selector + '["]:not(label)';
|
||||
var element = field.find(single + ',' + multiple);
|
||||
return element;
|
||||
};
|
||||
|
||||
fn.getElement = function(element, field_name, tab) {
|
||||
var elementType = element.prop('nodeName');
|
||||
var is_single = (element.length < 2) ? true : false;
|
||||
var output = '';
|
||||
|
||||
switch(elementType) {
|
||||
case 'TEXTAREA':
|
||||
output += fn.textarea(element, field_name, tab);
|
||||
break;
|
||||
case 'INPUT':
|
||||
switch(element.attr('type')) {
|
||||
case 'radio':
|
||||
output += fn.radio(element, field_name, tab);
|
||||
break;
|
||||
case 'checkbox':
|
||||
if(is_single) {
|
||||
output += fn.checkbox(element, field_name, tab);
|
||||
} else {
|
||||
output += fn.checkboxes(element, field_name, tab);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(element.hasClass('images')) {
|
||||
output += fn.textarea(element, field_name, tab);
|
||||
} else {
|
||||
if(is_single) {
|
||||
output += fn.input(element, field_name, is_single, tab);
|
||||
} else {
|
||||
if(field_name == 'datetime') {
|
||||
output += fn.input(element, field_name);
|
||||
} else {
|
||||
output += fn.inputs(element, field_name, tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'SELECT':
|
||||
output += fn.select(element, field_name, tab);
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
fn.setFieldsetName = function(tab, field, fieldset) {
|
||||
var fieldset_name = fieldset.attr('data-fieldset-name');
|
||||
var fieldset_count = field.attr('data-fieldset-count');
|
||||
if(fieldset_count == 1 && fieldset_name == 'default') {
|
||||
return '';
|
||||
}
|
||||
return tab + " _fieldset: " + fieldset_name + "\n";
|
||||
};
|
||||
|
||||
fn.inputs = function(element, field_name, tab) {
|
||||
var value = '';
|
||||
var indent = tab + ' ';
|
||||
|
||||
element.each(function( index ) {
|
||||
var val = $(this).val();
|
||||
val = val.replace(/"/g, '\\"');
|
||||
value += indent + '- "' + val + '"' + "\n";
|
||||
|
||||
});
|
||||
|
||||
value = value.slice(0, -1);
|
||||
return field_name + ": \n" + value + "\n";
|
||||
};
|
||||
|
||||
/* Input */
|
||||
fn.input = function(element, field_name) {
|
||||
var value = '';
|
||||
|
||||
element.each(function( index ) {
|
||||
value += $(this).val() + ' ';
|
||||
});
|
||||
value = value.slice(0, -1);
|
||||
value = value.replace(/"/g, '\\"');
|
||||
return field_name + ': "' + value + '"' + "\n";
|
||||
};
|
||||
|
||||
/* Textarea */
|
||||
fn.textarea = function(element, field_name, tab) {
|
||||
var value = element.val();
|
||||
var match = value.indexOf("\n");
|
||||
var indent = tab + ' ';
|
||||
|
||||
if(match > -1) {
|
||||
value = value.replace(/(?:\r\n|\r|\n)/g, "\n" + indent);
|
||||
if(value != '') {
|
||||
return field_name + ": |\n" + indent + value + "\n";
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return fn.input(element, field_name);
|
||||
};
|
||||
|
||||
/* Select */
|
||||
fn.select = function(element, field_name) {
|
||||
var value = element.val();
|
||||
value = value.replace(/"/g, '\\"');
|
||||
return field_name + ': "' + value + '"' + "\n";
|
||||
};
|
||||
|
||||
/* Radio */
|
||||
fn.radio = function(element, field_name) {
|
||||
out = '';
|
||||
element.each(function(index) {
|
||||
if($(this).is(':checked')) {
|
||||
var value = $(this).val();
|
||||
if(value == 'true' || value == 'false') {
|
||||
value = "'" + value + "'";
|
||||
}
|
||||
out += field_name + ": " + value + "\n";
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
/* Checkbox */
|
||||
fn.checkbox = function(element, field_name) {
|
||||
out = '';
|
||||
element.each(function(index) {
|
||||
if($(this).is(':checked')) {
|
||||
var value = $(this).val();
|
||||
if(value == 'on') {
|
||||
value = 'true';
|
||||
}
|
||||
out += field_name + ': ' + value + "\n";
|
||||
} else {
|
||||
out += field_name + ": false\n";
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
/* Checkboxes */
|
||||
fn.checkboxes = function(element, field_name, tab) {
|
||||
out = '';
|
||||
element.each(function(index) {
|
||||
if($(this).is(':checked')) {
|
||||
out += tab + ' - ' + $(this).val() + "\n";
|
||||
}
|
||||
});
|
||||
if(out != '') {
|
||||
out = field_name + ":\n" + out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
return fn;
|
||||
})();
|
||||
(function($) {
|
||||
$.fn.engineer = function() {
|
||||
return this.each(function() {
|
||||
var field = $(this);
|
||||
var fieldname = 'engineer';
|
||||
|
||||
if(field.data( fieldname )) {
|
||||
return true;
|
||||
} else {
|
||||
field.data( fieldname, true );
|
||||
}
|
||||
|
||||
EgrOutline.set(field);
|
||||
|
||||
field.on('click', '.egr [data-add]', function() {
|
||||
EgrAdd.add(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-delete-apply', function() {
|
||||
EgrDelete.deleteAction(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-delete-cancel', function() {
|
||||
EgrDelete.deleteCancel(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-clone', function() {
|
||||
EgrClone.clone(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-fieldset', function(e) {
|
||||
if(!$(e.target).closest('.egr-fieldset').not(this).length){
|
||||
EgrToggleActive.toggle(field, $(this));
|
||||
}
|
||||
});
|
||||
|
||||
field.on('click', '.egr-delete', function() {
|
||||
EgrDelete.deleteMessage(field, $(this));
|
||||
});
|
||||
|
||||
$(document).on('click', function(e) {
|
||||
if(!$(e.target).closest('.egr-add-button').not(this).length) {
|
||||
$(document).find('.egr-dropdown-active').removeClass('egr-dropdown-active');
|
||||
}
|
||||
if(!$(e.target).closest('.egr-fieldset').not(this).length) {
|
||||
EgrToggleActive.remove(field, $(this));
|
||||
}
|
||||
});
|
||||
|
||||
field.on('click', '.egr-sort-up', function(e) {
|
||||
EgrSort.sortUp(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-sort-down', function(e) {
|
||||
EgrSort.sortDown(field, $(this));
|
||||
});
|
||||
|
||||
field.on('click', '.egr-add-button', function(e) {
|
||||
if(!$(e.target).closest('.egr-add-button').not(this).length){
|
||||
EgrToggleDropdown.toggle(field, $(this));
|
||||
}
|
||||
});
|
||||
|
||||
EgrSort.sort(field);
|
||||
|
||||
field.find('.egr-presentation').on('input click change', 'input, select, textarea', function() {
|
||||
EgrRender.render(field, $(this));
|
||||
});
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
var EgrSort = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.sort = function(obj) {
|
||||
var items = obj.find('.egr');
|
||||
var firstSort = true;
|
||||
items.sortable({
|
||||
items: '.egr-sorted-fieldset',
|
||||
handle: '.egr-sort',
|
||||
start: function(e, ui) {
|
||||
if(firstSort) {
|
||||
items.sortable('refreshPositions');
|
||||
firstSort = false;
|
||||
}
|
||||
},
|
||||
update: function( event, ui ) {
|
||||
EgrRender.render(obj);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
fn.removeClasses = function(obj, this_obj) {
|
||||
obj.find('.egr-sorted-row').removeClass('egr-sorted-row');
|
||||
obj.find('.egr-sorted-fieldsets').removeClass('egr-sorted-fieldsets');
|
||||
obj.find('.egr-sorted-fieldset').removeClass('egr-sorted-fieldset');
|
||||
};
|
||||
|
||||
fn.toggle = function(obj, this_obj) {
|
||||
var row = this_obj.closest('.egr-row');
|
||||
var fieldsets = row.children('.egr-fieldsets');
|
||||
var fieldset = fieldsets.children('.egr-fieldset');
|
||||
fn.removeClasses(obj, this_obj);
|
||||
row.addClass('egr-sorted-row');
|
||||
fieldsets.addClass('egr-sorted-fieldsets');
|
||||
fieldset.addClass('egr-sorted-fieldset');
|
||||
EgrSort.sort(obj);
|
||||
};
|
||||
|
||||
fn.sortUp = function(obj, this_obj) {
|
||||
var current = this_obj.closest('.egr-fieldset');
|
||||
var prev = current.prev();
|
||||
var cloned = prev.clone(true);
|
||||
current.after(cloned);
|
||||
prev.remove();
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
fn.sortDown = function(obj, this_obj) {
|
||||
var current = this_obj.closest('.egr-fieldset');
|
||||
var next = current.next();
|
||||
var cloned = next.clone(true);
|
||||
current.before(cloned);
|
||||
next.remove();
|
||||
EgrRender.render(obj);
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrToggleActive = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.toggle = function(obj, this_obj) {
|
||||
if(this_obj.hasClass('egr-delete-active')) return;
|
||||
|
||||
obj.find('.egr-actions').hide();
|
||||
this_obj.children('.egr-actions').css('display', 'flex');
|
||||
EgrSort.toggle(obj, this_obj);
|
||||
};
|
||||
|
||||
fn.remove = function(obj, this_obj) {
|
||||
obj.find('.egr-actions').hide();
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrToggleDropdown = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.toggle = function(obj, this_obj) {
|
||||
if(fn.count(this_obj) > 1) {
|
||||
if(this_obj.parent().hasClass('egr-dropdown-active')) {
|
||||
this_obj.parent().removeClass('egr-dropdown-active');
|
||||
} else {
|
||||
obj.find('.egr-dropdown-active').removeClass('egr-dropdown-active');
|
||||
this_obj.parent().addClass('egr-dropdown-active');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fn.count = function(this_obj) {
|
||||
return this_obj.find('.egr-add-select').length;
|
||||
};
|
||||
|
||||
return fn;
|
||||
})();
|
||||
var EgrTrigger = (function () {
|
||||
var fn = {};
|
||||
|
||||
fn.trigger = function(row) {
|
||||
fn.triggerFields(row);
|
||||
fn.triggerPlugins(row);
|
||||
|
||||
fn.checkDuplicates(row);
|
||||
};
|
||||
|
||||
fn.triggerFields = function(row) {
|
||||
row.find('[data-field="urlfield"]').removeData('urlfield').off('click').urlfield();
|
||||
row.find('[data-field="date"]').removeData('date').off('change').date();
|
||||
row.find('[data-field="imagefield"]').removeData('imagefield').imagefield();
|
||||
row.find('[data-field="autocomplete"]').removeData('autocomplete').off('keydown keyup').autocomplete();
|
||||
row.find('[data-field="editor"]').removeData('editor').off('keydown click').editor();
|
||||
row.find('[data-field="counter"]').removeData('counter').counter();
|
||||
};
|
||||
|
||||
fn.triggerPlugins = function(row) {
|
||||
if ( row.find('[data-field="images"]').length ) {
|
||||
row.find('[data-field="images"]').removeData('images').images();
|
||||
}
|
||||
if ( row.find('[data-field="hero"]').length ) {
|
||||
row.find('[data-field="hero"]').removeData('hero').hero();
|
||||
}
|
||||
if ( row.find('[data-field="quickselect"]').length ) {
|
||||
row.find('[data-field="quickselect"]').removeData('quickselect').quickselect();
|
||||
}
|
||||
if ( row.find('[data-field="list"]').length ) {
|
||||
row.find('[data-field="list"]').removeData('list').list();
|
||||
}
|
||||
};
|
||||
|
||||
fn.checkDuplicates = function(row) {
|
||||
var i = 0;
|
||||
var values = [];
|
||||
row.closest('.egr').find('.field').each(function( index ) {
|
||||
var classes = $(this).attr('class').split(" ");
|
||||
|
||||
$.each(classes, function( index, value ) {
|
||||
if(value.endsWith("_egr__")) {
|
||||
values[i] = value;
|
||||
i++;
|
||||
}
|
||||
});
|
||||
});
|
||||
if(fn.hasDuplicates(values)) {
|
||||
console.log('Error: There are duplicates!');
|
||||
}
|
||||
};
|
||||
|
||||
fn.hasDuplicates = function(array) {
|
||||
return (new Set(array)).size !== array.length;
|
||||
}
|
||||
|
||||
return fn;
|
||||
})();
|
||||
1
site/OFF_plugins/field-engineer/fields/engineer/assets/js/script.min.js
vendored
Normal file
1
site/OFF_plugins/field-engineer/fields/engineer/assets/js/script.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
75
site/OFF_plugins/field-engineer/fields/engineer/engineer.php
Normal file
75
site/OFF_plugins/field-engineer/fields/engineer/engineer.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
class EngineerField extends BaseField {
|
||||
static public $assets;
|
||||
|
||||
public function __construct() {
|
||||
$this->Presentation = new \Engineer\Presentation();
|
||||
$this->PresentationArray = new \Engineer\PresentationArray();
|
||||
$this->Outline = new \Engineer\Outline();
|
||||
$this->Field = new \Engineer\Field();
|
||||
}
|
||||
|
||||
public function presentation() {
|
||||
return $this->Presentation;
|
||||
}
|
||||
|
||||
public function presentationArray() {
|
||||
return $this->PresentationArray;
|
||||
}
|
||||
|
||||
public function outline() {
|
||||
return $this->Outline;
|
||||
}
|
||||
|
||||
public function setField() {
|
||||
return $this->Field();
|
||||
}
|
||||
|
||||
public function input() {
|
||||
$blueprint = $this->page->blueprint()->yaml['fields'][$this->name];
|
||||
|
||||
$outline = $this->outline()->set($blueprint, $this->name);
|
||||
$presentation_array = $this->presentationArray()->prepare($blueprint);
|
||||
|
||||
$presentation = $this->presentation()->set($presentation_array, yaml($this->value));
|
||||
unset($presentation['label']);
|
||||
|
||||
kirby()->set('option', 'egr.count', 0);
|
||||
|
||||
$args['args'] = array(
|
||||
'instance' => $this,
|
||||
'outline' => array(
|
||||
'instance' => $this,
|
||||
'outline' => $outline
|
||||
),
|
||||
'presentation' => array(
|
||||
'instance' => $this,
|
||||
'presentation' => $presentation,
|
||||
'field_name' => $this->name,
|
||||
'id' => $this->name
|
||||
),
|
||||
);
|
||||
|
||||
$template = egr::snippet('template', $args);
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function element() {
|
||||
$element = parent::element();
|
||||
$element->data('field', 'engineer');
|
||||
$element->data('name', $this->name);
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
if(c::get('engineer.debug', false)) {
|
||||
EngineerField::$assets = array(
|
||||
'css' => array('style.css'),
|
||||
'js' => array('script.js'),
|
||||
);
|
||||
} else {
|
||||
EngineerField::$assets = array(
|
||||
'css' => array('style.min.css'),
|
||||
'js' => array('script.min.js'),
|
||||
);
|
||||
}
|
||||
43
site/OFF_plugins/field-engineer/gulpfile.js
Normal file
43
site/OFF_plugins/field-engineer/gulpfile.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
var gulp = require('gulp');
|
||||
|
||||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var cssmin = require('gulp-cssmin');
|
||||
var notify = require('gulp-notify');
|
||||
var sass = require('gulp-sass');
|
||||
var rename = require('gulp-rename');
|
||||
var uglify = require('gulp-uglify');
|
||||
var concat = require('gulp-concat');
|
||||
var gutil = require('gulp-util');
|
||||
//var sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
// css
|
||||
gulp.task('css', function() {
|
||||
gulp.src('assets/scss/style.scss')
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
//.pipe(sourcemaps.write(''))
|
||||
.pipe(gulp.dest('fields/engineer/assets/css'))
|
||||
.pipe(cssmin())
|
||||
.pipe(rename({suffix: '.min'}))
|
||||
.pipe(gulp.dest('fields/engineer/assets/css'))
|
||||
.pipe(notify("CSS generated!"))
|
||||
;
|
||||
});
|
||||
|
||||
// JS
|
||||
gulp.task('js', function() {
|
||||
gulp.src('assets/js/*.js')
|
||||
.pipe(concat('script.js'))
|
||||
.pipe(gulp.dest('fields/engineer/assets/js'))
|
||||
.pipe(uglify()).on('error', function (err) { gutil.log(gutil.colors.red('[Error]'), err.toString()); })
|
||||
.pipe(rename({suffix: '.min'}))
|
||||
.pipe(gulp.dest('fields/engineer/assets/js'))
|
||||
.pipe(notify("JS generated!"))
|
||||
;
|
||||
});
|
||||
|
||||
// Default
|
||||
gulp.task('default',function() {
|
||||
gulp.watch('assets/scss/*.scss',['css']);
|
||||
gulp.watch('assets/js/*.js',['js']);
|
||||
});
|
||||
60
site/OFF_plugins/field-engineer/lib/field.php
Normal file
60
site/OFF_plugins/field-engineer/lib/field.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
namespace Engineer;
|
||||
use c;
|
||||
|
||||
class Field {
|
||||
function data($key, $subfield, $page, $count = false) {
|
||||
$subfield['label'] = (isset($subfield['label'])) ? $subfield['label'] : '';
|
||||
|
||||
if($count) {
|
||||
$count = '_i' . kirby()->set('option', 'egr.count', kirby()->get('option', 'egr.count', 0) + 1);
|
||||
}
|
||||
|
||||
$value = (isset($subfield['value'])) ? $subfield['value'] : null;
|
||||
|
||||
if(is_array($value)) {
|
||||
$value = implode("\n" , $value);
|
||||
}
|
||||
|
||||
$suffix = $count . '_egr__';
|
||||
$name = $key . $suffix;
|
||||
$subfield = $this->fixSubfield($subfield);
|
||||
$form = new \EngineerForm(
|
||||
array($name => $subfield),
|
||||
array($name => $value),
|
||||
$page
|
||||
);
|
||||
$form = $this->fixLabel($form);
|
||||
$form = $this->manipulate($form, $key, $suffix);
|
||||
return $form;
|
||||
}
|
||||
|
||||
function fixLabel($form) {
|
||||
return str_replace('<label class="label" for="', '<label class="label" data-for="', $form);
|
||||
}
|
||||
|
||||
function fixSubfield($subfield) {
|
||||
$subfield = $this->fixTextarea($subfield);
|
||||
$subfield = $this->fixBool($subfield);
|
||||
return $subfield;
|
||||
}
|
||||
|
||||
function fixTextarea($subfield) {
|
||||
if($subfield['type'] == 'textarea') {
|
||||
$subfield['buttons'] = false;
|
||||
}
|
||||
return $subfield;
|
||||
}
|
||||
|
||||
function fixBool($value) {
|
||||
if(is_bool($value)) {
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
function manipulate($form, $key, $suffix) {
|
||||
$html = str_replace('<div class="field ', '<div data-prefix="' . $suffix . '" data-field-name="' . $key . '" class="field egr-field ', $form);
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
53
site/OFF_plugins/field-engineer/lib/form.php
Normal file
53
site/OFF_plugins/field-engineer/lib/form.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
use Kirby\Panel\Form;
|
||||
use Kirby\Panel\Form\Plugins;
|
||||
|
||||
class EngineerForm extends Form {
|
||||
public $tag = 'div';
|
||||
public $page = null;
|
||||
|
||||
public function __construct($fields = array(), $values = array(), $page) {
|
||||
kirby()->set('option', 'engineer.page', $page);
|
||||
|
||||
$this->fields = new Collection;
|
||||
$this->plugins = new Plugins();
|
||||
$this->values($values);
|
||||
$this->fields($fields);
|
||||
}
|
||||
|
||||
public function toHTML() {
|
||||
if($this->message) {
|
||||
$this->append($this->message);
|
||||
}
|
||||
|
||||
$html = '';
|
||||
foreach($this->fields() as $key => $field) {
|
||||
$html .= $field;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->toHTML();
|
||||
}
|
||||
|
||||
static public function field($type, $options = array()) {
|
||||
$class = $type . 'field';
|
||||
|
||||
if(!class_exists($class)) {
|
||||
throw new Exception('The ' . $type . ' field is missing. Please add it to your installed fields or remove it from your blueprint');
|
||||
}
|
||||
|
||||
$page = kirby()->get('option', 'engineer.page');
|
||||
|
||||
$field = new $class;
|
||||
$field->page = $page;
|
||||
|
||||
foreach($options as $key => $value) {
|
||||
$field->$key = $value;
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
}
|
||||
81
site/OFF_plugins/field-engineer/lib/outline.php
Normal file
81
site/OFF_plugins/field-engineer/lib/outline.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
namespace Engineer;
|
||||
|
||||
class Outline {
|
||||
function set($field, $name, $out = array(), $level = 0) {
|
||||
if(isset($field['type']) && $field['type'] == 'engineer') {
|
||||
$out[$name] = $this->mergeFieldsets($field);
|
||||
|
||||
if(isset($out[$name]['fieldsets'])) {
|
||||
foreach($out[$name]['fieldsets'] as $fieldset_name => $fieldset) {
|
||||
if(isset($fieldset['fields'])) {
|
||||
$dropdown = $this->dropdown($fieldset);
|
||||
if(!empty($dropdown)) {
|
||||
$out[$name]['fieldsets'][$fieldset_name]['_dropdown'] = $dropdown;
|
||||
}
|
||||
foreach($fieldset['fields'] as $field_name => $field) {
|
||||
$out[$name]['_level'] = $level;
|
||||
|
||||
if(isset($field['label'])) {
|
||||
$out[$name]['_label'] = $field['label'];
|
||||
}
|
||||
|
||||
$out = $this->set($field, $name . ',' . $field_name, $out, $out[$name]['_level'] + 1);
|
||||
if(isset($field['buttons'])) {
|
||||
$out[$name . ',' . $field_name]['buttons'] = $field['buttons'];
|
||||
}
|
||||
|
||||
if($field['type'] == 'engineer' && isset($field['width'])) {
|
||||
$out[$name . ',' . $field_name]['width'] = $field['width'];
|
||||
}
|
||||
|
||||
if(isset($field['style'])) {
|
||||
$out[$name . ',' . $field_name]['_style'] = $field['style'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function mergeFieldsets($field) {
|
||||
if(isset($field['fields'])) {
|
||||
$out['fieldsets']['default']['fields'] = $field['fields'];
|
||||
}
|
||||
if(isset($field['fieldsets'])) {
|
||||
if(isset($field['fields'])) {
|
||||
$out['fieldsets'] += $field['fieldsets'];
|
||||
} else {
|
||||
$out['fieldsets'] = $field['fieldsets'];
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function dropdown($fieldset) {
|
||||
$out = array();
|
||||
if(isset($fieldset['fields'])) {
|
||||
foreach($fieldset['fields'] as $field_name => $field) {
|
||||
if($field['type'] == 'engineer') {
|
||||
if(isset($field['label'])) {
|
||||
$out[$field_name]['label'] = $field['label'];
|
||||
}
|
||||
if(isset($field['fields'])) {
|
||||
$out[$field_name]['sets'] = array(
|
||||
'default' => 'Default'
|
||||
);
|
||||
}
|
||||
if(isset($field['fieldsets'])) {
|
||||
foreach($field['fieldsets'] as $fieldset_name => $fieldset) {
|
||||
$fieldset_label = (isset($fieldset['label'])) ? $fieldset['label'] : $fieldset_name;
|
||||
$out[$field_name]['sets'][$fieldset_name] = $fieldset_label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
site/OFF_plugins/field-engineer/lib/presentation-array.php
Normal file
85
site/OFF_plugins/field-engineer/lib/presentation-array.php
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
namespace Engineer;
|
||||
|
||||
class PresentationArray {
|
||||
function __construct() {
|
||||
$this->Field = new \Engineer\field;
|
||||
}
|
||||
function field() {
|
||||
return $this->Field;
|
||||
}
|
||||
|
||||
function prepare($field, $level = -1) {
|
||||
$out = $this->cleanup($field);
|
||||
$out = $this->level($out, $level);
|
||||
$out = $this->default($out, $field);
|
||||
$out = $this->fieldsets($out, $field);
|
||||
$out = $this->styleTable($out);
|
||||
$out = $this->loop($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
function styleTable($out) {
|
||||
if(isset($out['style']) && $out['style'] == 'table') {
|
||||
if(!empty($out['fieldsets'])) {
|
||||
foreach($out['fieldsets'] as $fieldset_key => $fieldset) {
|
||||
foreach($fieldset['fields'] as $field_key => $field) {
|
||||
if(isset($field['label'])) {
|
||||
$out['fieldsets'][$fieldset_key]['labels'][$field_key]['label'] = $field['label'];
|
||||
$out['fieldsets'][$fieldset_key]['labels'][$field_key]['width'] = $field['width'];
|
||||
}
|
||||
unset($out['fieldsets'][$fieldset_key]['fields'][$field_key]['label']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function cleanup($out) {
|
||||
unset($out['fieldsets'], $out['fields']);
|
||||
return $out;
|
||||
}
|
||||
|
||||
function level($out, $level) {
|
||||
if($out['type'] == 'engineer') {
|
||||
$out['_level'] = $level + 1;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function default($out, $field) {
|
||||
if(isset($field['fields'])) {
|
||||
$out['fieldsets']['default']['fields'] = $field['fields'];
|
||||
} else {
|
||||
$out['fieldsets']['default']['fields'] = array();
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function fieldsets($out, $field) {
|
||||
if(isset($field['fieldsets'])) {
|
||||
$out['fieldsets'] += $field['fieldsets'];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function loop($out) {
|
||||
if(isset($out['fieldsets'])) {
|
||||
foreach($out['fieldsets'] as $fieldset_name => $fieldset) {
|
||||
if(!empty($fieldset['fields'])) {
|
||||
$dropdown_label = (isset($fieldset['label'])) ? $fieldset['label'] : $fieldset_name;
|
||||
$dropdown[$fieldset_name] = $dropdown_label;
|
||||
foreach($fieldset['fields'] as $field_name => $field) {
|
||||
if($field['type'] == 'engineer') {
|
||||
$out['fieldsets'][$fieldset_name]['fields'][$field_name] = $this->prepare($field, $out['_level']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$out['_dropdown'] = $dropdown;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
71
site/OFF_plugins/field-engineer/lib/presentation.php
Normal file
71
site/OFF_plugins/field-engineer/lib/presentation.php
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
namespace Engineer;
|
||||
use egr;
|
||||
|
||||
class Presentation {
|
||||
function __construct() {
|
||||
$this->Field = new \Engineer\field;
|
||||
}
|
||||
function field() {
|
||||
return $this->Field;
|
||||
}
|
||||
function set($data, $value) {
|
||||
$new = $data;
|
||||
unset($new['fieldsets'], $new['fields']);
|
||||
if(! empty($value)) {
|
||||
foreach($value as $fieldset) {
|
||||
$set = kirby()->get('option', 'egr.set', 0);
|
||||
kirby()->set('option', 'egr.set', $set + 1);
|
||||
|
||||
$fieldset_name = (isset($fieldset['_fieldset'])) ? $fieldset['_fieldset'] : 'default';
|
||||
$fieldset_data = $data['fieldsets'][$fieldset_name];
|
||||
$labels = (isset($data['fieldsets'][$fieldset_name]['labels'])) ? $data['fieldsets'][$fieldset_name]['labels'] : array();
|
||||
$new['sets']['set_' . $set]['name'] = $fieldset_name;
|
||||
$new['sets']['set_' . $set]['labels'] = $labels;
|
||||
|
||||
if(!empty($fieldset_data['fields'])) {
|
||||
foreach($fieldset_data['fields'] as $field_name => $field) {
|
||||
$data_value = (isset($fieldset[$field_name])) ? $fieldset[$field_name] : '';
|
||||
$field_type = $field['type'];
|
||||
|
||||
$id = kirby()->get('option', 'egr.id', 0);
|
||||
kirby()->set('option', 'egr.id', $id + 1);
|
||||
|
||||
if($field_type == 'engineer') {
|
||||
$new['sets']['set_' . $set]['fields']['id_' . $id] = $this->set($field, $data_value);
|
||||
$new['sets']['set_' . $set]['fields']['id_' . $id]['name'] = $field_name;
|
||||
} else {
|
||||
$extra = array(
|
||||
'value' => $data_value,
|
||||
'name' => $field_name,
|
||||
'_fieldset' => $fieldset_name
|
||||
);
|
||||
$new['sets']['set_' . $set]['fields']['id_' . $id] = array_merge($field, $extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $new;
|
||||
}
|
||||
|
||||
function render($args) {
|
||||
extract($args);
|
||||
$out = '';
|
||||
if(!empty($set['fields'])) {
|
||||
foreach($set['fields'] as $field_id => $field) {
|
||||
if($field['type'] != 'engineer') {
|
||||
$out .= $this->field()->data($field['name'], $field, $instance->page, true);
|
||||
} else {
|
||||
$out .= egr::snippet('presentation', array(
|
||||
'presentation' => $field,
|
||||
'field_name' => $field['name'],
|
||||
'id' => $id . ',' . $field['name'],
|
||||
'instance' => $instance
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
43
site/OFF_plugins/field-engineer/lib/tpl.php
Normal file
43
site/OFF_plugins/field-engineer/lib/tpl.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
class egr {
|
||||
public static function oddEven($level) {
|
||||
return ($level % 2 == 0) ? 'egr-even' : 'egr-odd';
|
||||
}
|
||||
|
||||
public static function snippet($name, $data = array()) {
|
||||
$path = kirby()->roots()->plugins() . DS . 'field-engineer' . DS . 'snippets' . DS . $name . '.php';
|
||||
return tpl::load($path, $data);
|
||||
}
|
||||
|
||||
public static function grid($field) {
|
||||
$grid = '';
|
||||
if(isset($field['rowWidth'])) {
|
||||
$grid = ' egr-grid-item egr-grid-item-' . str_replace('/', '-', $field['rowWidth']);
|
||||
}
|
||||
return $grid;
|
||||
}
|
||||
|
||||
public static function buttons($set) {
|
||||
$buttons = array();
|
||||
if(isset($set['buttons'])) {
|
||||
$buttons = $set['buttons'];
|
||||
}
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
public static function count($field) {
|
||||
$count = 0;
|
||||
if(isset($field['sets'])) {
|
||||
$count = count($field['sets']);
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
public static function style($set) {
|
||||
$style = '';
|
||||
if(isset($set['style'])) {
|
||||
$style = ' egr-style-' . $set['style'];
|
||||
}
|
||||
return $style;
|
||||
}
|
||||
}
|
||||
20
site/OFF_plugins/field-engineer/package.json
Normal file
20
site/OFF_plugins/field-engineer/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "field-engineer",
|
||||
"description": "Kirby Engineer Field for Kirby CMS panel.",
|
||||
"author": "Jens Törnell <jens.tornell@gmail.com>",
|
||||
"version": "0.9",
|
||||
"type": "kirby-plugin",
|
||||
"license": "Commercial",
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^4.0.0",
|
||||
"gulp-cli": "^1.3.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-cssmin": "^0.2.0",
|
||||
"gulp-notify": "^3.0.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sass": "^3.1.0",
|
||||
"gulp-uglify": "^3.0.0",
|
||||
"gulp-util": "^3.0.8"
|
||||
}
|
||||
}
|
||||
62
site/OFF_plugins/field-engineer/readme.md
Normal file
62
site/OFF_plugins/field-engineer/readme.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Kirby Engineer Field
|
||||
|
||||
[](https://github.com/jenstornell/field-engineer/blob/master/docs/changelog.md) [](https://github.com/jenstornell/field-engineer/blob/master/docs/license.md) [](https://github.com/jenstornell/field-engineer/blob/master/docs/license.md)
|
||||
|
||||
***Note:*** *This is a commercial plugin. Read more about [how to purchase](#purchase).*
|
||||
|
||||
A [Kirby CMS](https://getkirby.com) field for complex field structures.
|
||||
|
||||
**Supports:**
|
||||
|
||||
- Nesting
|
||||
- Fieldsets
|
||||
- Inline editing
|
||||
- Sorting
|
||||
- Cloning
|
||||
|
||||
**Engineer example**
|
||||
|
||||
You can have pretty much any field structure you want. Also see the [blueprint](docs/examples.md) for this screenshot.
|
||||
|
||||
[](https://raw.githubusercontent.com/jenstornell/field-engineer/development/docs/hero.png)
|
||||
|
||||
[See more screenshots](docs/screenshots.md)
|
||||
|
||||
## Table of contents
|
||||
|
||||
1. **Get started**
|
||||
1. [Install](docs/install.md)
|
||||
1. [Blueprint](docs/blueprint.md)
|
||||
1. [Usage](docs/usage.md)
|
||||
1. [Templates and snippets](docs/templates-snippets.md)
|
||||
1. **More**
|
||||
- [Supported fields](docs/fields.md)
|
||||
- [Options](docs/options.md)
|
||||
- [Comparation](docs/compare.md) (to similar fields)
|
||||
- [Troubleshooting](docs/troubleshooting.md)
|
||||
- [Changelog](docs/changelog.md)
|
||||
1. **Advanced**
|
||||
- [For plugin developers](docs/advanced-for-plugin-developers.md)
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Kirby](https://getkirby.com) 2.5.2+
|
||||
- [PHP](https://www.php.net) 7+
|
||||
- A modern browser like [Chrome](https://www.google.se/chrome/browser/desktop/index.html), [Firefox](https://www.mozilla.org/firefox/new/) or [Edge](https://www.microsoft.com/windows/microsoft-edge) (Internet Explorer does not work).
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/jenstornell/field-engineer/issues/new).
|
||||
|
||||
## Purchase
|
||||
|
||||
Be sure to try before you buy. Refunds are not supported. Read more in the [license agreement](docs/license.md).
|
||||
|
||||
***The purchase button is temporary disabled***
|
||||
|
||||
**Price:** 50 EUR (on each project/domain)
|
||||
|
||||
## Credits
|
||||
|
||||
- [Jens Törnell](https://github.com/jenstornell)
|
||||
- The Kirby crew and community for all the great support!
|
||||
30
site/OFF_plugins/field-engineer/snippets/actions.php
Normal file
30
site/OFF_plugins/field-engineer/snippets/actions.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
$buttons = (empty($buttons)) ? array('delete', 'clone', 'sort-up', 'sort-down', 'sort') : $buttons;
|
||||
$button_array = array(
|
||||
'delete' => array(
|
||||
'icon' => 'trash-o'
|
||||
),
|
||||
'clone' => array(
|
||||
'icon' => 'clone'
|
||||
),
|
||||
'sort-up' => array(
|
||||
'icon' => 'long-arrow-up'
|
||||
),
|
||||
'sort-down' => array(
|
||||
'icon' => 'long-arrow-down'
|
||||
),
|
||||
'sort' => array(
|
||||
'icon' => 'arrows'
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
<div class="egr-actions">
|
||||
<?php foreach($buttons as $key) : ?>
|
||||
<?php if(isset($button_array[$key]['icon'])) : ?>
|
||||
<div class="egr-<?php echo $key; ?>">
|
||||
<i class="icon fa fa-<?php echo $button_array[$key]['icon']; ?>"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
14
site/OFF_plugins/field-engineer/snippets/delete.php
Normal file
14
site/OFF_plugins/field-engineer/snippets/delete.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
if(!kirby()->get('option', 'egr.delete.set')) {
|
||||
kirby()->set('option', 'egr.delete.set', true);
|
||||
?>
|
||||
<div class="egr-element-delete">
|
||||
<div class="egr-delete-message">
|
||||
<div class="label"><?php _l('fields.structure.delete.label') ?></div>
|
||||
<div class="egr-delete-buttons">
|
||||
<div class="egr-delete-cancel"><span><?php _l('fields.structure.cancel'); ?></span></div>
|
||||
<div class="egr-delete-apply"><?php _l('fields.structure.delete'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php }
|
||||
7
site/OFF_plugins/field-engineer/snippets/dropdown.php
Normal file
7
site/OFF_plugins/field-engineer/snippets/dropdown.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php if(count($fieldset_names) > 1) : ?>
|
||||
<div class="egr-dropdown">
|
||||
<?php foreach($fieldset_names as $field_key => $field_label) : ?>
|
||||
<div class="egr-add-select" data-add="<?php echo $field_key; ?>"><?php echo $field_label; ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
46
site/OFF_plugins/field-engineer/snippets/outline.php
Normal file
46
site/OFF_plugins/field-engineer/snippets/outline.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php if(!empty($outline)) : ?>
|
||||
<?php foreach($outline as $row_name => $set ) : ?>
|
||||
<?php $fieldset_names = array(); ?>
|
||||
<div class="egr-row egr-row-blueprint <?php echo egr::oddEven($set['_level'] + 1); ?> egr-style-<?php echo $set['_style'] ?? 'items'; ?>"
|
||||
data-field-name="<?php echo $row_name; ?>"
|
||||
data-id="<?php echo $row_name; ?>"
|
||||
data-fieldset-count="<?php echo count($set['fieldsets']); ?>"
|
||||
>
|
||||
<div class="egr-fieldsets<?php echo egr::grid($outline[$row_name]); ?>">
|
||||
<?php foreach($set['fieldsets'] as $fieldset_name => $fieldset ) : ?>
|
||||
<?php $fieldset_names[$fieldset_name] = (isset($fieldset['label'])) ? $fieldset['label'] : $fieldset_name; ?>
|
||||
|
||||
<div class="egr-fieldset" data-fieldset-name="<?php echo $fieldset_name; ?>">
|
||||
<div class="egr-fields"><?php
|
||||
if(!empty($fieldset['fields'])) {
|
||||
foreach($fieldset['fields'] as $field_name => $field) {
|
||||
if($field['type'] != 'engineer') {
|
||||
echo $instance->setField()->data($field_name, $field, $instance->page);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php if(isset($fieldset['_dropdown'])) : ?>
|
||||
<?php foreach($fieldset['_dropdown'] as $key => $dropdown ) : ?>
|
||||
<div class="egr-row <?php echo egr::oddEven($set['_level']); ?>"
|
||||
data-field-name="<?php echo $key; ?>"
|
||||
data-id="<?php echo $row_name; ?>,<?php echo $key; ?>"
|
||||
data-count="0"
|
||||
>
|
||||
<?php if(isset($dropdown['label'])) : ?>
|
||||
<label class="label"><?php echo $dropdown['label']; ?></label>
|
||||
<?php endif; ?>
|
||||
<div class="egr-fieldsets"></div>
|
||||
<?php echo egr::snippet('row-meta', array('fieldset_names' => $dropdown['sets'])); ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php echo egr::snippet('actions', array('buttons' => egr::buttons($set))); ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
40
site/OFF_plugins/field-engineer/snippets/presentation.php
Normal file
40
site/OFF_plugins/field-engineer/snippets/presentation.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<div
|
||||
class="egr-row <?php echo egr::oddEven($presentation['_level'] + 1) . egr::style($presentation); ?>"
|
||||
data-field-name="<?php echo $field_name; ?>"
|
||||
data-id="<?php echo $id; ?>"
|
||||
data-count="<?php echo egr::count($presentation); ?>"
|
||||
data-fieldset-count="<?php echo count($presentation['_dropdown']); ?>"
|
||||
>
|
||||
<?php if(isset($presentation['label'])) : ?>
|
||||
<label class="label"><?php echo $presentation['label']; ?></label>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="egr-fieldsets<?php echo egr::grid($presentation); ?>">
|
||||
<?php if(isset($presentation['sets'])) : ?>
|
||||
<?php $first = array_values($presentation['sets'])[0]; ?>
|
||||
<?php if(isset($first['labels']) && !empty($first['labels'])) : ?>
|
||||
<div class="egr-labels"><?php
|
||||
foreach($first['labels'] as $field_key => $field) :
|
||||
?><div class="field egr-field field-grid-item field-grid-item-<?php echo (isset($field['width']) ? str_replace('/', '-', $field['width']) : '1-2') ?>">
|
||||
<label class="label"><?php echo $field['label']; ?></label>
|
||||
</div><?php endforeach;
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
foreach($presentation['sets'] as $set_id => $set ) :
|
||||
?><div class="egr-fieldset" data-fieldset-name="<?php echo $set['name']; ?>">
|
||||
<div class="egr-fields"><?php
|
||||
echo $instance->presentation()->render(array(
|
||||
'instance' => $instance,
|
||||
'set' => $set,
|
||||
'id' => $id,
|
||||
));
|
||||
?></div>
|
||||
<?php echo egr::snippet('actions', array('buttons' => egr::buttons($presentation))); ?>
|
||||
</div><?php
|
||||
endforeach; endif; ?>
|
||||
</div>
|
||||
|
||||
<?php echo egr::snippet('row-meta', array('fieldset_names' => $presentation['_dropdown'])); ?>
|
||||
</div>
|
||||
12
site/OFF_plugins/field-engineer/snippets/row-actions.php
Normal file
12
site/OFF_plugins/field-engineer/snippets/row-actions.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<div class="egr-row-actions">
|
||||
<div class="egr-add">
|
||||
<div class="egr-add-button"<?php echo $data_add; ?>>
|
||||
<?php if(count($fieldset_names) > 1) : ?>
|
||||
<i class="icon icon-left fa fa-arrow-circle-down"></i><span><?php echo l('fields.structure.add'); ?></span>
|
||||
<?php else : ?>
|
||||
<i class="icon icon-left fa fa-plus-circle"></i><span><?php echo l('fields.structure.add'); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php echo egr::snippet('dropdown', array('fieldset_names' => $fieldset_names)); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
7
site/OFF_plugins/field-engineer/snippets/row-empty.php
Normal file
7
site/OFF_plugins/field-engineer/snippets/row-empty.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<div class="egr-empty">
|
||||
<?php $icon = (!empty($data_add)) ? 'plus-circle' : 'arrow-circle-down'; ?>
|
||||
<i class="icon icon-left fa fa-<?php echo $icon; ?>"></i>
|
||||
<span class="egr-add-button"<?php echo $data_add; ?>><?php _l('fields.structure.add.first') ?>
|
||||
<?php echo egr::snippet('dropdown', array('fieldset_names' => $fieldset_names)); ?>
|
||||
</span>
|
||||
</div>
|
||||
8
site/OFF_plugins/field-engineer/snippets/row-meta.php
Normal file
8
site/OFF_plugins/field-engineer/snippets/row-meta.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
$data_add = '';
|
||||
if(count($fieldset_names) == 1) {
|
||||
reset($fieldset_names);
|
||||
$data_add = ' data-add="' . key($fieldset_names) . '"';
|
||||
}
|
||||
echo egr::snippet('row-actions', array('data_add' => $data_add, 'fieldset_names' => $fieldset_names));
|
||||
echo egr::snippet('row-empty', array('data_add' => $data_add, 'fieldset_names' => $fieldset_names));
|
||||
21
site/OFF_plugins/field-engineer/snippets/template.php
Normal file
21
site/OFF_plugins/field-engineer/snippets/template.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php if(c::get('engineer.debug', false)) : ?>
|
||||
<style>
|
||||
.egr-outline,
|
||||
.egr-output {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
<div class="egr">
|
||||
<div class="egr-outline">
|
||||
<?php echo egr::snippet('delete'); ?>
|
||||
<?php echo egr::snippet('outline', $args['outline']); ?>
|
||||
</div>
|
||||
<div class="egr-presentation"><?php echo egr::snippet('presentation', $args['presentation']); ?></div>
|
||||
<div class="egr-output">
|
||||
<textarea
|
||||
name="<?= $args['instance']->name; ?>"
|
||||
id="form-field-<?= $args['instance']->name; ?>
|
||||
"><?php echo htmlspecialchars($args['instance']->value); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# fields on root and sub level
|
||||
# fieldsets on root and sub level
|
||||
# single fieldset on sub level (no dropdown needed for a single fieldset)
|
||||
# empty fields on root and sub level
|
||||
# empty fieldsets on root and sub level
|
||||
|
||||
title: Engineer fieldsets
|
||||
pages: true
|
||||
fields:
|
||||
single:
|
||||
type: engineer
|
||||
label: Single fields
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
engineer_fields:
|
||||
label: Fields
|
||||
type: engineer
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
engineer_fieldset:
|
||||
label: Single fieldset
|
||||
type: engineer
|
||||
fieldsets:
|
||||
labled:
|
||||
label: Labled
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
multiple:
|
||||
type: engineer
|
||||
label: Fieldsets
|
||||
fieldsets:
|
||||
labled:
|
||||
label: Labled
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
engineer:
|
||||
type: engineer
|
||||
fieldsets:
|
||||
first:
|
||||
label: First
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
second:
|
||||
fields:
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
unlabled:
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
50
site/OFF_plugins/field-engineer/tests/blueprints/grid.yml
Normal file
50
site/OFF_plugins/field-engineer/tests/blueprints/grid.yml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# width on root and sub level
|
||||
# rowWidth on root and sub level
|
||||
# buttons on root and sub level
|
||||
|
||||
title: Engineer grid
|
||||
pages: true
|
||||
fields:
|
||||
width:
|
||||
type: engineer
|
||||
width: 1/2
|
||||
rowWidth: 1/2
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
width: 1/2
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
width: 1/2
|
||||
engineer:
|
||||
type: engineer
|
||||
label: Root
|
||||
rowWidth: 1/2
|
||||
buttons:
|
||||
- delete
|
||||
- clone
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
width: 1/2
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
width: 1/2
|
||||
engineer:
|
||||
type: engineer
|
||||
width: 1/2 # Fails with type engineer on a sub level
|
||||
rowWidth: 1/2
|
||||
buttons:
|
||||
- delete
|
||||
- sort
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
31
site/OFF_plugins/field-engineer/tests/blueprints/nesting.yml
Normal file
31
site/OFF_plugins/field-engineer/tests/blueprints/nesting.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
title: Engineer nesting
|
||||
pages: true
|
||||
fields:
|
||||
engineer:
|
||||
type: engineer
|
||||
label: Level 0
|
||||
fields:
|
||||
text:
|
||||
label: Text field
|
||||
type: text
|
||||
engineer:
|
||||
label: Level 1
|
||||
type: engineer
|
||||
fields:
|
||||
text:
|
||||
label: Text field
|
||||
type: text
|
||||
engineer:
|
||||
label: Level 2
|
||||
type: engineer
|
||||
fields:
|
||||
text:
|
||||
label: Text field
|
||||
type: text
|
||||
engineer:
|
||||
label: Level 3
|
||||
type: engineer
|
||||
fields:
|
||||
text:
|
||||
label: Text field
|
||||
type: text
|
||||
46
site/OFF_plugins/field-engineer/tests/blueprints/options.yml
Normal file
46
site/OFF_plugins/field-engineer/tests/blueprints/options.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# All option tests are on both root level and sub level
|
||||
# label, type, default, icon, readonly, help, placeholder, required
|
||||
|
||||
title: Engineer options
|
||||
pages: true
|
||||
fields:
|
||||
engineer:
|
||||
type: engineer
|
||||
label: Single fields
|
||||
fields:
|
||||
text:
|
||||
label: Text without options
|
||||
type: text
|
||||
text_options1:
|
||||
label: Text with options 1
|
||||
type: text
|
||||
default: Default value
|
||||
icon: info
|
||||
disabled: true
|
||||
help: default, icon, help
|
||||
text_options2:
|
||||
label: Text with options 2
|
||||
type: text
|
||||
placeholder: A placeholder
|
||||
required: true
|
||||
help: placeholder, required, help
|
||||
engineer:
|
||||
label: Fields
|
||||
type: engineer
|
||||
fields:
|
||||
text:
|
||||
label: Text without options
|
||||
type: text
|
||||
text_options1:
|
||||
label: Text with options 1
|
||||
type: text
|
||||
default: Default value
|
||||
icon: info
|
||||
disabled: true
|
||||
help: default, icon, help
|
||||
text_options2:
|
||||
label: Text with options 2
|
||||
type: text
|
||||
placeholder: A placeholder
|
||||
required: true
|
||||
help: placeholder, required, help
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
title: Engineer panel fields
|
||||
pages: true
|
||||
fields:
|
||||
engineer:
|
||||
type: engineer
|
||||
label: Panel fields
|
||||
fields:
|
||||
checkbox:
|
||||
type: toggle
|
||||
text: My checkbox
|
||||
width: 1/3
|
||||
checkboxes:
|
||||
type: checkboxes
|
||||
options:
|
||||
one: One
|
||||
two: Two
|
||||
width: 1/3
|
||||
date:
|
||||
type: date
|
||||
width: 1/3
|
||||
datetime:
|
||||
type: date
|
||||
width: 1/3
|
||||
email:
|
||||
type: email
|
||||
width: 1/3
|
||||
headline:
|
||||
type: headline
|
||||
image:
|
||||
type: files
|
||||
width: 1/3
|
||||
headline2:
|
||||
label: H2
|
||||
type: headline
|
||||
info:
|
||||
type: info
|
||||
width: 1/3
|
||||
text: >
|
||||
Some text
|
||||
added
|
||||
line:
|
||||
type: line
|
||||
width: 1/3
|
||||
number:
|
||||
type: number
|
||||
width: 1/3
|
||||
page:
|
||||
type: pages
|
||||
width: 1/3
|
||||
radio:
|
||||
type: radio
|
||||
options:
|
||||
one: One
|
||||
two: Two
|
||||
width: 1/3
|
||||
select:
|
||||
type: select
|
||||
options:
|
||||
one: One
|
||||
two: Two
|
||||
width: 1/3
|
||||
tags:
|
||||
type: tags
|
||||
width: 1/3
|
||||
tel:
|
||||
type: tel
|
||||
width: 1/3
|
||||
text:
|
||||
type: text
|
||||
width: 1/3
|
||||
textarea:
|
||||
type: textarea
|
||||
width: 1/3
|
||||
time:
|
||||
type: time
|
||||
width: 1/3
|
||||
toggle:
|
||||
type: toggle
|
||||
width: 1/3
|
||||
url:
|
||||
type: url
|
||||
width: 1/3
|
||||
user:
|
||||
type: users
|
||||
width: 1/3
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
title: Engineer supported fields
|
||||
pages: true
|
||||
fields:
|
||||
engineer:
|
||||
type: engineer
|
||||
label: Supported fields
|
||||
fields:
|
||||
hero:
|
||||
label: Hero
|
||||
type: hero
|
||||
width: 1/3
|
||||
quickselect:
|
||||
label: quickselect
|
||||
type: quickselect
|
||||
options: files
|
||||
width: 1/3
|
||||
images:
|
||||
label: Images
|
||||
type: files
|
||||
39
site/OFF_plugins/field-engineer/tests/blueprints/table.yml
Normal file
39
site/OFF_plugins/field-engineer/tests/blueprints/table.yml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# style: table
|
||||
|
||||
title: Engineer table
|
||||
pages: true
|
||||
fields:
|
||||
engineer:
|
||||
type: engineer
|
||||
style: table
|
||||
label: Table
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
width: 1/3
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
width: 1/3
|
||||
textarea2:
|
||||
label: Textarea2
|
||||
type: textarea
|
||||
width: 1/3
|
||||
nested:
|
||||
type: engineer
|
||||
label: Root
|
||||
fields:
|
||||
engineer:
|
||||
label: Engineer
|
||||
type: engineer
|
||||
style: table
|
||||
fields:
|
||||
text:
|
||||
label: Text
|
||||
type: text
|
||||
width: 1/2
|
||||
textarea:
|
||||
label: Textarea
|
||||
type: textarea
|
||||
width: 1/2
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
title: Engineer working fields
|
||||
pages: true
|
||||
fields:
|
||||
to_structure:
|
||||
type: structure
|
||||
label: For select a stucture field
|
||||
style: table
|
||||
fields:
|
||||
item:
|
||||
type: text
|
||||
engineer:
|
||||
type: engineer
|
||||
label: Working fields
|
||||
fields:
|
||||
switch:
|
||||
label: Switch
|
||||
type: switch
|
||||
text: Switch me
|
||||
width: 1/3
|
||||
country:
|
||||
label: Country
|
||||
type: country
|
||||
width: 1/3
|
||||
decimal:
|
||||
label: Decimal
|
||||
type: decimal
|
||||
width: 1/3
|
||||
selectastructure:
|
||||
label: Select a structure
|
||||
type: selectastructure
|
||||
width: 1/3
|
||||
structurepage: plugin-fields
|
||||
structurefield: to_structure
|
||||
optionkey: item
|
||||
logic:
|
||||
label: Logic
|
||||
title: My logic field
|
||||
width: 1/3
|
||||
type: logic
|
||||
controlledcheckboxes:
|
||||
label: Controlled list
|
||||
type: controlledcheckboxes
|
||||
controller: MyPlugin::userlist
|
||||
Loading…
Add table
Add a link
Reference in a new issue