- if (!Array.prototype.filter)
- {
- Array.prototype.filter = function(fun /*, thisp */)
- {
- "use strict";
- if (this === void 0 || this === null)
- throw new TypeError();
- var t = Object(this);
- var len = t.length >>> 0;
- if (typeof fun !== "function")
- throw new TypeError();
- var res = [];
- var thisp = arguments[1];
- for (var i = 0; i < len; i++)
- {
- if (i in t)
- {
- var val = t[i]; // in case fun mutates this
- if (fun.call(thisp, val, i, t))
- res.push(val);
- }
- }
- return res;
- };
- }
- // read support for HTML5 data Attributes
- Element.addMethods({
- getDataset: function(element) {
- if (element.dataset) return element.dataset;
- var match, attr, dataset = {},
- attributes = element.attributes,
- index = attributes.length;
- while (index--) {
- attr = attributes[index];
- if (attr.localName.startsWith('data-'))
- dataset[attr.localName.substring(5)] = attr.nodeValue;
- }
- return element.dataset = dataset;
- }
- });
- // Like perl ;)
- "use strict";
- // a single node
- var FormEditorNode = Class.create( {
- // Initalize new Element
- initialize: function(raw, htm, pt) {
- var these = this;
- these.raw = raw;
- // get a describtive title
- var title = these.raw.label ? these.raw.label : these.raw.name;
- // is root?
- these.pt = pt ? pt.raw.name : false;
- if ( these.root && !these.raw.name ) {
- // Special name for the root/form-Element
- these.id = "element_root";
- } else {
- these.id = "element_" + these.raw.name;
- }
- },
- // update a node
- update: function(raw) {
- var these = this;
- Object.extend(these.raw, raw);
- // special cases, which could not be simple merged
- these.raw.attributes = raw.attributes ? raw.attributes : undefined;
- these.raw.options = raw.options ? raw.options : undefined;
- these.raw.restraints = raw.restraints ? raw.restraints : undefined;
- },
- });
- // FormEditor for FormFu-templates
- var FormEditor = Class.create({
- // List of elements which are selectable and there possible attributes
- types: {
- 'Text' : { type: 'Text', description: 'Text input field', 'attributes': ['size','width','title'] },
- 'Checkbox' : { type: 'Text', description: 'Single Checkbox', 'attributes': ['size','width','title'] },
- 'Password' : { type: 'Password', description: 'Password field', 'attributes': ['size','width','title'] },
- 'Textarea' : { type: 'Textarea', description: 'Textarea', 'attributes': ['size','width','title'] },
- 'Submit': { type: 'Submit', description: 'Submit Button', 'attributes': ['size','width','title'], 'removes': ['constraints'] },
- 'Block': { type: 'Block', description: 'Text paragraph', 'content': true, 'attributes': ['size','width','title'], 'removes': ['constraints','value','label'] },
- 'Hr': { type: 'Hr', description: 'Horizontal ruler', 'removes': ['constraints','label','value','name'], 'attributes': ['width'] },
- 'Select': { type: 'Select', description: 'Select field', 'label': false, 'options': true, 'attributes': ['size','width','title'] },
- 'Webdisk': { type: 'Webdisk', description: 'Webdisk-Dialog', 'kind': true, 'attributes': ['size','width','title'] }
- },
- // List of constraints which are selectable
- constraints: {
- 'Required' : { type: 'Required', description: 'Input required', 'configs': ['message'] },
- 'Number' : { type: 'Number', description: 'Number required', 'configs': ['message'] },
- 'Regex' : { type: 'Regex', description: 'Regex validation', 'configs': ['regex','message'] },
- 'MinLength': { type: 'MinLength', description: 'Minimal length', 'configs': ['min', 'message' ] },
- 'Length' : { type: 'Length', description: 'Min/Max length', 'configs': ['min', 'max', 'message' ] },
- 'Equal' : { type: 'Equal', description: 'Equal required', 'configs': ['others','message'] },
- 'Range' : { type: 'Range', description: 'Number in Range', 'configs': [ 'min','max','message'] }
- },
- // Initialize and render tree
- initialize: function(form, options) {
- var these = this;
- these.form = form;
- // initalize options
- these.container = options.container;
- these.saver = options.saver;
- these.previewer = options.previewer;
- these.renderer = options.renderer;
- these.elements = $H();
- these.nodelist = $H();
- these.token = options.token;
- these.formfile = options.formfile;
- these.y2j = options.y2j;
- these.j2y = options.j2y;
- these.tree = options.inittree;
- these.form.observe('submit', function(e) { Event.stop(e); these.preview() } );
- if (options.undo_button) {
- these.undo_button = options.undo_button;
- these.undo_button.disabled = true;
- these.undo_button.observe('click', function(e) { these.undo() } );
- }
- if (options.redo_button ) {
- these.redo_button = options.redo_button;
- these.redo_button.disabled = true;
- these.redo_button.observe('click', function(e) { these.redo() } );
- }
- // render the tree
- these.rendertree();
- // history
- these.history_redo = [ ];
- these.history_undo = [ ];
- },
- preview: function() {
- var these = this;
- var parameters = {
- __json: Object.toJSON(these.serialize()),
- __form: these.formfile
- };
- parameters = $H(parameters).merge( these.form.serialize(true) );
- new Ajax.Request( these.previewer,
- {
- method:'post',
- parameters: parameters,
- onSuccess: function(transport){
- errormsg();
- infomsg("PReview successfull");
- these.form.replace(transport.responseText );
- these.form = $('previewForm');
- these.form.observe('submit', function(e) { Event.stop(e); these.preview() } );
- these.rendertree();
- },
- onFailure: function(transport){
- infomsg();
- errormsg(transport.responseText);
- }
- }
- );
- },
- parseform: function(element) {
- var these = this;
- return these.traverseform(element, function(keyname,ele) {
- these.elements.set( keyname, ele );
- });
- },
- // Traverseform and execute callback for every element found
- traverseform: function(element,cb) {
- var these = this;
- var childs = element.childElements();
- var dataset = element.getDataset();
- if (dataset.feName || dataset['fe-name'] ) {
- var fename = dataset.feName || dataset['fe-name'] ;
- // Exec Callback
- cb(fename, element);
- }
- childs.each( function(ele, idx) {
- these.traverseform(ele,cb);
- });
- },
- store: function() {
- var these = this;
- new Ajax.Request(these.saver, {
- 'method': 'post',
- 'asynchronous': false,
- 'parameters': { '__form': these.formfile, '__json': Object.toJSON(these.serialize()), '_token': these.token },
- 'onSuccess': function(transport) {
- errormsg();
- infomsg(transport.responseText);
- },
- 'onFailure': function(transport){
- infomsg();
- errormsg(transport.responseText);
- }
- });
- },
- // Create json
- serialize: function() {
- var these = this;
- var ds = { elements: [] };
- var eles = {};
- var parents = {};
- these.traverseform(these.form, function(keyname,ele) {
- var node = ele.retrieve('object');
- if ( node ) {
- parents[node.raw.name] = node.raw;
- if ( node.pt == false ) {
- ds = node.raw;
- ds.elements = [];
- } else {
- var par = parents[node.pt];
- if (!par.elements) { par.elements = [] };
- par.elements.push(node.raw);
- }
- }
- });
- return ds;
- },
- // Toolbar, Add, remove and sort elements
- showtoolbar: function(ele) {
- var these = this;
- ele.setStyle( { 'position':'relative' });
- var old = ele.down('.form_editor_toolbar');
- if ( old ) { old.remove() };
- var node = ele.retrieve('object');
- // build fresh
- var toolbar = new Element('div', { 'class': 'form_editor_toolbar' });
- var a_add = new Element('a', { 'class': 'form_editor_toolbar_add' }).update('add');
- var a_delete = new Element('a', { 'class': 'form_editor_toolbar_delete' }).update('delete');
- var a_edit = new Element('a', { 'class': 'form_editor_toolbar_edit' }).update('edit');
- var a_up = new Element('a', { 'class': 'form_editor_toolbar_up' }).update('up');
- var a_down = new Element('a', { 'class': 'form_editor_toolbar_down'}).update('down');
- toolbar.insert(a_add);
- if ( node.pt ) {
- toolbar.insert(a_edit);
- toolbar.insert(a_up);
- toolbar.insert(a_down);
- toolbar.insert(a_delete)
- }
- ele.insert(toolbar);
- a_edit.observe('click', function(event,element) { these.edit_element(ele) });
- a_add.observe('click', function(event,element) { these.add_element(ele) });
- a_delete.observe('click', function(event,element) { these.delete_element(ele); });
- a_up.observe('click', function(event,element) { these.up_element(ele) });
- a_down.observe('click', function(event,element) { these.down_element(ele); });
- },
- // edit element dialog
- edit_element: function(ele) {
- var these = this;
- var cb = function(ele,node,raw) {
- these.undopoint();
- node.update( raw );
- // Render HTML on the serverside
- new Ajax.Request(these.renderer, {
- 'method': 'post',
- 'asynchronous': false,
- 'parameters': { 'json': Object.toJSON(node.raw) },
- 'onSuccess': function(response) {
- var ans = response.responseJSON;
- var htmlcode = ans.container;
- ele.replace( htmlcode);
- these.rendertree();
- },
- 'onFailure': function() {
- alert("Could not convert");
- }
- });
- these.rendertree();
- };
- var node = ele.retrieve('object');
- return this._dialog_element('edit', node.html,node, "Configure field", "Update", cb )
- },
- // private dialog window
- _dialog_element: function(mode, ele, node, dialog_title, button_title, callback, newtype) {
- var these = this;
- var current = (mode == 'edit') ? node : { raw : {}};
- var type = (mode == 'edit') ? node.raw.type : newtype ;
- var stype = these.types[type];
- if ( stype ) {
- // Ask for Config
- var editbox = new Element('ul', { 'class': 'form_editor_dialog' });
- var title = new Element('li', { 'class': 'boxheader'}).update(dialog_title);
- editbox.insert(title);
- var removes = these.types[type].removes || [];
- if (removes.indexOf('name') == -1 ) {
- var li_name = new Element('li');
- var label_name = new Element('label').update('Name (Variable)');
- var block_name = new Element('div', { 'class': 'block' });
- var error_name = new Element('span', { 'class': 'fielderror' }) ;
- var field_name = new Element('input', { 'type': 'text', 'name': 'base_name', 'value': ( current.raw.name || "" ) });
- li_name.insert(label_name);
- block_name.insert(error_name);
- block_name.insert(field_name);
- li_name.insert(block_name);
- editbox.insert(li_name);
- }
- if ( removes.indexOf('label') == -1 ) {
- var li_label = new Element('li');
- var label_label = new Element('label').update("Label");
- var block_label = new Element('div', { 'class': 'block' });
- var error_label = new Element('span', { 'class': 'fielderror' });
- var field_label = new Element('input', { 'type': 'text', 'name': 'base_label', 'value': ( current.raw.label || "" ) });
- var xml_label = new Element('input', { 'type': 'checkbox', 'name': 'check_xml_label' });
- var xml_extra = new Element('small', { }).update('XML');
- // Handle XML content
- if ( current.raw.label_xml && !current.raw.label ) {
- xml_label.checked = true;
- var label_value = current.raw.label_xml;
- label_value.replace(/"/,"\"");
- field_label.value = label_value;
- }
- li_label.insert(label_label);
- block_label.insert(error_label);
- block_label.insert(field_label);
- block_label.insert(xml_label);
- block_label.insert(xml_extra);
- li_label.insert(block_label);
- editbox.insert(li_label);
- }
- if ( type == 'Block' ) {
- var li_content = new Element('li');
- var content_content = new Element('label').update("Content");
- var block_content = new Element('div', { 'class': 'block' });
- var error_content = new Element('span', { 'class': 'fielderror' });
- var field_content = new Element('textarea', { 'type': 'text', 'name': 'base_content' });
- var xml_content = new Element('input', { 'type': 'checkbox', 'name': 'check_xml_content' });
- var xml_extra = new Element('small', { }).update('XML');
- // Handle XML content
- if ( current.raw.content_xml && !current.raw.content ) {
- xml_content.checked = true;
- var content_value = current.raw.content_xml;
- content_value.replace(/"/,"\"");
- field_content.value = content_value;
- } else {
- field_content.value = content_value;
- }
- li_content.insert(content_content);
- block_content.insert(error_content);
- block_content.insert(field_content);
- block_content.insert(xml_content);
- block_content.insert(xml_extra);
- li_content.insert(block_content);
- editbox.insert(li_content);
- }
- if ( removes.indexOf('value') == -1 ) {
- var li_value = new Element('li');
- var label_value = new Element('label').update("Value (Default)");
- var block_value = new Element('div', { 'class': 'block' });
- var error_value = new Element('span', { 'class': 'fielderror' });
- var field_value = new Element('input', { 'type': 'text', 'name': 'base_value', 'value': ( current.raw.value || "" ) });
- li_value.insert(label_value);
- block_value.insert(error_value);
- block_value.insert(field_value);
- li_value.insert(block_value);
- editbox.insert(li_value);
- }
- var options_blocks = [];
- if ( these.types[type] && these.types[type].options ) {
- var li_option = new Element('li');
- var label_option = new Element('label').update("Options");
- var block_option = new Element('div', { 'class': 'block' });
- var error_option = new Element('span', { 'class': 'fielderror' });
- var add_option_cb = function(item,container) {
- var options_key = new Element('input', { 'type': 'text', 'value': ( item[0] || "" ) });
- var options_option = new Element('input', { 'type': 'text', 'value': ( item[1] || "" ) });
- var options_drop = new Element('a').update("â ");
- var options_set = [ options_key, options_option ];
- options_blocks.push(options_set);
- container.insert(options_key);
- container.insert(options_option);
- container.insert(options_drop);
- options_drop.on('click', function() {
- options_key.remove();
- options_option.remove();
- options_drop.remove();
- options_set = [];
- });
- };
- if ( current.raw && current.raw.options) {
- // Loop over every option
- current.raw.options.each( function(item,idx) {
- add_option_cb(item,block_option);
- });
- }
- li_option.insert(label_option);
- block_option.insert(error_option);
- li_option.insert(block_option);
- var add_option = new Element('a').update("Add option");
- add_option.on('click', function() {
- add_option.remove();
- add_option_cb([],block_option);
- block_option.insert(add_option);
- });
- block_option.insert(add_option);
- editbox.insert(li_option);
- }
- var attribute_sets = [];
- if (these.types[type] && these.types[type].attributes && these.types[type].attributes.length > 0) {
- var li_attribute = new Element('li');
- var label_attribute = new Element('label').update("Attributes");
- var block_attribute = new Element('div', { 'class': 'block' });
- var error_attribute = new Element('span', { 'class': 'fielderror' });
- var attributes = current.raw.attributes;
- var add_attribute_cb = function(key,item,container, before) {
- var attribute_key = new Element('span', { 'class': 'attribute_title' } ).update(key);
- var attribute_value = new Element('input', { 'type': 'text', 'value': item });
- var attribute_drop = new Element('a').update("â ");
- var attribute_next = new Element('br');
- var attribute_set = [attribute_key, attribute_value, key];
- attribute_sets.push(attribute_set);
- if ( before ) {
- before.insert( { 'before': attribute_key });
- before.insert( { 'before': attribute_value });
- before.insert( { 'before': attribute_drop });
- before.insert( { 'before': attribute_next });
- } else {
- container.insert(attribute_key);
- container.insert(attribute_value);
- container.insert(attribute_drop);
- container.insert(attribute_next);
- }
- attribute_drop.on('click', function() {
- attribute_key.remove();
- attribute_value.remove();
- attribute_drop.remove();
- attribute_next.remove();
- attribute_sets = attribute_sets.filter( function(it) { it[2] != key } );
- });
- };
- // Loop over every option
- for ( var key in attributes ) {
- var item = attributes[key];
- add_attribute_cb(key,item,block_attribute);
- };
- var add_select = new Element('select', { 'name': 'attribute_select', 'id': 'attribute_select' } );
- these.types[type].attributes.each( function(item,idx) {
- var add_option = new Element('option', { 'value': item }).update(item);
- add_select.insert(add_option);
- });
- var add_attribute = new Element('a').update(" Add attribute");
- add_attribute.on('click', function() {
- var attribute_type = add_select.getValue();
- add_attribute_cb(attribute_type,false, block_attribute, add_select );
- });
- block_attribute.insert(add_select);
- block_attribute.insert(add_attribute);
- li_attribute.insert(label_attribute);
- block_attribute.insert(error_attribute);
- li_attribute.insert(block_attribute);
- editbox.insert(li_attribute);
- }
- var attribute_xml_sets = [];
- if (these.types[type] && these.types[type].attributes && these.types[type].attributes.length > 0) {
- var li_attribute_xml = new Element('li');
- var label_attribute_xml = new Element('label').update("Attributes XML");
- var block_attribute_xml = new Element('div', { 'class': 'block' });
- var error_attribute_xml = new Element('span', { 'class': 'fielderror' });
- var attribute_xmls = current.raw.attributes_xml;
- var add_attribute_xml_cb = function(key,item,container, before) {
- if ( item ) { item.replace(/"/, "\""); }
- var attribute_xml_key = new Element('span', { 'class': 'attribute_title' } ).update(key);
- var attribute_xml_value = new Element('input', { 'type': 'text', 'value': item });
- var attribute_xml_drop = new Element('a').update("â ");
- var attribute_xml_next = new Element('br');
- var attribute_xml_set = [attribute_xml_key, attribute_xml_value, key];
- attribute_xml_sets.push(attribute_xml_set);
- if ( before ) {
- before.insert( { 'before': attribute_xml_key });
- before.insert( { 'before': attribute_xml_value });
- before.insert( { 'before': attribute_xml_drop });
- before.insert( { 'before': attribute_xml_next });
- } else {
- container.insert(attribute_xml_key);
- container.insert(attribute_xml_value);
- container.insert(attribute_xml_drop);
- container.insert(attribute_xml_next);
- }
- attribute_xml_drop.on('click', function() {
- attribute_xml_key.remove();
- attribute_xml_value.remove();
- attribute_xml_drop.remove();
- attribute_xml_next.remove();
- attribute_xml_sets = attribute_xml_sets.filter( function(it) { it[2] != key } );
- });
- };
- // Loop over every option
- for ( var key in attribute_xmls ) {
- var item = attribute_xmls[key];
- add_attribute_xml_cb(key,item,block_attribute_xml);
- };
- var add_select_xml = new Element('select', { 'name': 'attribute_xml_select', 'id': 'attribute_xml_select' } );
- these.types[type].attributes.each( function(item,idx) {
- var add_option = new Element('option', { 'value': item }).update(item);
- add_select_xml.insert(add_option);
- });
- var add_attribute_xml = new Element('a').update(" Add attribute (XML, no escaping)");
- add_attribute_xml.on('click', function() {
- var attribute_xml_type = add_select_xml.getValue();
- add_attribute_xml_cb(attribute_xml_type,false, block_attribute_xml, add_select_xml );
- });
- block_attribute_xml.insert(add_select_xml);
- block_attribute_xml.insert(add_attribute_xml);
- li_attribute_xml.insert(label_attribute_xml);
- block_attribute_xml.insert(error_attribute_xml);
- li_attribute_xml.insert(block_attribute_xml);
- editbox.insert(li_attribute_xml);
- }
- if ( removes.indexOf('constraints') == -1 ) {
- var constraint_sets = [];
- var li_constraint = new Element('li');
- var label_constraint = new Element('label').update("Constraints");
- var block_constraint = new Element('div', { 'class': 'block' });
- var error_constraint = new Element('span', { 'class': 'fielderror' });
- var constraints = current.raw.constraints;
- var add_constraint_cb = function(key,item,container, before) {
- var build = these.constraints[key];
- if (!build) {
- alert("Error please add " + key + "to the list of constraints");
- }
- var constraint_key = new Element('span',{'class': 'contraint_type' } ).update(key);
- var constraint_config_input = {};
- $A(build.configs).each( function(citem,idx) {
- var clabel = new Element('span', { 'class':'constraint_title' }).update(citem);
- var cinput = new Element('input', { 'type': 'text', 'value': (item[citem] || "" ) });
- var cnext = new Element('br');
- constraint_config_input[citem] = [ clabel, cinput, cnext ] ;
- });
- var constraint_drop = new Element('a').update("â ");
- var constraint_next = new Element('br');
- constraint_sets.push([constraint_key, constraint_config_input,key]);
- if ( before ) {
- before.insert( { 'before': constraint_key });
- $H(constraint_config_input).each( function(item) {
- before.insert( { 'before': item.value[2] });
- before.insert( { 'before': item.value[0] });
- before.insert( { 'before': item.value[1] });
- });
- before.insert( { 'before': constraint_drop });
- before.insert( { 'before': constraint_next });
- } else {
- container.insert(constraint_key);
- $H(constraint_config_input).each( function(item) {
- container.insert(item.value[2]);
- container.insert(item.value[0]);
- container.insert(item.value[1]);
- });
- container.insert(constraint_drop);
- container.insert(constraint_next);
- }
- constraint_drop.on('click', function() {
- constraint_key.remove();
- constraint_drop.remove();
- constraint_next.remove();
- $H(constraint_config_input).each( function(item) {
- item.value[0].remove();
- item.value[1].remove();
- item.value[2].remove();
- });
- constraint_sets = constraint_sets.filter( function(it) { it[3] != item.key } );
- });
- };
- // Loop over every constraint
- $A(constraints).each( function(item,idx) {
- if (Object.isString(item)) {
- var type = item;
- add_constraint_cb(type,item,block_constraint);
- } else {
- add_constraint_cb(item.type,item,block_constraint);
- }
- });
- var add_c_select = new Element('select', { 'name': 'constraint_select', 'id': 'constraint_select' } );
- $H(these.constraints).each( function(item,idx) {
- var add_option = new Element('option', { 'value': item.key }).update(item.key);
- add_c_select.insert(add_option);
- });
- var add_constraint = new Element('a').update("Add constraint");
- add_constraint.on('click', function() {
- var constraint_type = add_c_select.getValue();
- add_constraint_cb(constraint_type,false, block_constraint, add_c_select );
- });
- block_constraint.insert(add_c_select);
- block_constraint.insert(add_constraint);
- li_constraint.insert(label_constraint);
- block_constraint.insert(error_constraint);
- li_constraint.insert(block_constraint);
- editbox.insert(li_constraint);
- }
- var last = new Element('div');
- var submit = new Element('button', { 'type': 'button' }).update(button_title);
- var cancel = new Element('a', { 'style': 'color: #900' }).update("cancel");
- cancel.on('click', function(event) { editbox.remove() });
- last.insert(submit);
- last.insert(cancel);
- var error_block = false;
- submit.on('click', function(event) {
- var errors = 0;
- if ( error_block ) { error_block.remove(); }
- var raw = {};
- if (removes.indexOf('name') == -1 ) {
- error_name.update("");
- var value_name = field_name.getValue();
- raw.name = value_name;
- if (!value_name) { error_name.update("Please add a unique variable name"); errors++; };
- if ( these.checkexistname( value_name, node.raw.name ) ) { error_name.update("Please choose a other name, name exists"); errors++ };
- }
- if (removes.indexOf('label') == -1 ) {
- error_label.update("");
- var value_label = field_label.getValue();
- if ( xml_label.checked == true ) {
- raw.label_xml = value_label;
- raw.label = undefined;
- } else {
- raw.label = value_label;
- raw.label_xml = undefined;
- }
- if (!value_label) { error_label.update("Pease add a label"); errors++ };
- }
- if ( type == 'Block' ) {
- error_content.update("");
- var value_label = field_content.getValue();
- if ( xml_content.checked == true ) {
- raw.content_xml = value_label;
- raw.content = undefined;
- } else {
- raw.content = value_label;
- raw.content_xml = undefined;
- }
- }
- if (removes.indexOf('value') == -1 ) {
- error_value.update("");
- var value_value = field_value.getValue();
- raw.value = value_value;
- }
- // options for select
- options_blocks.each( function(item,idx) {
- if ( idx == 0) {
- // Initialize options
- raw.options = $A([]);
- }
- if ( item.length == 2 ) {
- var option_key = item[0];
- var option_value = item[1];
- var option_key_value = option_key.getValue();
- var option_value_value = option_value.getValue();
- if ( idx == 0 || ( option_key_value && option_value_value)) {
- raw.options.push( [ option_key_value, option_value_value ] ) ;
- }
- }
- });
- if ( removes.indexOf('constraints') == -1 ) {
- raw.constraints = [];
- constraint_sets.each( function(item,idx) {
- var constraint = { };
- if ( $H(item[1]).keys().length ) {
- constraint.type = item[2];
- $H(item[1]).each(function(config) {
- constraint[config.key] = config.value[1].getValue();
- });
- } else {
- constraint = item[2];
- }
- raw.constraints.push( constraint );
- });
- }
- attribute_sets.each( function(item,idx) {
- if ( idx == 0 ) {
- raw.attributes = {};
- }
- if ( item.length == 3) {
- var attribute_key_field = item[0];
- var attribute_value_field = item[1];
- var attribute_key = attribute_key_field.innerHTML;
- var attribute_value = attribute_value_field.value;
- raw.attributes[attribute_key] = attribute_value;
- }
- });
- attribute_xml_sets.each( function(item,idx) {
- if ( idx == 0 ) {
- raw.attributes_xml = {};
- }
- if ( item.length == 3) {
- var attribute_key_field = item[0];
- var attribute_value_field = item[1];
- var attribute_key = attribute_key_field.innerHTML;
- var attribute_value = attribute_value_field.value;
- raw.attributes_xml[attribute_key] = attribute_value;
- }
- });
- if ( errors ) {
- error_block = new Element('li', { 'style': 'color: #900; font-weight: bold' }).update('Please fill in as described');
- title.insert( { 'after': error_block });
- } else {
- callback(ele,node,raw);
- editbox.remove();
- }
- });
- editbox.insert(last);
- ele.insert(editbox);
- } else {
- // unknown Type
- // Ask for Config
- var editbox = new Element('ul', { 'class': 'form_editor_dialog' });
- var title = new Element('li', { 'class': 'boxheader'}).update("Edit unknown type " + type);
- editbox.insert(title);
- ele.insert(editbox);
- var rawc = new Element('li');
- var rawbox = new Element('textarea', { 'style': 'width: 430px; height: 300px' });
- var jsonraw = Object.toJSON(node.raw);
- these.convert_j2y(jsonraw, function(yamlraw) {
- rawbox.value = yamlraw;
- rawc.insert(rawbox);
- editbox.insert(rawc);
- var last = new Element('li');
- var submit = new Element('button', { 'type': 'button' }).update("Update");
- var cancel = new Element('a', { 'style': 'color: #900' }).update("cancel");
- cancel.on('click', function(event) { editbox.remove() });
- last.insert(submit);
- last.insert(cancel);
- submit.on('click', function(event) {
- var rawcode = rawbox.value;
- these.convert_y2j(rawcode, function(raw) {
- callback(ele,node,raw.evalJSON());
- editbox.remove();
- });
- });
- editbox.insert(last);
- });
- }
- },
- // add an element, select field type
- add_element: function(ele) {
- var these = this;
- // Show possible types
- var selectbox = new Element('ul', { 'class': 'form_editor_dialog' });
- var title = new Element('li', { 'class': 'boxheader'}).update('1/2 Select field type');
- selectbox.insert(title);
- $H(these.types).each( function(pair) {
- var item = new Element('li', { 'class': 'type' }).update(pair.value.description);
- item.store(pair.value);
- selectbox.insert(item);
- item.on('click', function(event) { selectbox.remove(); these.askadd_element( ele, pair.value.type ) });
- });
- var cancel = new Element('li', { 'style': 'color: #900' }).update("cancel");
- cancel.on('click', function(event) { selectbox.remove() });
- selectbox.insert(cancel);
- ele.insert(selectbox);
- },
- // configure dialog for add a new field
- askadd_element: function(ele,type) {
- var these = this;
- var cb = function(ele,node,raw) {
- these.doadd_element(ele, Object.extend( raw, { type: type } ));
- these.rendertree();
- };
- return this._dialog_element('add', ele, { raw: {}}, "2/2 Configure field", "Add", cb, type )
- },
- // add the new Element
- doadd_element: function(ele, raw) {
- var these = this;
- // History
- these.undopoint();
- // Render HTML on the serverside
- new Ajax.Request(these.renderer, {
- 'method': 'post',
- 'asynchronous': false,
- 'parameters': { 'json': Object.toJSON(raw) },
- 'onSuccess': function(response) {
- var ans = response.responseJSON;
- var htmlcode = ans.container;
- var node = ele.retrieve('object')
- if ( node && node.pt ) {
- var newnode = new FormEditorNode(raw, htmlcode, these.nodelist.get(node.pt) );
- these.nodelist.set(raw.name,newnode);
- ele.insert( { after: htmlcode } );
- } else if ( node && !node.pt ) {
- var fs = ele.select('fieldset');
- var fsf = fs.reverse()[0];
- fsf.insert( { 'top': htmlcode });
- var newnode = new FormEditorNode(raw, htmlcode,node );
- these.nodelist.set(raw.name,newnode);
- } else {
- ele.insert( htmlcode );
- var newnode = new FormEditorNode(raw, htmlcode );
- these.nodelist.set(raw.name,newnode);
- }
- these.rendertree();
- },
- 'onFailure': function() {
- alert("Could not convert");
- }
- });
- },
- _current: function() {
- var these = this;
- return [ Object.toJSON(these.serialize()), these.form.innerHTML ];
- },
- // Undo the last action
- undo: function() {
- var these = this;
- var set = these.history_undo.pop();
- if ( set ) {
- these.history_redo.push(these._current());
- these.tree = set[0].evalJSON();
- these.form.update( set[1] );
- these.form.select('.form_editor_toolbar').map(Element.remove);
- these.form.select('.form_editor_dialog').map(Element.remove);
- these.rendertree();
- }
- if ( these.undo_button) {
- these.undo_button.disabled = these.history_undo.length ? false : true;
- }
- if ( these.redo_button) {
- these.redo_button.disabled = these.history_redo.length ? false : true;
- }
- },
- // create an undo point
- undopoint: function() {
- var these = this;
- these.history_undo.push(these._current());
- if ( these.undo_button) {
- these.undo_button.disabled = these.history_undo.length ? false : true;
- }
- if ( these.redo_button) {
- these.redo_button.disabled = these.history_redo.length ? false : true;
- }
- },
- // redo the last action
- redo: function() {
- var these = this;
- var set = these.history_redo.pop();
- if ( set ) {
- these.history_undo.push(these._current());
- these.tree = set[0].evalJSON();
- these.form.update( set[1] );
- these.form.select('.form_editor_toolbar').map(Element.remove);
- these.form.select('.form_editor_dialog').map(Element.remove);
- these.rendertree();
- }
- if ( this.undo_button) {
- this.undo_button.disabled = these.history_undo.length ? false : true;
- }
- if ( this.redo_button) {
- this.redo_button.disabled = these.history_redo.length ? false : true;
- }
- },
- // Validate name, check if there no other field with the same name
- checkexistname: function(name, old) {
- var these = this;
- var match = false;
- if ( name && old && name === old ) {
- return false;
- }
- return match;
- },
- // sort up, unless the ele is the first
- up_element: function(ele) {
- var these = this;
- // find previous element
- var prev_eles = ele.previousSiblings();
- if ( prev_eles.length > 0 ) {
- these.undopoint();
- var prev = prev_eles[0].remove();
- ele.insert( { after: prev });
- }
- },
- // sort down, unless the ele is the last
- down_element: function(ele) {
- var these = this;
- // find previous element
- var next_eles = ele.nextSiblings();
- if ( next_eles.length > 0 ) {
- these.undopoint();
- var next = next_eles[0].remove();
- ele.insert( { before: next });
- }
- },
- // delete the element
- delete_element: function(ele) {
- var these = this;
- // make History
- these.undopoint();
- // retrieve object from element
- var node = ele.retrieve('object');
- var key = node.raw.name;
- // Remove from list of elements
- these.elements.unset(key);
- // Remove form nodes
- these.nodelist.unset(key);
- // Remove form html
- node.html.remove();
- // Remove node
- these.rendertree();
- },
- elementsselect: function() {
- var these = this;
- var elementselect = new Element('div', { 'class': 'form_editor_select_elements' });
- },
- // render the whole tree, cleanup the container
- rendertree: function() {
- var these = this;
- // Parse recursive
- these.parseform(these.form);
- if ( these.elements && these.elements.size() == 0 ) {
- // no elements given, inital add-button
- var toolbar = new Element('div', { 'class': 'form_editor_toolbar' });
- var a_add = new Element('a', { 'class': 'form_editor_toolbar_add' }).update('add');
- toolbar.insert(a_add);
- these.form.down('fieldset').setStyle({ 'position':'relative' });
- these.form.down('fieldset').insert(toolbar);
- a_add.observe('click', function(e) {
- these.add_element(these.form.down('fieldset'));
- });
- }
- // start recursive build
- these.build(these.tree);
- // combine HTML with nodes
- these.elements.each( function(item) {
- var ele = item.value;
- var dataset = ele.getDataset();
- var fename = dataset['fe-name'] || dataset.feName;
- var node = these.nodelist.get(fename);
- if ( node ) {
- ele.store('object', node );
- node.html = ele;
- these.showtoolbar(ele);
- }
- });
- },
- // build a node and subnodes
- build: function(raw,parentnode) {
- var these = this;
- var node = new FormEditorNode( raw, undefined, parentnode );
- // Set as root node
- if (!parentnode) {
- these.root = node;
- }
- // Store nodes
- these.nodelist.set(node.raw.name, node);
- if ( raw.elements) {
- raw.elements.each( function(ele) { these.build(ele,node) });
- }
- },
- convert_y2j : function(yaml,cb) {
- var these = this;
- new Ajax.Request(these.y2j, {
- 'method': 'post',
- 'parameters': { 'yaml': yaml },
- 'onSuccess': function(transport) {
- errormsg();
- cb( transport.responseText);
- },
- 'onFailure': function(transport){
- infomsg();
- errormsg(transport.responseText);
- return;
- }
- });
- },
- convert_j2y : function(json,cb) {
- var these = this;
- new Ajax.Request(these.j2y, {
- 'method': 'post',
- 'parameters': { 'json': json },
- 'onSuccess': function(transport) {
- errormsg();
- cb( transport.responseText);
- },
- 'onFailure': function(transport){
- infomsg("Error");
- errormsg(transport.responseText);
- return;
- }
- });
- }
- });