mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
Prerequisites to the custom fields (and space tabs to regular tabs conversion on some files)
SVN:trunk[3919]
This commit is contained in:
562
js/field_set.js
562
js/field_set.js
@@ -1,305 +1,307 @@
|
||||
//iTop Form handler
|
||||
//iTop Field set
|
||||
//Used by itop.form_handler and itop.subform_field to list their fields
|
||||
;
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'form_handler' the widget name
|
||||
$.widget( 'itop.field_set',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
field_identifier_attr: 'data-field-id', // convention: fields are rendered into a div and are identified by this attribute
|
||||
fields_list: null,
|
||||
fields_impacts: {},
|
||||
touched_fields: [],
|
||||
is_valid: true,
|
||||
form_path: '',
|
||||
script_element: null,
|
||||
style_element: null
|
||||
},
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'field_set' the widget name
|
||||
$.widget( 'itop.field_set',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
field_identifier_attr: 'data-field-id', // convention: fields are rendered into a div and are identified by this attribute
|
||||
fields_list: null,
|
||||
fields_impacts: {},
|
||||
touched_fields: [],
|
||||
is_valid: true,
|
||||
form_path: '',
|
||||
script_element: null,
|
||||
style_element: null
|
||||
},
|
||||
|
||||
buildData:
|
||||
{
|
||||
script_code: '',
|
||||
style_code: ''
|
||||
},
|
||||
buildData:
|
||||
{
|
||||
script_code: '',
|
||||
style_code: ''
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('field_set');
|
||||
|
||||
this.element
|
||||
.bind('field_change', function(event, data){
|
||||
console.log('field_set: field_change');
|
||||
me._onFieldChange(event, data);
|
||||
})
|
||||
.bind('update_form', function(event, data){
|
||||
console.log('field_set: update_form');
|
||||
me._onUpdateForm(event, data);
|
||||
})
|
||||
.bind('get_current_values', function(event, data){
|
||||
console.log('field_set: get_current_values');
|
||||
return me._onGetCurrentValues(event, data);
|
||||
})
|
||||
.bind('validate', function(event, data){
|
||||
if (data === undefined)
|
||||
{
|
||||
data = {};
|
||||
}
|
||||
console.log('field_set: validate');
|
||||
return me._onValidate(event, data);
|
||||
});
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('field_set');
|
||||
|
||||
this.element
|
||||
.bind('field_change', function(oEvent, oData){
|
||||
console.log('field_set: field_change');
|
||||
me._onFieldChange(oEvent, oData);
|
||||
})
|
||||
.bind('update_form', function(oEvent, oData){
|
||||
console.log('field_set: update_form');
|
||||
me._onUpdateForm(oEvent, oData);
|
||||
})
|
||||
.bind('get_current_values', function(oEvent, oData){
|
||||
console.log('field_set: get_current_values');
|
||||
return me._onGetCurrentValues(oEvent, oData);
|
||||
})
|
||||
.bind('validate', function(oEvent, oData){
|
||||
if (oData === undefined)
|
||||
{
|
||||
oData = {};
|
||||
}
|
||||
console.log('field_set: validate');
|
||||
return me._onValidate(oEvent, oData);
|
||||
});
|
||||
|
||||
// Creating DOM elements if not using user's specifics
|
||||
if(this.options.script_element === null)
|
||||
{
|
||||
this.options.script_element = $('<script type="text/javascript"></script>');
|
||||
this.element.after(this.options.script_element);
|
||||
}
|
||||
if(this.options.style_element === null)
|
||||
{
|
||||
this.options.style_element = $('<style></style>');
|
||||
this.element.before(this.options.style_element);
|
||||
}
|
||||
// Creating DOM elements if not using user's specifics
|
||||
if(this.options.script_element === null)
|
||||
{
|
||||
this.options.script_element = $('<script type="text/javascript"></script>');
|
||||
this.element.after(this.options.script_element);
|
||||
}
|
||||
if(this.options.style_element === null)
|
||||
{
|
||||
this.options.style_element = $('<style></style>');
|
||||
this.element.before(this.options.style_element);
|
||||
}
|
||||
|
||||
// Building the form
|
||||
if(this.options.fields_list !== null)
|
||||
{
|
||||
this.buildForm();
|
||||
}
|
||||
},
|
||||
// Building the form
|
||||
if(this.options.fields_list !== null)
|
||||
{
|
||||
this.buildForm();
|
||||
}
|
||||
},
|
||||
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('field_set');
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
// always refresh when changing options
|
||||
_setOptions: function()
|
||||
{
|
||||
this._superApply(arguments);
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
this._super( key, value );
|
||||
},
|
||||
_getField: function (sFieldId)
|
||||
{
|
||||
return this.element.find('[' + this.options.field_identifier_attr + '="'+sFieldId+'"][data-form-path="'+this.options.form_path+'"]');
|
||||
},
|
||||
_onGetCurrentValues: function(event, data)
|
||||
{
|
||||
event.stopPropagation();
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('field_set');
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
// always refresh when changing options
|
||||
_setOptions: function()
|
||||
{
|
||||
this._superApply(arguments);
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
this._super( key, value );
|
||||
},
|
||||
getField: function (sFieldId)
|
||||
{
|
||||
return this.element.find('[' + this.options.field_identifier_attr + '="' + sFieldId + '"][data-form-path="' + this.options.form_path + '"]');
|
||||
},
|
||||
_onGetCurrentValues: function(oEvent, oData)
|
||||
{
|
||||
oEvent.stopPropagation();
|
||||
|
||||
var result = {};
|
||||
|
||||
for(var i in this.options.fields_list)
|
||||
{
|
||||
var field = this.options.fields_list[i];
|
||||
if(this._getField(field.id).hasClass('form_field'))
|
||||
{
|
||||
result[field.id] = this._getField(field.id).triggerHandler('get_current_value');
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Field set : Cannot retrieve current value from field [' + this.options.field_identifier_attr + '="'+field.id+'"] as it seems to have no itop.form_field widget attached.');
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
_getRequestedFields: function(sourceFieldName)
|
||||
{
|
||||
var fieldsName = [];
|
||||
|
||||
if(this.options.fields_impacts[sourceFieldName] !== undefined)
|
||||
{
|
||||
for(var i in this.options.fields_impacts[sourceFieldName])
|
||||
{
|
||||
fieldsName.push(this.options.fields_impacts[sourceFieldName][i]);
|
||||
}
|
||||
}
|
||||
|
||||
return fieldsName;
|
||||
},
|
||||
_onFieldChange: function(event, data)
|
||||
{
|
||||
event.stopPropagation();
|
||||
var oResult = {};
|
||||
|
||||
for(var i in this.options.fields_list)
|
||||
{
|
||||
var oField = this.options.fields_list[i];
|
||||
if(this.getField(oField.id).hasClass('form_field'))
|
||||
{
|
||||
oResult[oField.id] = this.getField(oField.id).triggerHandler('get_current_value');
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Field set : Cannot retrieve current value from field [' + this.options.field_identifier_attr + '="' + oField.id + '"][data-form-path="' + this.options.form_path + '"] as it seems to have no itop.form_field widget attached.');
|
||||
}
|
||||
}
|
||||
|
||||
return oResult;
|
||||
},
|
||||
_getRequestedFields: function(sSourceFieldName)
|
||||
{
|
||||
var aFieldsName = [];
|
||||
|
||||
if(this.options.fields_impacts[sSourceFieldName] !== undefined)
|
||||
{
|
||||
for(var i in this.options.fields_impacts[sSourceFieldName])
|
||||
{
|
||||
aFieldsName.push(this.options.fields_impacts[sSourceFieldName][i]);
|
||||
}
|
||||
}
|
||||
|
||||
return aFieldsName;
|
||||
},
|
||||
_onFieldChange: function(oEvent, oData)
|
||||
{
|
||||
oEvent.stopPropagation();
|
||||
|
||||
// Set field as touched so we know that we have to do checks on it later
|
||||
if(this.options.touched_fields.indexOf(data.name) < 0)
|
||||
{
|
||||
this.options.touched_fields.push(data.name);
|
||||
}
|
||||
// Set field as touched so we know that we have to do checks on it later
|
||||
if(this.options.touched_fields.indexOf(oData.name) < 0)
|
||||
{
|
||||
this.options.touched_fields.push(oData.name);
|
||||
}
|
||||
|
||||
// Validate the field
|
||||
var oRes = this._getField(data.name).triggerHandler('validate', {touched_fields_only: true});
|
||||
if (!oRes.is_valid)
|
||||
{
|
||||
this.options.is_valid = false;
|
||||
}
|
||||
// Validate the field
|
||||
var oResult = this.getField(oData.name).triggerHandler('validate', {touched_fields_only: true});
|
||||
if (!oResult.is_valid)
|
||||
{
|
||||
this.options.is_valid = false;
|
||||
}
|
||||
|
||||
var requestedFields = this._getRequestedFields(data.name);
|
||||
if(requestedFields.length > 0)
|
||||
{
|
||||
this.element.trigger('update_fields', {form_path: this.options.form_path, requested_fields: requestedFields});
|
||||
}
|
||||
},
|
||||
_onUpdateForm: function(event, data)
|
||||
{
|
||||
event.stopPropagation();
|
||||
var oRequestedFields = this._getRequestedFields(oData.name);
|
||||
if(oRequestedFields.length > 0)
|
||||
{
|
||||
this.element.trigger('update_fields', {form_path: this.options.form_path, requested_fields: oRequestedFields});
|
||||
}
|
||||
},
|
||||
_onUpdateForm: function(oEvent, oData)
|
||||
{
|
||||
oEvent.stopPropagation();
|
||||
|
||||
this.buildData.script_code = '';
|
||||
this.buildData.style_code = '';
|
||||
this.buildData.script_code = '';
|
||||
this.buildData.style_code = '';
|
||||
|
||||
for (var i in data.updated_fields)
|
||||
{
|
||||
var updated_field = data.updated_fields[i];
|
||||
this.options.fields_list[updated_field.id] = updated_field;
|
||||
this._prepareField(updated_field.id);
|
||||
}
|
||||
for (var i in oData.updated_fields)
|
||||
{
|
||||
var oUpdatedField = oData.updated_fields[i];
|
||||
this.options.fields_list[oUpdatedField.id] = oUpdatedField;
|
||||
this._prepareField(oUpdatedField.id);
|
||||
}
|
||||
|
||||
// Adding code to the dom
|
||||
this.options.script_element.append('\n\n// Appended by update at ' + Date() + '\n' + this.buildData.script_code);
|
||||
this.options.style_element.append('\n\n// Appended by update at ' + Date() + '\n' + this.buildData.style_code);
|
||||
// Adding code to the dom
|
||||
this.options.script_element.append('\n\n// Appended by update on ' + Date() + '\n' + this.buildData.script_code);
|
||||
this.options.style_element.append('\n\n// Appended by update on ' + Date() + '\n' + this.buildData.style_code);
|
||||
|
||||
// Evaluating script code as adding it to dom did not executed it (only script from update !)
|
||||
eval(this.buildData.script_code);
|
||||
},
|
||||
_onValidate: function(event, data)
|
||||
{
|
||||
event.stopPropagation();
|
||||
// Evaluating script code as adding it to dom did not executed it (only script from update !)
|
||||
eval(this.buildData.script_code);
|
||||
},
|
||||
_onValidate: function(oEvent, oData)
|
||||
{
|
||||
oEvent.stopPropagation();
|
||||
|
||||
this.options.is_valid = true;
|
||||
this.options.is_valid = true;
|
||||
|
||||
var aFieldsToValidate = [];
|
||||
if ((oData.touched_fields_only !== undefined) && (oData.touched_fields_only === true))
|
||||
{
|
||||
aFieldsToValidate = this.options.touched_fields;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO : Requires IE9+ Object.keys(this.options.fields_list);
|
||||
for (var sFieldId in this.options.fields_list)
|
||||
{
|
||||
aFieldsToValidate.push(sFieldId);
|
||||
}
|
||||
}
|
||||
|
||||
var aFieldsToValidate = [];
|
||||
if ((data.touched_fields_only !== undefined) && (data.touched_fields_only === true))
|
||||
{
|
||||
aFieldsToValidate = this.options.touched_fields;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Requires IE9+ Object.keys(this.options.fields_list);
|
||||
for (var sFieldId in this.options.fields_list)
|
||||
{
|
||||
aFieldsToValidate.push(sFieldId);
|
||||
}
|
||||
}
|
||||
for(var i in aFieldsToValidate)
|
||||
{
|
||||
var oRes = this.getField(aFieldsToValidate[i]).triggerHandler('validate', oData);
|
||||
if (!oRes.is_valid)
|
||||
{
|
||||
this.options.is_valid = false;
|
||||
}
|
||||
}
|
||||
return this.options.is_valid;
|
||||
},
|
||||
// Debug helper
|
||||
showOptions: function()
|
||||
{
|
||||
return this.options;
|
||||
},
|
||||
_loadCssFile: function(url)
|
||||
{
|
||||
if (!$('link[href="' + url + '"]').length)
|
||||
$('<link href="' + url + '" rel="stylesheet">').appendTo('head');
|
||||
},
|
||||
_loadJsFile: function(url)
|
||||
{
|
||||
if (!$('script[src="' + url + '"]').length)
|
||||
$.getScript(url);
|
||||
},
|
||||
// Place a field for which no container exists
|
||||
_addField: function(sFieldId)
|
||||
{
|
||||
$('<div ' + this.options.field_identifier_attr + '="' + sFieldId + '" data-form-path="' + this.options.form_path + '"></div>').appendTo(this.element);
|
||||
},
|
||||
_prepareField: function(sFieldId)
|
||||
{
|
||||
var oField = this.options.fields_list[sFieldId];
|
||||
|
||||
for(var i in aFieldsToValidate)
|
||||
{
|
||||
var oRes = this._getField(aFieldsToValidate[i]).triggerHandler('validate', data);
|
||||
if (!oRes.is_valid)
|
||||
{
|
||||
this.options.is_valid = false;
|
||||
}
|
||||
}
|
||||
return this.options.is_valid;
|
||||
},
|
||||
showOptions: function() // Debug helper
|
||||
{
|
||||
console.log(this.options);
|
||||
return this.options;
|
||||
},
|
||||
_loadCssFile: function(url)
|
||||
{
|
||||
if (!$('link[href="'+url+'"]').length)
|
||||
$('<link href="'+url+'" rel="stylesheet">').appendTo('head');
|
||||
},
|
||||
_loadJsFile: function(url)
|
||||
{
|
||||
if (!$('script[src="'+url+'"]').length)
|
||||
$.getScript(url);
|
||||
},
|
||||
// Place a field for which no container exists
|
||||
_addField: function(field_id)
|
||||
{
|
||||
$('<div ' + this.options.field_identifier_attr + '="'+field_id+'" data-form-path="' + this.options.form_path + '"></div>').appendTo(this.element);
|
||||
},
|
||||
_prepareField: function(field_id)
|
||||
{
|
||||
var field = this.options.fields_list[field_id];
|
||||
if(this.getField(oField.id).length === 1)
|
||||
{
|
||||
// We replace the node instead of just replacing the inner html so the previous widget is automatically destroyed.
|
||||
this.getField(oField.id).replaceWith(
|
||||
$('<div ' + this.options.field_identifier_attr + '="' + oField.id + '" data-form-path="' + this.options.form_path + '"></div>')
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._addField(oField.id);
|
||||
}
|
||||
|
||||
if(this._getField(field.id).length === 1)
|
||||
{
|
||||
// We replace the node instead of just replacing the inner html so the previous widget is automatically destroyed.
|
||||
this._getField(field.id).replaceWith( $('<div ' + this.options.field_identifier_attr + '="'+field.id+'" data-form-path="' + this.options.form_path + '"></div>') );
|
||||
}
|
||||
else
|
||||
{
|
||||
this._addField(field.id);
|
||||
}
|
||||
var oFieldContainer = this.getField(oField.id);
|
||||
// HTML
|
||||
if( (oField.html !== undefined) && (oField.html !== '') )
|
||||
{
|
||||
oFieldContainer.html(oField.html);
|
||||
}
|
||||
// JS files
|
||||
if( (oField.js_files !== undefined) && (oField.js_files.length > 0) )
|
||||
{
|
||||
for(var j in oField.js_files)
|
||||
{
|
||||
this._loadJsFile(oField.js_files[i]);
|
||||
}
|
||||
}
|
||||
// CSS files
|
||||
if( (oField.css_files !== undefined) && (oField.css_files.length > 0) )
|
||||
{
|
||||
for(var j in oField.css_files)
|
||||
{
|
||||
this._loadCssFile(oField.css_files[i]);
|
||||
}
|
||||
}
|
||||
// JS inline
|
||||
if( (oField.js_inline !== undefined) && (oField.js_inline !== '') )
|
||||
{
|
||||
this.buildData.script_code += '; '+ oField.js_inline;
|
||||
}
|
||||
// CSS inline
|
||||
if( (oField.css_inline !== undefined) && (oField.css_inline !== '') )
|
||||
{
|
||||
this.buildData.style_code += ' '+ oField.css_inline;
|
||||
}
|
||||
|
||||
},
|
||||
buildForm: function()
|
||||
{
|
||||
this.buildData.script_code = '';
|
||||
this.buildData.style_code = '';
|
||||
|
||||
var field_container = this._getField(field.id);
|
||||
// HTML
|
||||
if( (field.html !== undefined) && (field.html !== '') )
|
||||
{
|
||||
field_container.html(field.html);
|
||||
}
|
||||
// JS files
|
||||
if( (field.js_files !== undefined) && (field.js_files.length > 0) )
|
||||
{
|
||||
for(var j in field.js_files)
|
||||
{
|
||||
this._loadJsFile(field.js_files[i]);
|
||||
}
|
||||
}
|
||||
// CSS files
|
||||
if( (field.css_files !== undefined) && (field.css_files.length > 0) )
|
||||
{
|
||||
for(var j in field.css_files)
|
||||
{
|
||||
this._loadCssFile(field.css_files[i]);
|
||||
}
|
||||
}
|
||||
// JS inline
|
||||
if( (field.js_inline !== undefined) && (field.js_inline !== '') )
|
||||
{
|
||||
this.buildData.script_code += '; '+ field.js_inline;
|
||||
}
|
||||
// CSS inline
|
||||
if( (field.css_inline !== undefined) && (field.css_inline !== '') )
|
||||
{
|
||||
this.buildData.style_code += ' '+ field.css_inline;
|
||||
}
|
||||
|
||||
},
|
||||
buildForm: function()
|
||||
{
|
||||
this.buildData.script_code = '';
|
||||
this.buildData.style_code = '';
|
||||
for(var i in this.options.fields_list)
|
||||
{
|
||||
var oField = this.options.fields_list[i];
|
||||
if(oField.id === undefined)
|
||||
{
|
||||
console.log('Field set : An field must have at least an id property.');
|
||||
return false;
|
||||
}
|
||||
|
||||
for(var i in this.options.fields_list)
|
||||
{
|
||||
var field = this.options.fields_list[i];
|
||||
if(field.id === undefined)
|
||||
{
|
||||
console.log('Field set : An field must have at least an id property.');
|
||||
return false;
|
||||
}
|
||||
this._prepareField(oField.id);
|
||||
}
|
||||
|
||||
this._prepareField(field.id);
|
||||
}
|
||||
|
||||
this.options.script_element.text('$(document).ready(function(){ '+this.buildData.script_code+' });');
|
||||
this.options.style_element.text(this.buildData.style_code);
|
||||
|
||||
eval(this.options.script_element.text());
|
||||
}
|
||||
});
|
||||
this.options.script_element.text('$(document).ready(function(){ ' + this.buildData.script_code + ' });');
|
||||
this.options.style_element.text(this.buildData.style_code);
|
||||
|
||||
eval(this.options.script_element.text());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
394
js/form_field.js
394
js/form_field.js
@@ -2,203 +2,205 @@
|
||||
;
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'form_field' the widget name
|
||||
$.widget( 'itop.form_field',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
validators: null,
|
||||
validate_callback: 'validate', // When using an anonymous function, use the 'me' parameter to acces the current widget : function(me){ return me.validate(); },
|
||||
on_validation_callback: function(data){ },
|
||||
get_current_value_callback: 'getCurrentValue',
|
||||
|
||||
},
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'form_field' the widget name
|
||||
$.widget( 'itop.form_field',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
validators: null,
|
||||
validate_callback: 'validate', // When using an anonymous function, use the 'me' parameter to acces the current widget : function(me){ return me.validate(); },
|
||||
on_validation_callback: function(data){ },
|
||||
get_current_value_callback: 'getCurrentValue',
|
||||
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('form_field');
|
||||
|
||||
this.element
|
||||
.bind('set_validators', function(event, data){
|
||||
event.stopPropagation();
|
||||
me.options.validators = data;
|
||||
});
|
||||
this.element
|
||||
.bind('validate get_current_value', function(event, data){
|
||||
event.stopPropagation();
|
||||
var callback = me.options[event.type+'_callback'];
|
||||
|
||||
if(typeof callback === 'string')
|
||||
{
|
||||
return me[callback](event, data);
|
||||
}
|
||||
else if(typeof callback === 'function')
|
||||
{
|
||||
return callback(me, event, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field : callback type must be a function or a existing function name of the widget');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('form_field');
|
||||
|
||||
this.element
|
||||
.bind('set_validators', function(oEvent, oData){
|
||||
oEvent.stopPropagation();
|
||||
me.options.validators = oData;
|
||||
});
|
||||
this.element
|
||||
.bind('validate get_current_value', function(oEvent, oData){
|
||||
oEvent.stopPropagation();
|
||||
|
||||
var callback = me.options[oEvent.type+'_callback'];
|
||||
|
||||
if(typeof callback === 'string')
|
||||
{
|
||||
return me[callback](oEvent, oData);
|
||||
}
|
||||
else if(typeof callback === 'function')
|
||||
{
|
||||
return callback(me, oEvent, oData);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field : callback type must be a function or a existing function name of the widget');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('form_field');
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
// always refresh when changing options
|
||||
_setOptions: function()
|
||||
{
|
||||
this._superApply(arguments);
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
this._super( key, value );
|
||||
},
|
||||
getCurrentValue: function()
|
||||
{
|
||||
var value = null;
|
||||
|
||||
this.element.find(':input').each(function(index, elem){
|
||||
if($(elem).is(':hidden') || $(elem).is(':text') || $(elem).is('textarea'))
|
||||
{
|
||||
value = $(elem).val();
|
||||
}
|
||||
else if($(elem).is('select'))
|
||||
{
|
||||
value = [];
|
||||
$(elem).find('option:selected').each(function(){
|
||||
value.push($(this).val());
|
||||
});
|
||||
}
|
||||
else if($(elem).is(':checkbox') || $(elem).is(':radio'))
|
||||
{
|
||||
if(value === null)
|
||||
{
|
||||
value = [];
|
||||
}
|
||||
if($(elem).is(':checked'))
|
||||
{
|
||||
value.push($(elem).val());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field : Input type not handle yet.');
|
||||
}
|
||||
});
|
||||
|
||||
return value;
|
||||
},
|
||||
validate: function(event, data)
|
||||
{
|
||||
var oResult = { is_valid: true, error_messages: [] };
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('form_field');
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
// always refresh when changing options
|
||||
_setOptions: function()
|
||||
{
|
||||
this._superApply(arguments);
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
this._super( key, value );
|
||||
},
|
||||
getCurrentValue: function()
|
||||
{
|
||||
var value = null;
|
||||
|
||||
this.element.find(':input').each(function(iIndex, oElem){
|
||||
if($(oElem).is(':hidden') || $(oElem).is(':text') || $(oElem).is('textarea'))
|
||||
{
|
||||
value = $(oElem).val();
|
||||
}
|
||||
else if($(oElem).is('select'))
|
||||
{
|
||||
value = [];
|
||||
$(oElem).find('option:selected').each(function(){
|
||||
value.push($(this).val());
|
||||
});
|
||||
}
|
||||
else if($(oElem).is(':checkbox') || $(oElem).is(':radio'))
|
||||
{
|
||||
if(value === null)
|
||||
{
|
||||
value = [];
|
||||
}
|
||||
if($(oElem).is(':checked'))
|
||||
{
|
||||
value.push($(oElem).val());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field : Input type not handle yet.');
|
||||
}
|
||||
});
|
||||
|
||||
return value;
|
||||
},
|
||||
validate: function(oEvent, oData)
|
||||
{
|
||||
var oResult = { is_valid: true, error_messages: [] };
|
||||
|
||||
// Doing data validation
|
||||
if(this.options.validators !== null)
|
||||
{
|
||||
var bMandatory = (this.options.validators.mandatory !== undefined);
|
||||
// Extracting value for the field
|
||||
var oValue = this.getCurrentValue();
|
||||
var aValueKeys = Object.keys(oValue);
|
||||
|
||||
// This is just a safety check in case a field doesn't always return an object when no value assigned, so we have to check the mandatory validator here...
|
||||
// ... But this should never happen.
|
||||
if( (aValueKeys.length === 0) && bMandatory )
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(this.options.validators.mandatory.message);
|
||||
}
|
||||
// ... Otherwise, we check every validators
|
||||
else if(aValueKeys.length > 0)
|
||||
{
|
||||
var value = oValue[aValueKeys[0]];
|
||||
for(var sValidatorType in this.options.validators)
|
||||
{
|
||||
var oValidator = this.options.validators[sValidatorType];
|
||||
if(sValidatorType === 'mandatory')
|
||||
{
|
||||
// Works for string, array, object
|
||||
if($.isEmptyObject(value))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
// ... In case of non empty array, we have to check if the value is not null
|
||||
else if($.isArray(value))
|
||||
{
|
||||
for(var i in value)
|
||||
{
|
||||
if(typeof value[i] === 'string')
|
||||
{
|
||||
if($.isEmptyObject(value[i]))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field: mandatory validation not supported yet for the type "' + (typeof value[i]) +'"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var oRegExp = new RegExp(oValidator.reg_exp, "g");
|
||||
if(typeof value === 'string')
|
||||
{
|
||||
if(!oRegExp.test(value))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
}
|
||||
else if($.isArray(value))
|
||||
{
|
||||
for(var i in value)
|
||||
{
|
||||
if(value[i] === 'string' && !oRegExp.test(value))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field: validation not supported yet for the type "' + (typeof value) +'"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.options.on_validation_callback(this, oResult);
|
||||
|
||||
return oResult;
|
||||
},
|
||||
showOptions: function()
|
||||
{
|
||||
return this.options;
|
||||
}
|
||||
});
|
||||
// Doing data validation
|
||||
if(this.options.validators !== null)
|
||||
{
|
||||
var bMandatory = (this.options.validators.mandatory !== undefined);
|
||||
// Extracting value for the field
|
||||
var oValue = this.getCurrentValue();
|
||||
var aValueKeys = Object.keys(oValue);
|
||||
|
||||
// This is just a safety check in case a field doesn't always return an object when no value assigned, so we have to check the mandatory validator here...
|
||||
// ... But this should never happen.
|
||||
if( (aValueKeys.length === 0) && bMandatory )
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(this.options.validators.mandatory.message);
|
||||
}
|
||||
// ... Otherwise, we check every validators
|
||||
else if(aValueKeys.length > 0)
|
||||
{
|
||||
var value = oValue[aValueKeys[0]];
|
||||
for(var sValidatorType in this.options.validators)
|
||||
{
|
||||
var oValidator = this.options.validators[sValidatorType];
|
||||
if(sValidatorType === 'mandatory')
|
||||
{
|
||||
// Works for string, array, object
|
||||
if($.isEmptyObject(value))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
// ... In case of non empty array, we have to check if the value is not null
|
||||
else if($.isArray(value))
|
||||
{
|
||||
for(var i in value)
|
||||
{
|
||||
if(typeof value[i] === 'string')
|
||||
{
|
||||
if($.isEmptyObject(value[i]))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field: mandatory validation not supported yet for the type "' + (typeof value[i]) +'"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var oRegExp = new RegExp(oValidator.reg_exp, "g");
|
||||
if(typeof value === 'string')
|
||||
{
|
||||
if(!oRegExp.test(value))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
}
|
||||
else if($.isArray(value))
|
||||
{
|
||||
for(var i in value)
|
||||
{
|
||||
if(value[i] === 'string' && !oRegExp.test(value))
|
||||
{
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form field: validation not supported yet for the type "' + (typeof value) +'"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.options.on_validation_callback(this, oResult);
|
||||
|
||||
return oResult;
|
||||
},
|
||||
// Debug helper
|
||||
showOptions: function()
|
||||
{
|
||||
return this.options;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,150 +2,151 @@
|
||||
;
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'form_handler' the widget name
|
||||
$.widget( 'itop.form_handler',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
formmanager_class: null,
|
||||
formmanager_data: null,
|
||||
submit_btn_selector: null,
|
||||
cancel_btn_selector: null,
|
||||
endpoint: null,
|
||||
is_modal: false,
|
||||
field_set: null
|
||||
},
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'form_handler' the widget name
|
||||
$.widget( 'itop.form_handler',
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
formmanager_class: null,
|
||||
formmanager_data: null,
|
||||
submit_btn_selector: null,
|
||||
cancel_btn_selector: null,
|
||||
endpoint: null,
|
||||
is_modal: false,
|
||||
field_set: null
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('form_handler');
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('form_handler');
|
||||
|
||||
this.element.bind('update_fields', function(event, data){
|
||||
this._onUpdateFields(event, data);
|
||||
});
|
||||
// Binding events
|
||||
this.element.bind('update_fields', function(oEvent, oData){
|
||||
me._onUpdateFields(oEvent, oData);
|
||||
});
|
||||
|
||||
// Binding buttons
|
||||
if(this.options.submit_btn_selector !== null)
|
||||
{
|
||||
this.options.submit_btn_selector.off('click').on('click', function(event){ me._onSubmitClick(event); });
|
||||
}
|
||||
if(this.options.cancel_btn_selector !== null)
|
||||
{
|
||||
this.options.cancel_btn_selector.off('click').on('click', function(event){ me._onCancelClick(event); });
|
||||
}
|
||||
},
|
||||
// Binding buttons
|
||||
if(this.options.submit_btn_selector !== null)
|
||||
{
|
||||
this.options.submit_btn_selector.off('click').on('click', function(oEvent){ me._onSubmitClick(oEvent); });
|
||||
}
|
||||
if(this.options.cancel_btn_selector !== null)
|
||||
{
|
||||
this.options.cancel_btn_selector.off('click').on('click', function(oEvent){ me._onCancelClick(oEvent); });
|
||||
}
|
||||
},
|
||||
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('form_handler');
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
// always refresh when changing options
|
||||
_setOptions: function()
|
||||
{
|
||||
this._superApply(arguments);
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
this._super( key, value );
|
||||
},
|
||||
getCurrentValues: function()
|
||||
{
|
||||
return this.options.field_set.triggerHandler('get_current_values');
|
||||
},
|
||||
_onUpdateFields: function(event, data)
|
||||
{
|
||||
var me = this;
|
||||
var sFormPath = data.form_path;
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('form_handler');
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
// always refresh when changing options
|
||||
_setOptions: function()
|
||||
{
|
||||
this._superApply(arguments);
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
this._super( key, value );
|
||||
},
|
||||
getCurrentValues: function()
|
||||
{
|
||||
return this.options.field_set.triggerHandler('get_current_values');
|
||||
},
|
||||
_onUpdateFields: function(oEvent, oData)
|
||||
{
|
||||
var me = this;
|
||||
var sFormPath = oData.form_path;
|
||||
|
||||
// Data checks
|
||||
if(this.options.endpoint === null)
|
||||
{
|
||||
console.log('Form handler : An endpoint must be defined.');
|
||||
return false;
|
||||
}
|
||||
if(this.options.formmanager_class === null)
|
||||
{
|
||||
console.log('Form handler : Form manager class must be defined.');
|
||||
return false;
|
||||
}
|
||||
if(this.options.formmanager_data === null)
|
||||
{
|
||||
console.log('Form handler : Form manager data must be defined.');
|
||||
return false;
|
||||
}
|
||||
|
||||
this._disableFormBeforeLoading();
|
||||
$.post(
|
||||
this.options.endpoint,
|
||||
{
|
||||
operation: 'update',
|
||||
formmanager_class: this.options.formmanager_class,
|
||||
formmanager_data: JSON.stringify(this.options.formmanager_data),
|
||||
current_values: this.getCurrentValues(),
|
||||
requested_fields: data.requested_fields,
|
||||
form_path: sFormPath
|
||||
},
|
||||
function(data){
|
||||
me._onUpdateSuccess(data, sFormPath);
|
||||
}
|
||||
)
|
||||
.fail(function(data){ me._onUpdateFailure(data, sFormPath); })
|
||||
.always(function(data){ me._onUpdateAlways(data, sFormPath); });
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onSubmitClick: function(event)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onCancelClick: function(event)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateSuccess: function(data, sFormPath)
|
||||
{
|
||||
if(data.form.updated_fields !== undefined)
|
||||
{
|
||||
this.element.find('[data-form-path="'+sFormPath+'"]').trigger('update_form', {updated_fields: data.form.updated_fields});
|
||||
}
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateFailure: function(data, sFormPath)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateAlways: function(data, sFormPath)
|
||||
{
|
||||
// Check all touched AFTER ajax is complete, otherwise the renderer will redraw the field in the mean time.
|
||||
this.element.find('[data-form-path="'+sFormPath+'"]').trigger('validate');
|
||||
this._enableFormAfterLoading();
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_disableFormBeforeLoading: function()
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_enableFormAfterLoading: function()
|
||||
{
|
||||
},
|
||||
showOptions: function() // Debug helper
|
||||
{
|
||||
console.log(this.options);
|
||||
}
|
||||
});
|
||||
// Data checks
|
||||
if(this.options.endpoint === null)
|
||||
{
|
||||
console.log('Form handler : An endpoint must be defined.');
|
||||
return false;
|
||||
}
|
||||
if(this.options.formmanager_class === null)
|
||||
{
|
||||
console.log('Form handler : Form manager class must be defined.');
|
||||
return false;
|
||||
}
|
||||
if(this.options.formmanager_data === null)
|
||||
{
|
||||
console.log('Form handler : Form manager data must be defined.');
|
||||
return false;
|
||||
}
|
||||
|
||||
this._disableFormBeforeLoading();
|
||||
$.post(
|
||||
this.options.endpoint,
|
||||
{
|
||||
operation: 'update',
|
||||
formmanager_class: this.options.formmanager_class,
|
||||
formmanager_data: JSON.stringify(this.options.formmanager_data),
|
||||
current_values: this.getCurrentValues(),
|
||||
requested_fields: oData.requested_fields,
|
||||
form_path: sFormPath
|
||||
},
|
||||
function(oData){
|
||||
me._onUpdateSuccess(oData, sFormPath);
|
||||
}
|
||||
)
|
||||
.fail(function(oData){ me._onUpdateFailure(oData, sFormPath); })
|
||||
.always(function(oData){ me._onUpdateAlways(oData, sFormPath); });
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onSubmitClick: function(oEvent)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onCancelClick: function(oEvent)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateSuccess: function(oData, sFormPath)
|
||||
{
|
||||
if(oData.form.updated_fields !== undefined)
|
||||
{
|
||||
this.element.find('[data-form-path="' + sFormPath + '"]').trigger('update_form', {updated_fields: oData.form.updated_fields});
|
||||
}
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateFailure: function(oData, sFormPath)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateAlways: function(oData, sFormPath)
|
||||
{
|
||||
// Check all touched AFTER ajax is complete, otherwise the renderer will redraw the field in the mean time.
|
||||
this.element.find('[data-form-path="' + sFormPath + '"]').trigger('validate');
|
||||
this._enableFormAfterLoading();
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_disableFormBeforeLoading: function()
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_enableFormAfterLoading: function()
|
||||
{
|
||||
},
|
||||
showOptions: function() // Debug helper
|
||||
{
|
||||
console.log(this.options);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
//iTop Form field
|
||||
//iTop Subform field
|
||||
;
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'subform_field' the widget name
|
||||
$.widget( 'itop.subform_field', $.itop.form_field,
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
field_set: null
|
||||
},
|
||||
// the widget definition, where 'itop' is the namespace,
|
||||
// 'subform_field' the widget name
|
||||
$.widget( 'itop.subform_field', $.itop.form_field,
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
field_set: null
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('subform_field');
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('subform_field');
|
||||
|
||||
this._super();
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('subform_field');
|
||||
this._super();
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
_destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('subform_field');
|
||||
|
||||
this._super();
|
||||
},
|
||||
getCurrentValue: function()
|
||||
{
|
||||
return this.options.field_set.triggerHandler('get_current_values');
|
||||
},
|
||||
validate: function(event, data)
|
||||
{
|
||||
return {
|
||||
is_valid: this.options.field_set.triggerHandler('validate', data),
|
||||
error_messages: []
|
||||
}
|
||||
},
|
||||
});
|
||||
this._super();
|
||||
},
|
||||
getCurrentValue: function()
|
||||
{
|
||||
return this.options.field_set.triggerHandler('get_current_values');
|
||||
},
|
||||
validate: function(oEvent, oData)
|
||||
{
|
||||
return {
|
||||
is_valid: this.options.field_set.triggerHandler('validate', oData),
|
||||
error_messages: []
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,6 +28,6 @@ use \Combodo\iTop\Form\Field\MultipleChoicesField;
|
||||
*/
|
||||
class CheckboxField extends MultipleChoicesField
|
||||
{
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = true;
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = true;
|
||||
|
||||
}
|
||||
|
||||
@@ -30,254 +30,330 @@ use \Combodo\iTop\Form\Validator\MandatoryValidator;
|
||||
*/
|
||||
abstract class Field
|
||||
{
|
||||
const DEFAULT_LABEL = '';
|
||||
const DEFAULT_READ_ONLY = false;
|
||||
const DEFAULT_MANDATORY = false;
|
||||
const DEFAULT_VALID = true;
|
||||
const DEFAULT_LABEL = '';
|
||||
const DEFAULT_READ_ONLY = false;
|
||||
const DEFAULT_MANDATORY = false;
|
||||
const DEFAULT_VALID = true;
|
||||
|
||||
protected $sId;
|
||||
protected $sGlobalId;
|
||||
protected $sFormPath;
|
||||
protected $sLabel;
|
||||
protected $bReadOnly;
|
||||
protected $bMandatory;
|
||||
protected $aValidators;
|
||||
protected $bValid;
|
||||
protected $aErrorMessages;
|
||||
protected $currentValue;
|
||||
protected $onFinalizeCallback;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Closure $callback (Used in the $oForm->AddField($sId, ..., function() use ($oManager, $oForm, '...') { ... } ); )
|
||||
*/
|
||||
public function __construct($sId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->sGlobalId = 'field_'.$sId.uniqid();
|
||||
$this->sLabel = static::DEFAULT_LABEL;
|
||||
$this->bReadOnly = static::DEFAULT_READ_ONLY;
|
||||
$this->bMandatory = static::DEFAULT_MANDATORY;
|
||||
$this->aValidators = array();
|
||||
$this->bValid = static::DEFAULT_VALID;
|
||||
$this->aErrorMessages = array();
|
||||
$this->onFinalizeCallback = $onFinalizeCallback;
|
||||
}
|
||||
protected $sId;
|
||||
protected $sGlobalId;
|
||||
protected $sFormPath;
|
||||
protected $sLabel;
|
||||
protected $bReadOnly;
|
||||
protected $bMandatory;
|
||||
protected $aValidators;
|
||||
protected $bValid;
|
||||
protected $aErrorMessages;
|
||||
protected $currentValue;
|
||||
protected $onFinalizeCallback;
|
||||
|
||||
/**
|
||||
* Get the field id within its container form
|
||||
* @return string
|
||||
*/
|
||||
public function GetId()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
* Default constructor
|
||||
*
|
||||
* @param string $sId
|
||||
* @param Closure $onFinalizeCallback (Used in the $oForm->AddField($sId, ..., function() use ($oManager, $oForm, '...') { ... } ); )
|
||||
*/
|
||||
public function __construct($sId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->sGlobalId = 'field_' . $sId . '_' . uniqid();
|
||||
$this->sLabel = static::DEFAULT_LABEL;
|
||||
$this->bReadOnly = static::DEFAULT_READ_ONLY;
|
||||
$this->bMandatory = static::DEFAULT_MANDATORY;
|
||||
$this->aValidators = array();
|
||||
$this->bValid = static::DEFAULT_VALID;
|
||||
$this->aErrorMessages = array();
|
||||
$this->onFinalizeCallback = $onFinalizeCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a unique field id within the top level form
|
||||
* @return string
|
||||
*/
|
||||
public function GetGlobalId()
|
||||
{
|
||||
return $this->sGlobalId;
|
||||
}
|
||||
/**
|
||||
* Returns the field id within its container form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetId()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the container form
|
||||
* @return string
|
||||
*/
|
||||
public function GetFormPath()
|
||||
{
|
||||
return $this->sFormPath;
|
||||
}
|
||||
/**
|
||||
* Returns a unique field id within the top level form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetGlobalId()
|
||||
{
|
||||
return $this->sGlobalId;
|
||||
}
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
/**
|
||||
* Returns the id of the container form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetFormPath()
|
||||
{
|
||||
return $this->sFormPath;
|
||||
}
|
||||
|
||||
public function GetReadOnly()
|
||||
{
|
||||
return $this->bReadOnly;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
public function GetMandatory()
|
||||
{
|
||||
return $this->bMandatory;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetReadOnly()
|
||||
{
|
||||
return $this->bReadOnly;
|
||||
}
|
||||
|
||||
public function GetValidators()
|
||||
{
|
||||
return $this->aValidators;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetMandatory()
|
||||
{
|
||||
return $this->bMandatory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current validation state of the field (true|false).
|
||||
* It DOESN'T make the validation, see Validate() instead.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetValid()
|
||||
{
|
||||
return $this->bValid;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetValidators()
|
||||
{
|
||||
return $this->aValidators;
|
||||
}
|
||||
|
||||
public function GetErrorMessages()
|
||||
{
|
||||
return $this->aErrorMessages;
|
||||
}
|
||||
/**
|
||||
* Returns the current validation state of the field (true|false).
|
||||
* It DOESN'T make the validation, see Validate() instead.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetValid()
|
||||
{
|
||||
return $this->bValid;
|
||||
}
|
||||
|
||||
public function GetCurrentValue()
|
||||
{
|
||||
return $this->currentValue;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetErrorMessages()
|
||||
{
|
||||
return $this->aErrorMessages;
|
||||
}
|
||||
|
||||
public function SetLabel($sLabel)
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCurrentValue()
|
||||
{
|
||||
return $this->currentValue;
|
||||
}
|
||||
|
||||
public function SetReadOnly($bReadOnly)
|
||||
{
|
||||
$this->bReadOnly = $bReadOnly;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Sets the field formpath
|
||||
* Usually Called by the form when adding the field
|
||||
*
|
||||
* @param string $sFormPath
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetFormPath($sFormPath)
|
||||
{
|
||||
$this->sFormPath = $sFormPath;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetMandatory($bMandatory)
|
||||
{
|
||||
// Before changing the property, we check if it was already mandatory. If not, we had the mandatory validator
|
||||
if ($bMandatory && !$this->bMandatory)
|
||||
{
|
||||
$this->AddValidator(new MandatoryValidator());
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param type $sLabel
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetLabel($sLabel)
|
||||
{
|
||||
$this->sLabel = $sLabel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!$bMandatory)
|
||||
{
|
||||
foreach ($this->aValidators as $iKey => $oValue)
|
||||
{
|
||||
if ($oValue::Getname() === MandatoryValidator::GetName())
|
||||
{
|
||||
unset($this->aValidators[$iKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param boolean $bReadOnly
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetReadOnly($bReadOnly)
|
||||
{
|
||||
$this->bReadOnly = $bReadOnly;
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->bMandatory = $bMandatory;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Sets if the field is mandatory or not.
|
||||
* Setting the value will automatically add/remove a MandatoryValidator to the Field
|
||||
*
|
||||
* @param boolean $bMandatory
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetMandatory($bMandatory)
|
||||
{
|
||||
// Before changing the property, we check if it was already mandatory. If not, we had the mandatory validator
|
||||
if ($bMandatory && !$this->bMandatory)
|
||||
{
|
||||
$this->AddValidator(new MandatoryValidator());
|
||||
}
|
||||
|
||||
public function SetValidators($aValidators)
|
||||
{
|
||||
$this->aValidators = $aValidators;
|
||||
return $this;
|
||||
}
|
||||
if (!$bMandatory)
|
||||
{
|
||||
foreach ($this->aValidators as $iKey => $oValue)
|
||||
{
|
||||
if ($oValue::Getname() === MandatoryValidator::GetName())
|
||||
{
|
||||
unset($this->aValidators[$iKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as bValid should not be set from outside
|
||||
*
|
||||
* @param boolean $bValid
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function SetValid($bValid)
|
||||
{
|
||||
$this->bValid = $bValid;
|
||||
return $this;
|
||||
}
|
||||
$this->bMandatory = $bMandatory;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @param array $aErrorMessages
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function SetErrorMessages($aErrorMessages)
|
||||
{
|
||||
$this->aErrorMessages = $aErrorMessages;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param array $aValidators
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetValidators($aValidators)
|
||||
{
|
||||
$this->aValidators = $aValidators;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetCurrentValue($currentValue)
|
||||
{
|
||||
$this->currentValue = $currentValue;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as bValid should not be set from outside
|
||||
*
|
||||
* @param boolean $bValid
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function SetValid($bValid)
|
||||
{
|
||||
$this->bValid = $bValid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetOnFinalizeCallback(Closure $onFinalizeCallback)
|
||||
{
|
||||
$this->onFinalizeCallback = $onFinalizeCallback;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @param array $aErrorMessages
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function SetErrorMessages($aErrorMessages)
|
||||
{
|
||||
$this->aErrorMessages = $aErrorMessages;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the form when adding the field
|
||||
*/
|
||||
public function SetFormPath($sFormPath)
|
||||
{
|
||||
$this->sFormPath = $sFormPath;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param mixed $currentValue
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetCurrentValue($currentValue)
|
||||
{
|
||||
$this->currentValue = $currentValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddValidator(Validator $oValidator)
|
||||
{
|
||||
$this->aValidators[] = $oValidator;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param Closure $onFinalizeCallback
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function SetOnFinalizeCallback(Closure $onFinalizeCallback)
|
||||
{
|
||||
$this->onFinalizeCallback = $onFinalizeCallback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function RemoveValidator(Validator $oValidator)
|
||||
{
|
||||
foreach ($this->aValidators as $iKey => $oValue)
|
||||
{
|
||||
if ($oValue === $oValidator)
|
||||
{
|
||||
unset($this->aValidators[$iKey]);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param Validator $oValidator
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function AddValidator(Validator $oValidator)
|
||||
{
|
||||
$this->aValidators[] = $oValidator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be add from outside
|
||||
*
|
||||
* @param string $sErrorMessage
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function AddErrorMessage($sErrorMessage)
|
||||
{
|
||||
$this->aErrorMessages[] = $sErrorMessage;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param Validator $oValidator
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
public function RemoveValidator(Validator $oValidator)
|
||||
{
|
||||
foreach ($this->aValidators as $iKey => $oValue)
|
||||
{
|
||||
if ($oValue === $oValidator)
|
||||
{
|
||||
unset($this->aValidators[$iKey]);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function EmptyErrorMessages()
|
||||
{
|
||||
$this->aErrorMessages = array();
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be add from outside
|
||||
*
|
||||
* @param string $sErrorMessage
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function AddErrorMessage($sErrorMessage)
|
||||
{
|
||||
$this->aErrorMessages[] = $sErrorMessage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function OnCancel()
|
||||
{
|
||||
// Overload when needed
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function EmptyErrorMessages()
|
||||
{
|
||||
$this->aErrorMessages = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function OnFinalize()
|
||||
{
|
||||
if ($this->onFinalizeCallback !== null)
|
||||
{
|
||||
// Note : We MUST have a temp variable to call the Closure. otherwise it won't work when the Closure is a class member
|
||||
$callback = $this->onFinalizeCallback;
|
||||
$callback($this);
|
||||
}
|
||||
}
|
||||
public function OnCancel()
|
||||
{
|
||||
// Overload when needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validators to see if the field's current value is valid.
|
||||
* Then sets $bValid and $aErrorMessages.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function Validate();
|
||||
public function OnFinalize()
|
||||
{
|
||||
if ($this->onFinalizeCallback !== null)
|
||||
{
|
||||
// Note : We MUST have a temp variable to call the Closure. otherwise it won't work when the Closure is a class member
|
||||
$callback = $this->onFinalizeCallback;
|
||||
$callback($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validators to see if the field's current value is valid.
|
||||
* Then sets $bValid and $aErrorMessages.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function Validate();
|
||||
}
|
||||
|
||||
@@ -32,146 +32,146 @@ use \Combodo\iTop\Form\Field\Field;
|
||||
*/
|
||||
abstract class MultipleChoicesField extends Field
|
||||
{
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = false;
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = false;
|
||||
|
||||
protected $bMultipleValuesEnabled;
|
||||
protected $aChoices;
|
||||
protected $bMultipleValuesEnabled;
|
||||
protected $aChoices;
|
||||
|
||||
public function __construct($sId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
parent::__construct($sId, $onFinalizeCallback);
|
||||
$this->bMultipleValuesEnabled = static::DEFAULT_MULTIPLE_VALUES_ENABLED;
|
||||
$this->aChoices = array();
|
||||
$this->currentValue = array();
|
||||
}
|
||||
public function __construct($sId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
parent::__construct($sId, $onFinalizeCallback);
|
||||
$this->bMultipleValuesEnabled = static::DEFAULT_MULTIPLE_VALUES_ENABLED;
|
||||
$this->aChoices = array();
|
||||
$this->currentValue = array();
|
||||
}
|
||||
|
||||
public function GetCurrentValue()
|
||||
{
|
||||
$value = null;
|
||||
if (!empty($this->currentValue))
|
||||
{
|
||||
if ($this->bMultipleValuesEnabled)
|
||||
{
|
||||
$value = $this->currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
reset($this->currentValue);
|
||||
$value = current($this->currentValue);
|
||||
}
|
||||
}
|
||||
public function GetCurrentValue()
|
||||
{
|
||||
$value = null;
|
||||
if (!empty($this->currentValue))
|
||||
{
|
||||
if ($this->bMultipleValuesEnabled)
|
||||
{
|
||||
$value = $this->currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
reset($this->currentValue);
|
||||
$value = current($this->currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current value for the MultipleChoicesField.
|
||||
*
|
||||
* @param mixed $currentValue Can be either an array of values (in case of multiple values) or just a simple value
|
||||
* @return \Combodo\iTop\Form\Field\MultipleChoicesField
|
||||
*/
|
||||
public function SetCurrentValue($currentValue)
|
||||
{
|
||||
if (is_array($currentValue))
|
||||
{
|
||||
$this->currentValue = $currentValue;
|
||||
}
|
||||
elseif (is_null($currentValue))
|
||||
{
|
||||
$this->currentValue = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->currentValue = array($currentValue);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Sets the current value for the MultipleChoicesField.
|
||||
*
|
||||
* @param mixed $currentValue Can be either an array of values (in case of multiple values) or just a simple value
|
||||
* @return \Combodo\iTop\Form\Field\MultipleChoicesField
|
||||
*/
|
||||
public function SetCurrentValue($currentValue)
|
||||
{
|
||||
if (is_array($currentValue))
|
||||
{
|
||||
$this->currentValue = $currentValue;
|
||||
}
|
||||
elseif (is_null($currentValue))
|
||||
{
|
||||
$this->currentValue = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->currentValue = array($currentValue);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetMultipleValuesEnabled()
|
||||
{
|
||||
return $this->bMultipleValuesEnabled;
|
||||
}
|
||||
public function GetMultipleValuesEnabled()
|
||||
{
|
||||
return $this->bMultipleValuesEnabled;
|
||||
}
|
||||
|
||||
public function SetMultipleValuesEnabled($bMultipleValuesEnabled)
|
||||
{
|
||||
$this->bMultipleValuesEnabled = $bMultipleValuesEnabled;
|
||||
return $this;
|
||||
}
|
||||
public function SetMultipleValuesEnabled($bMultipleValuesEnabled)
|
||||
{
|
||||
$this->bMultipleValuesEnabled = $bMultipleValuesEnabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetValues($aValues)
|
||||
{
|
||||
$this->currentValue = $aValues;
|
||||
return $this;
|
||||
}
|
||||
public function SetValues($aValues)
|
||||
{
|
||||
$this->currentValue = $aValues;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddValue($value)
|
||||
{
|
||||
$this->currentValue = $value;
|
||||
return $this;
|
||||
}
|
||||
public function AddValue($value)
|
||||
{
|
||||
$this->currentValue = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function RemoveValue($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->currentValue))
|
||||
{
|
||||
unset($this->currentValue[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function RemoveValue($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->currentValue))
|
||||
{
|
||||
unset($this->currentValue[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function IsAmongValues($value)
|
||||
{
|
||||
return in_array($value, $this->currentValue);
|
||||
}
|
||||
public function IsAmongValues($value)
|
||||
{
|
||||
return in_array($value, $this->currentValue);
|
||||
}
|
||||
|
||||
public function GetChoices()
|
||||
{
|
||||
return $this->aChoices;
|
||||
}
|
||||
public function GetChoices()
|
||||
{
|
||||
return $this->aChoices;
|
||||
}
|
||||
|
||||
public function SetChoices($aChoices)
|
||||
{
|
||||
$this->aChoices = $aChoices;
|
||||
return $this;
|
||||
}
|
||||
public function SetChoices($aChoices)
|
||||
{
|
||||
$this->aChoices = $aChoices;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function AddChoice($sId, $choice = null)
|
||||
{
|
||||
if ($choice === null)
|
||||
{
|
||||
$choice = $sId;
|
||||
}
|
||||
$this->aChoices[$sId] = $choice;
|
||||
return $this;
|
||||
}
|
||||
public function AddChoice($sId, $choice = null)
|
||||
{
|
||||
if ($choice === null)
|
||||
{
|
||||
$choice = $sId;
|
||||
}
|
||||
$this->aChoices[$sId] = $choice;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function RemoveChoice($sId)
|
||||
{
|
||||
if (in_array($sId, $this->aChoices))
|
||||
{
|
||||
unset($this->aChoices[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function RemoveChoice($sId)
|
||||
{
|
||||
if (in_array($sId, $this->aChoices))
|
||||
{
|
||||
unset($this->aChoices[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function Validate()
|
||||
{
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
public function Validate()
|
||||
{
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
|
||||
foreach ($this->GetValidators() as $oValidator)
|
||||
{
|
||||
foreach ($this->currentValue as $value)
|
||||
{
|
||||
if (!preg_match($oValidator->GetRegExp(true), $value))
|
||||
{
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage($oValidator->GetErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->GetValidators() as $oValidator)
|
||||
{
|
||||
foreach ($this->currentValue as $value)
|
||||
{
|
||||
if (!preg_match($oValidator->GetRegExp(true), $value))
|
||||
{
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage($oValidator->GetErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->GetValid();
|
||||
}
|
||||
return $this->GetValid();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,6 @@ use \Combodo\iTop\Form\Field\MultipleChoicesField;
|
||||
*/
|
||||
class RadioField extends MultipleChoicesField
|
||||
{
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = false;
|
||||
const DEFAULT_MULTIPLE_VALUES_ENABLED = false;
|
||||
|
||||
}
|
||||
|
||||
@@ -29,56 +29,56 @@ use \Combodo\iTop\Form\Field\MultipleChoicesField;
|
||||
*/
|
||||
class SelectField extends MultipleChoicesField
|
||||
{
|
||||
const DEFAULT_NULL_CHOICE_LABEL = 'TOTR: - Choisir une valeur -';
|
||||
const DEFAULT_STARTS_WITH_NULL_CHOICE = true;
|
||||
const DEFAULT_NULL_CHOICE_LABEL = 'TOTR: - Choisir une valeur -';
|
||||
const DEFAULT_STARTS_WITH_NULL_CHOICE = true;
|
||||
|
||||
protected $bStartsWithNullChoice;
|
||||
protected $bStartsWithNullChoice;
|
||||
|
||||
public function __construct($sId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
parent::__construct($sId, $onFinalizeCallback);
|
||||
$this->bStartsWithNullChoice = static::DEFAULT_STARTS_WITH_NULL_CHOICE;
|
||||
}
|
||||
public function __construct($sId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
parent::__construct($sId, $onFinalizeCallback);
|
||||
$this->bStartsWithNullChoice = static::DEFAULT_STARTS_WITH_NULL_CHOICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the select starts with a dummy choice before its choices.
|
||||
* This can be useful when you want to force the user to explicitly select a choice.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetStartsWithNullChoice()
|
||||
{
|
||||
return $this->bStartsWithNullChoice;
|
||||
}
|
||||
/**
|
||||
* Returns if the select starts with a dummy choice before its choices.
|
||||
* This can be useful when you want to force the user to explicitly select a choice.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetStartsWithNullChoice()
|
||||
{
|
||||
return $this->bStartsWithNullChoice;
|
||||
}
|
||||
|
||||
public function SetStartsWithNullChoice($bStartsWithNullChoice)
|
||||
{
|
||||
$this->bStartsWithNullChoice = $bStartsWithNullChoice;
|
||||
public function SetStartsWithNullChoice($bStartsWithNullChoice)
|
||||
{
|
||||
$this->bStartsWithNullChoice = $bStartsWithNullChoice;
|
||||
|
||||
if (!array_key_exists(null, $this->aChoices))
|
||||
{
|
||||
$this->aChoices = array(null => static::DEFAULT_NULL_CHOICE_LABEL) + $this->aChoices;
|
||||
}
|
||||
if (!array_key_exists(null, $this->aChoices))
|
||||
{
|
||||
$this->aChoices = array(null => static::DEFAULT_NULL_CHOICE_LABEL) + $this->aChoices;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the choices for the fields
|
||||
* Overloads the methods for the super class in order to put a dummy choice first if necessary.
|
||||
*
|
||||
* @param array $aChoices
|
||||
* @return \Combodo\iTop\Form\Field\SelectField
|
||||
*/
|
||||
public function SetChoices($aChoices)
|
||||
{
|
||||
if ($this->bStartsWithNullChoice && !array_key_exists(null, $aChoices))
|
||||
{
|
||||
$aChoices = array(null => static::DEFAULT_NULL_CHOICE_LABEL) + $aChoices;
|
||||
}
|
||||
/**
|
||||
* Sets the choices for the fields
|
||||
* Overloads the methods for the super class in order to put a dummy choice first if necessary.
|
||||
*
|
||||
* @param array $aChoices
|
||||
* @return \Combodo\iTop\Form\Field\SelectField
|
||||
*/
|
||||
public function SetChoices($aChoices)
|
||||
{
|
||||
if ($this->bStartsWithNullChoice && !array_key_exists(null, $aChoices))
|
||||
{
|
||||
$aChoices = array(null => static::DEFAULT_NULL_CHOICE_LABEL) + $aChoices;
|
||||
}
|
||||
|
||||
parent::SetChoices($aChoices);
|
||||
return $this;
|
||||
}
|
||||
parent::SetChoices($aChoices);
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ use \Closure;
|
||||
use \Combodo\iTop\Form\Form;
|
||||
|
||||
/**
|
||||
* Description of StringField
|
||||
* Description of SubFormField
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
*/
|
||||
@@ -31,12 +31,23 @@ class SubFormField extends Field
|
||||
{
|
||||
protected $oForm;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param string $sId
|
||||
* @param string $sParentFormId
|
||||
* @param Closure $onFinalizeCallback
|
||||
*/
|
||||
public function __construct($sId, $sParentFormId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
$this->oForm = new Form($sParentFormId.'-subform_'.$sId);
|
||||
parent::__construct($sId, $onFinalizeCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
@@ -53,11 +64,19 @@ class SubFormField extends Field
|
||||
$this->oForm->Validate();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetValid()
|
||||
{
|
||||
return $this->oForm->GetValid();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetErrorMessages()
|
||||
{
|
||||
$aRet = array();
|
||||
@@ -68,13 +87,23 @@ class SubFormField extends Field
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCurrentValue()
|
||||
{
|
||||
return $this->oForm->GetCurrentValues();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $value
|
||||
* @return \Combodo\iTop\Form\Field\SubFormField
|
||||
*/
|
||||
public function SetCurrentValue($value)
|
||||
{
|
||||
return $this->oForm->SetCurrentValues($value);
|
||||
$this->oForm->SetCurrentValues($value);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,5 +28,5 @@ use \Combodo\iTop\Form\Field\TextField;
|
||||
*/
|
||||
class TextAreaField extends TextField
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -29,26 +29,26 @@ use \Combodo\iTop\Form\Field\Field;
|
||||
abstract class TextField extends Field
|
||||
{
|
||||
|
||||
/**
|
||||
* Checks the validators to see if the field's current value is valid.
|
||||
* Then sets $bValid and $aErrorMessages.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function Validate()
|
||||
{
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
foreach ($this->GetValidators() as $oValidator)
|
||||
{
|
||||
if (!preg_match($oValidator->GetRegExp(true), $this->GetCurrentValue()))
|
||||
{
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage($oValidator->GetErrorMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks the validators to see if the field's current value is valid.
|
||||
* Then sets $bValid and $aErrorMessages.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function Validate()
|
||||
{
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
foreach ($this->GetValidators() as $oValidator)
|
||||
{
|
||||
if (!preg_match($oValidator->GetRegExp(true), $this->GetCurrentValue()))
|
||||
{
|
||||
$this->SetValid(false);
|
||||
$this->AddErrorMessage($oValidator->GetErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->GetValid();
|
||||
}
|
||||
return $this->GetValid();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,268 +30,343 @@ use \Combodo\iTop\Form\Field\Field;
|
||||
*/
|
||||
class Form
|
||||
{
|
||||
protected $sId;
|
||||
protected $aFields;
|
||||
protected $aDependencies;
|
||||
protected $bValid;
|
||||
protected $aErrorMessages;
|
||||
protected $sId;
|
||||
protected $aFields;
|
||||
protected $aDependencies;
|
||||
protected $bValid;
|
||||
protected $aErrorMessages;
|
||||
|
||||
public function __construct($sId)
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->aFields = array();
|
||||
$this->aDependencies = array();
|
||||
$this->bValid = true;
|
||||
$this->aErrorMessages = array();
|
||||
}
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param string $sId
|
||||
*/
|
||||
public function __construct($sId)
|
||||
{
|
||||
$this->sId = $sId;
|
||||
$this->aFields = array();
|
||||
$this->aDependencies = array();
|
||||
$this->bValid = true;
|
||||
$this->aErrorMessages = array();
|
||||
}
|
||||
|
||||
public function GetId()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetId()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
public function GetFields()
|
||||
{
|
||||
return $this->aFields;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetFields()
|
||||
{
|
||||
return $this->aFields;
|
||||
}
|
||||
|
||||
public function GetDependencies()
|
||||
{
|
||||
return $this->aDependencies;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetDependencies()
|
||||
{
|
||||
return $this->aDependencies;
|
||||
}
|
||||
|
||||
public function GetCurrentValues()
|
||||
{
|
||||
$aValues = array();
|
||||
foreach ($this->aFields as $sId => $oField)
|
||||
{
|
||||
$aValues[$sId] = $oField->GetCurrentValue();
|
||||
}
|
||||
return $aValues;
|
||||
}
|
||||
/**
|
||||
* Returns a hash array of "Field id" => "Field value"
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCurrentValues()
|
||||
{
|
||||
$aValues = array();
|
||||
foreach ($this->aFields as $sId => $oField)
|
||||
{
|
||||
$aValues[$sId] = $oField->GetCurrentValue();
|
||||
}
|
||||
return $aValues;
|
||||
}
|
||||
|
||||
public function SetCurrentValues($aValues)
|
||||
{
|
||||
foreach ($aValues as $sId => $value)
|
||||
{
|
||||
$oField = $this->GetField($sId);
|
||||
$oField->SetCurrentValue($value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param array $aValues Must be a hash array of "Field id" => "Field value"
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function SetCurrentValues($aValues)
|
||||
{
|
||||
foreach ($aValues as $sId => $value)
|
||||
{
|
||||
$oField = $this->GetField($sId);
|
||||
$oField->SetCurrentValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current validation state of the form (true|false).
|
||||
* It DOESN'T make the validation, see Validate() instead.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetValid()
|
||||
{
|
||||
return $this->bValid;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as bValid should not be set from outside
|
||||
*
|
||||
* @param boolean $bValid
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function SetValid($bValid)
|
||||
{
|
||||
$this->bValid = $bValid;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Returns the current validation state of the form (true|false).
|
||||
* It DOESN'T make the validation, see Validate() instead.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function GetValid()
|
||||
{
|
||||
return $this->bValid;
|
||||
}
|
||||
|
||||
public function GetErrorMessages()
|
||||
{
|
||||
return $this->aErrorMessages;
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as bValid should not be set from outside
|
||||
*
|
||||
* @param boolean $bValid
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function SetValid($bValid)
|
||||
{
|
||||
$this->bValid = $bValid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @param array $aErrorMessages
|
||||
* @param string $sFieldId
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function SetErrorMessages($aErrorMessages, $sFieldId = null)
|
||||
{
|
||||
if ($sFieldId === null)
|
||||
{
|
||||
$this->aErrorMessages = $aErrorMessages;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aErrorMessages[$sFieldId] = $aErrorMessages;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetErrorMessages()
|
||||
{
|
||||
return $this->aErrorMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* If $sFieldId is not set, the $sErrorMessage will be added to the general form messages
|
||||
*
|
||||
* Note : Function is protected as aErrorMessages should not be add from outside
|
||||
*
|
||||
* @param string $sErrorMessage
|
||||
* @param string $sFieldId
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function AddErrorMessage($sErrorMessage, $sFieldId = '_main')
|
||||
{
|
||||
if (!isset($this->aErrorMessages[$sFieldId]))
|
||||
{
|
||||
$this->aErrorMessages[$sFieldId] = array();
|
||||
}
|
||||
$this->aErrorMessages[$sFieldId][] = $sErrorMessage;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @param array $aErrorMessages
|
||||
* @param string $sFieldId
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function SetErrorMessages($aErrorMessages, $sFieldId = null)
|
||||
{
|
||||
if ($sFieldId === null)
|
||||
{
|
||||
$this->aErrorMessages = $aErrorMessages;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->aErrorMessages[$sFieldId] = $aErrorMessages;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function EmptyErrorMessages()
|
||||
{
|
||||
$this->aErrorMessages = array();
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* If $sFieldId is not set, the $sErrorMessage will be added to the general form messages
|
||||
*
|
||||
* Note : Function is protected as aErrorMessages should not be add from outside
|
||||
*
|
||||
* @param string $sErrorMessage
|
||||
* @param string $sFieldId
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function AddErrorMessage($sErrorMessage, $sFieldId = '_main')
|
||||
{
|
||||
if (!isset($this->aErrorMessages[$sFieldId]))
|
||||
{
|
||||
$this->aErrorMessages[$sFieldId] = array();
|
||||
}
|
||||
$this->aErrorMessages[$sFieldId][] = $sErrorMessage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetField($sId)
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aFields))
|
||||
{
|
||||
throw new Exception('Field with ID "' . $sId . '" was not found in the Form.');
|
||||
}
|
||||
return $this->aFields[$sId];
|
||||
}
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
protected function EmptyErrorMessages()
|
||||
{
|
||||
$this->aErrorMessages = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function HasField($sId)
|
||||
{
|
||||
return array_key_exists($sId, $this->aFields);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sId
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetField($sId)
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aFields))
|
||||
{
|
||||
throw new Exception('Field with ID "' . $sId . '" was not found in the Form.');
|
||||
}
|
||||
return $this->aFields[$sId];
|
||||
}
|
||||
|
||||
public function AddField(Field $oField, $aDependsOnIds = array())
|
||||
{
|
||||
$oField->SetFormPath($this->sId);
|
||||
$this->aFields[$oField->GetId()] = $oField;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sId
|
||||
* @return boolean
|
||||
*/
|
||||
public function HasField($sId)
|
||||
{
|
||||
return array_key_exists($sId, $this->aFields);
|
||||
}
|
||||
|
||||
public function RemoveField($sId)
|
||||
{
|
||||
if (array_key_exists($sId, $this->aFields))
|
||||
{
|
||||
unset($this->aFields[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
* @param array $aDependsOnIds
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function AddField(Field $oField, $aDependsOnIds = array())
|
||||
{
|
||||
$oField->SetFormPath($this->sId);
|
||||
$this->aFields[$oField->GetId()] = $oField;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a array (list) of the fields ordered by their dependencies.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetOrderedFields()
|
||||
{
|
||||
// TODO : Do this so it flatten the array
|
||||
return $this->aFields;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sId
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function RemoveField($sId)
|
||||
{
|
||||
if (array_key_exists($sId, $this->aFields))
|
||||
{
|
||||
unset($this->aFields[$sId]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of field ids the $sFieldId depends on.
|
||||
*
|
||||
* @param string $sFieldId
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetFieldDependencies($sFieldId)
|
||||
{
|
||||
if (!array_key_exists($sFieldId, $this->aDependencies))
|
||||
{
|
||||
throw new Exception('Field with ID "' . $sFieldId . '" had no dependancies declared in the Form.');
|
||||
}
|
||||
return $this->aDependencies[$sFieldId];
|
||||
}
|
||||
/**
|
||||
* Returns a array (list) of the fields ordered by their dependencies.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetOrderedFields()
|
||||
{
|
||||
// TODO : Do this so it flatten the array
|
||||
return $this->aFields;
|
||||
}
|
||||
|
||||
public function AddFieldDependencies($sFieldId, array $aDependsOnIds)
|
||||
{
|
||||
foreach ($aDependsOnIds as $sDependsOnId)
|
||||
{
|
||||
$this->AddFieldDependency($sFieldId, $sDependsOnId);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Returns an array of field ids the $sFieldId depends on.
|
||||
*
|
||||
* @param string $sFieldId
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetFieldDependencies($sFieldId)
|
||||
{
|
||||
if (!array_key_exists($sFieldId, $this->aDependencies))
|
||||
{
|
||||
throw new Exception('Field with ID "' . $sFieldId . '" had no dependancies declared in the Form.');
|
||||
}
|
||||
return $this->aDependencies[$sFieldId];
|
||||
}
|
||||
|
||||
public function AddFieldDependency($sFieldId, $sDependsOnId)
|
||||
{
|
||||
if (!array_key_exists($sFieldId, $this->aDependencies))
|
||||
{
|
||||
$this->aDependencies[$sFieldId] = array();
|
||||
}
|
||||
$this->aDependencies[$sFieldId][] = $sDependsOnId;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sFieldId
|
||||
* @param array $aDependsOnIds
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function AddFieldDependencies($sFieldId, array $aDependsOnIds)
|
||||
{
|
||||
foreach ($aDependsOnIds as $sDependsOnId)
|
||||
{
|
||||
$this->AddFieldDependency($sFieldId, $sDependsOnId);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash array of the fields impacts on other fields. Key being the field that impacts the fields stored in the value as a regular array
|
||||
* (It kind of reversed the dependencies array)
|
||||
*
|
||||
* eg :
|
||||
* - 'service' => array('subservice', 'template')
|
||||
* - 'subservice' => array()
|
||||
* - ...
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetFieldsImpacts()
|
||||
{
|
||||
$aRes = array();
|
||||
/**
|
||||
*
|
||||
* @param string $sFieldId
|
||||
* @param string $sDependsOnId
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function AddFieldDependency($sFieldId, $sDependsOnId)
|
||||
{
|
||||
if (!array_key_exists($sFieldId, $this->aDependencies))
|
||||
{
|
||||
$this->aDependencies[$sFieldId] = array();
|
||||
}
|
||||
$this->aDependencies[$sFieldId][] = $sDependsOnId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach ($this->aDependencies as $sImpactedFieldId => $aDependentFieldsIds)
|
||||
{
|
||||
foreach ($aDependentFieldsIds as $sDependentFieldId)
|
||||
{
|
||||
if (!array_key_exists($sDependentFieldId, $aRes))
|
||||
{
|
||||
$aRes[$sDependentFieldId] = array();
|
||||
}
|
||||
$aRes[$sDependentFieldId][] = $sImpactedFieldId;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns a hash array of the fields impacts on other fields. Key being the field that impacts the fields stored in the value as a regular array
|
||||
* (It kind of reversed the dependencies array)
|
||||
*
|
||||
* eg :
|
||||
* - 'service' => array('subservice', 'template')
|
||||
* - 'subservice' => array()
|
||||
* - ...
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetFieldsImpacts()
|
||||
{
|
||||
$aRes = array();
|
||||
|
||||
return $aRes;
|
||||
}
|
||||
foreach ($this->aDependencies as $sImpactedFieldId => $aDependentFieldsIds)
|
||||
{
|
||||
foreach ($aDependentFieldsIds as $sDependentFieldId)
|
||||
{
|
||||
if (!array_key_exists($sDependentFieldId, $aRes))
|
||||
{
|
||||
$aRes[$sDependentFieldId] = array();
|
||||
}
|
||||
$aRes[$sDependentFieldId][] = $sImpactedFieldId;
|
||||
}
|
||||
}
|
||||
|
||||
public function Finalize()
|
||||
{
|
||||
//TODO : Call GetOrderedFields
|
||||
// Must call OnFinalize on each fields, regarding the dependencies order
|
||||
// On a SubFormField, will call its own Finalize
|
||||
foreach ($this->aFields as $sId => $oField)
|
||||
{
|
||||
$oField->OnFinalize();
|
||||
}
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function Validate()
|
||||
{
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
|
||||
foreach ($this->aFields as $oField)
|
||||
{
|
||||
if (!$oField->Validate())
|
||||
{
|
||||
$this->SetValid(false);
|
||||
foreach ($oField->GetErrorMessages() as $sErrorMessage)
|
||||
{
|
||||
$this->AddErrorMessage(Dict::S($sErrorMessage), $oField->Getid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->GetValid();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function Finalize()
|
||||
{
|
||||
//TODO : Call GetOrderedFields
|
||||
// Must call OnFinalize on each fields, regarding the dependencies order
|
||||
// On a SubFormField, will call its own Finalize
|
||||
foreach ($this->aFields as $sId => $oField)
|
||||
{
|
||||
$oField->OnFinalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the form and return if it's valid or not
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function Validate()
|
||||
{
|
||||
$this->SetValid(true);
|
||||
$this->EmptyErrorMessages();
|
||||
|
||||
foreach ($this->aFields as $oField)
|
||||
{
|
||||
if (!$oField->Validate())
|
||||
{
|
||||
$this->SetValid(false);
|
||||
foreach ($oField->GetErrorMessages() as $sErrorMessage)
|
||||
{
|
||||
$this->AddErrorMessage(Dict::S($sErrorMessage), $oField->Getid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->GetValid();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,72 +29,111 @@ use \Combodo\iTop\Renderer\FormRenderer;
|
||||
*/
|
||||
abstract class FormManager
|
||||
{
|
||||
protected $oForm;
|
||||
protected $oRenderer;
|
||||
|
||||
static function FromJSON($sJson)
|
||||
{
|
||||
// Overload in child class when needed
|
||||
$aJson = json_decode($sJson, true);
|
||||
|
||||
$oFormManager = new static();
|
||||
|
||||
$sFormRendererClass = $aJson['formrenderer_class'];
|
||||
$oFormRenderer = new $sFormRendererClass();
|
||||
$oFormRenderer->SetEndpoint($aJson['formrenderer_endpoint']);
|
||||
$oFormManager->SetRenderer($oFormRenderer);
|
||||
|
||||
return $oFormManager;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Overload in child class when needed
|
||||
}
|
||||
protected $oForm;
|
||||
protected $oRenderer;
|
||||
|
||||
/**
|
||||
* @return Form
|
||||
*/
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
}
|
||||
* Creates an instance of \Combodo\iTop\Form\FormManager from JSON data that must contain at least :
|
||||
* - formrenderer_class : The class of the FormRenderer to use in the FormManager
|
||||
* - formrenderer_endpoint : The endpoint of the renderer
|
||||
*
|
||||
* @param string $sJson
|
||||
* @return \Combodo\iTop\Form\FormManager
|
||||
*/
|
||||
static function FromJSON($sJson)
|
||||
{
|
||||
// Overload in child class when needed
|
||||
$aJson = json_decode($sJson, true);
|
||||
|
||||
/**
|
||||
* @return FormRenderer
|
||||
*/
|
||||
public function GetRenderer()
|
||||
{
|
||||
return $this->oRenderer;
|
||||
}
|
||||
$oFormManager = new static();
|
||||
|
||||
public function SetRenderer(FormRenderer $oRenderer)
|
||||
{
|
||||
$this->oRenderer = $oRenderer;
|
||||
return $this;
|
||||
}
|
||||
$sFormRendererClass = $aJson['formrenderer_class'];
|
||||
$oFormRenderer = new $sFormRendererClass();
|
||||
$oFormRenderer->SetEndpoint($aJson['formrenderer_endpoint']);
|
||||
$oFormManager->SetRenderer($oFormRenderer);
|
||||
|
||||
public function GetClass()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
return $oFormManager;
|
||||
}
|
||||
|
||||
public function ToJSON()
|
||||
{
|
||||
// Overload in child class when needed
|
||||
return array(
|
||||
'id' => $this->oForm->GetId(),
|
||||
'formmanager_class' => $this->GetClass(),
|
||||
'formrenderer_class' => get_class($this->GetRenderer()),
|
||||
'formrenderer_endpoint' => $this->GetRenderer()->GetEndpoint()
|
||||
);
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
// Overload in child class when needed
|
||||
}
|
||||
|
||||
abstract public function Build();
|
||||
/**
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
}
|
||||
|
||||
abstract public function OnUpdate($aArgs = null);
|
||||
/**
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Form $oForm
|
||||
* @return \Combodo\iTop\Form\FormManager
|
||||
*/
|
||||
public function SetForm(Form $oForm)
|
||||
{
|
||||
$this->oForm = $oForm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract public function OnSubmit($aArgs = null);
|
||||
/**
|
||||
*
|
||||
* @return \Combodo\iTop\Renderer\FormRenderer
|
||||
*/
|
||||
public function GetRenderer()
|
||||
{
|
||||
return $this->oRenderer;
|
||||
}
|
||||
|
||||
abstract public function OnCancel($aArgs = null);
|
||||
/**
|
||||
*
|
||||
* @param \Combodo\iTop\Renderer\FormRenderer $oRenderer
|
||||
* @return \Combodo\iTop\Form\FormManager
|
||||
*/
|
||||
public function SetRenderer(FormRenderer $oRenderer)
|
||||
{
|
||||
$this->oRenderer = $oRenderer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetClass()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JSON string from the current object including :
|
||||
* - id : Id of the current Form
|
||||
* - formmanager_class
|
||||
* - formrenderer_class
|
||||
* - formrenderer_endpoint
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ToJSON()
|
||||
{
|
||||
// Overload in child class when needed
|
||||
return array(
|
||||
'id' => $this->oForm->GetId(),
|
||||
'formmanager_class' => $this->GetClass(),
|
||||
'formrenderer_class' => get_class($this->GetRenderer()),
|
||||
'formrenderer_endpoint' => $this->GetRenderer()->GetEndpoint()
|
||||
);
|
||||
}
|
||||
|
||||
abstract public function Build();
|
||||
|
||||
abstract public function OnUpdate($aArgs = null);
|
||||
|
||||
abstract public function OnSubmit($aArgs = null);
|
||||
|
||||
abstract public function OnCancel($aArgs = null);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ use \Combodo\iTop\Form\Validator\Validator;
|
||||
*/
|
||||
class IntegerValidator extends Validator
|
||||
{
|
||||
const VALIDATOR_NAME = 'integer';
|
||||
const DEFAULT_REGEXP = '^[0-9]+$';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST NOT BE AN INTEGER MESSAGE';
|
||||
const VALIDATOR_NAME = 'integer';
|
||||
const DEFAULT_REGEXP = '^[0-9]+$';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST NOT BE AN INTEGER MESSAGE';
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ use \Combodo\iTop\Form\Validator\Validator;
|
||||
*/
|
||||
class MandatoryValidator extends Validator
|
||||
{
|
||||
const VALIDATOR_NAME = 'mandatory';
|
||||
const DEFAULT_REGEXP = '.*\S.*';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MANDATORY MESSAGE';
|
||||
const VALIDATOR_NAME = 'mandatory';
|
||||
const DEFAULT_REGEXP = '.*\S.*';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MANDATORY MESSAGE';
|
||||
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ use \Combodo\iTop\Form\Validator\Validator;
|
||||
*/
|
||||
class NotEmptyExtKeyValidator extends Validator
|
||||
{
|
||||
const VALIDATOR_NAME = 'notemptyextkey';
|
||||
const DEFAULT_REGEXP = '^[1-9]+$';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST SELECT ONE';
|
||||
const VALIDATOR_NAME = 'notemptyextkey';
|
||||
const DEFAULT_REGEXP = '^[1-9]+$';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST SELECT ONE';
|
||||
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ use \Combodo\iTop\Form\Validator\Validator;
|
||||
*/
|
||||
class NotEmptyValidator extends Validator
|
||||
{
|
||||
const VALIDATOR_NAME = 'notempty';
|
||||
const DEFAULT_REGEXP = '.*\S.*';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST NOT BE EMPTY MESSAGE';
|
||||
const VALIDATOR_NAME = 'notempty';
|
||||
const DEFAULT_REGEXP = '.*\S.*';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST NOT BE EMPTY MESSAGE';
|
||||
|
||||
}
|
||||
|
||||
@@ -26,83 +26,83 @@ namespace Combodo\iTop\Form\Validator;
|
||||
*/
|
||||
class Validator
|
||||
{
|
||||
const VALIDATOR_NAME = 'expression';
|
||||
const DEFAULT_REGEXP = '';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: Core:Validator:Default';
|
||||
const VALIDATOR_NAME = 'expression';
|
||||
const DEFAULT_REGEXP = '';
|
||||
const DEFAULT_ERROR_MESSAGE = 'TOTR: Core:Validator:Default';
|
||||
|
||||
protected $sRegExp;
|
||||
protected $sErrorMessage;
|
||||
protected $sRegExp;
|
||||
protected $sErrorMessage;
|
||||
|
||||
public static function GetName()
|
||||
{
|
||||
return static::VALIDATOR_NAME;
|
||||
}
|
||||
public static function GetName()
|
||||
{
|
||||
return static::VALIDATOR_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Closure $callback (Used in the $oForm->AddField($sId, ..., function() use ($oManager, $oForm, '...') { ... } ); )
|
||||
*/
|
||||
public function __construct($sRegExp = null, $sErrorMessage = null)
|
||||
{
|
||||
$this->sRegExp = ($sRegExp === null) ? static::DEFAULT_REGEXP : $sRegExp;
|
||||
$this->sErrorMessage = ($sErrorMessage === null) ? static::DEFAULT_ERROR_MESSAGE : $sErrorMessage;
|
||||
$this->ComputeConstraints();
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param Closure $callback (Used in the $oForm->AddField($sId, ..., function() use ($oManager, $oForm, '...') { ... } ); )
|
||||
*/
|
||||
public function __construct($sRegExp = null, $sErrorMessage = null)
|
||||
{
|
||||
$this->sRegExp = ($sRegExp === null) ? static::DEFAULT_REGEXP : $sRegExp;
|
||||
$this->sErrorMessage = ($sErrorMessage === null) ? static::DEFAULT_ERROR_MESSAGE : $sErrorMessage;
|
||||
$this->ComputeConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the regular expression of the validator.
|
||||
*
|
||||
* @param boolean $bWithSlashes If true, surrounds $sRegExp with '/'. Used with preg_match & co
|
||||
* @return string
|
||||
*/
|
||||
public function GetRegExp($bWithSlashes = false)
|
||||
{
|
||||
return ($bWithSlashes) ? '/' . $this->sRegExp . '/' : $this->sRegExp;
|
||||
}
|
||||
/**
|
||||
* Returns the regular expression of the validator.
|
||||
*
|
||||
* @param boolean $bWithSlashes If true, surrounds $sRegExp with '/'. Used with preg_match & co
|
||||
* @return string
|
||||
*/
|
||||
public function GetRegExp($bWithSlashes = false)
|
||||
{
|
||||
return ($bWithSlashes) ? '/' . $this->sRegExp . '/' : $this->sRegExp;
|
||||
}
|
||||
|
||||
public function GetErrorMessage()
|
||||
{
|
||||
return $this->sErrorMessage;
|
||||
}
|
||||
public function GetErrorMessage()
|
||||
{
|
||||
return $this->sErrorMessage;
|
||||
}
|
||||
|
||||
public function SetRegExp($sRegExp)
|
||||
{
|
||||
$this->sRegExp = $sRegExp;
|
||||
$this->ComputeConstraints();
|
||||
return $this;
|
||||
}
|
||||
public function SetRegExp($sRegExp)
|
||||
{
|
||||
$this->sRegExp = $sRegExp;
|
||||
$this->ComputeConstraints();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetErrorMessage($sErrorMessage)
|
||||
{
|
||||
$this->sErrorMessage = $sErrorMessage;
|
||||
$this->ComputeConstraints();
|
||||
return $this;
|
||||
}
|
||||
public function SetErrorMessage($sErrorMessage)
|
||||
{
|
||||
$this->sErrorMessage = $sErrorMessage;
|
||||
$this->ComputeConstraints();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the regular expression and error message when changing constraints on the validator.
|
||||
* Should be called in the validator's setters.
|
||||
*/
|
||||
public function ComputeConstraints()
|
||||
{
|
||||
$this->ComputeRegularExpression();
|
||||
$this->ComputeErrorMessage();
|
||||
}
|
||||
/**
|
||||
* Computes the regular expression and error message when changing constraints on the validator.
|
||||
* Should be called in the validator's setters.
|
||||
*/
|
||||
public function ComputeConstraints()
|
||||
{
|
||||
$this->ComputeRegularExpression();
|
||||
$this->ComputeErrorMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the regular expression when changing constraints on the validator.
|
||||
*/
|
||||
public function ComputeRegularExpression()
|
||||
{
|
||||
// Overload when necessary
|
||||
}
|
||||
/**
|
||||
* Computes the regular expression when changing constraints on the validator.
|
||||
*/
|
||||
public function ComputeRegularExpression()
|
||||
{
|
||||
// Overload when necessary
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the error message when changing constraints on the validator.
|
||||
*/
|
||||
public function ComputeErrorMessage()
|
||||
{
|
||||
// Overload when necessary
|
||||
}
|
||||
/**
|
||||
* Computes the error message when changing constraints on the validator.
|
||||
*/
|
||||
public function ComputeErrorMessage()
|
||||
{
|
||||
// Overload when necessary
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,16 +29,22 @@ use \Combodo\iTop\Form\Form;
|
||||
*/
|
||||
class BsFormRenderer extends FormRenderer
|
||||
{
|
||||
const DEFAULT_RENDERER_NAMESPACE = 'Combodo\\iTop\\Renderer\\Bootstrap\\FieldRenderer\\';
|
||||
const DEFAULT_RENDERER_NAMESPACE = 'Combodo\\iTop\\Renderer\\Bootstrap\\FieldRenderer\\';
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Form $oForm
|
||||
*/
|
||||
public function __construct(Form $oForm = null)
|
||||
{
|
||||
parent::__construct($oForm);
|
||||
$this->AddSupportedField('HiddenField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('StringField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('TextAreaField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('SelectField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('RadioField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('CheckboxField', 'BsSimpleFieldRenderer');
|
||||
}
|
||||
|
||||
public function __construct(Form $oForm = null)
|
||||
{
|
||||
parent::__construct($oForm);
|
||||
$this->AddSupportedField('HiddenField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('StringField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('TextAreaField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('SelectField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('RadioField', 'BsSimpleFieldRenderer');
|
||||
$this->AddSupportedField('CheckboxField', 'BsSimpleFieldRenderer');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,201 +31,209 @@ use \Combodo\iTop\Renderer\RenderingOutput;
|
||||
class BsSimpleFieldRenderer extends FieldRenderer
|
||||
{
|
||||
|
||||
public function Render()
|
||||
{
|
||||
$oOutput = new RenderingOutput();
|
||||
$sFieldClass = get_class($this->oField);
|
||||
$sFieldId = 'field_' . spl_object_hash($this->oField);
|
||||
$sFieldMandatoryClass = ($this->oField->GetMandatory()) ? 'form_mandatory' : '';
|
||||
/**
|
||||
* Returns a RenderingOutput for the FieldRenderer's Field
|
||||
*
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function Render()
|
||||
{
|
||||
$oOutput = new RenderingOutput();
|
||||
$sFieldClass = get_class($this->oField);
|
||||
$sFieldMandatoryClass = ($this->oField->GetMandatory()) ? 'form_mandatory' : '';
|
||||
|
||||
// TODO : Shouldn't we have a field type so we don't have to maintain FQN classname ?
|
||||
// Rendering field in edition mode
|
||||
if (!$this->oField->GetReadOnly())
|
||||
{
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $sFieldId . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<input type="text" id="' . $sFieldId . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '" class="form-control" />');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
// TODO : Shouldn't we have a field type so we don't have to maintain FQN classname ?
|
||||
// Rendering field in edition mode
|
||||
if (!$this->oField->GetReadOnly())
|
||||
{
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '" class="form-control" />');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $sFieldId . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<textarea id="' . $sFieldId . '" name="' . $this->oField->GetId() . '" class="form-control" rows="8">' . $this->oField->GetCurrentValue() . '</textarea>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<textarea id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" class="form-control" rows="8">' . $this->oField->GetCurrentValue() . '</textarea>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $sFieldId . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<select id="' . $sFieldId . '" name="' . $this->oField->GetId() . '" ' . ( ($this->oField->GetMultipleValuesEnabled()) ? 'multiple' : '' ) . ' class="form-control">');
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel)
|
||||
{
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sSelectedAtt = ($this->oField->GetCurrentValue() == $sChoice) ? 'selected' : '';
|
||||
$oOutput->AddHtml('<option value="' . $sChoice . '" ' . $sSelectedAtt . ' >' . $sLabel . '</option>');
|
||||
}
|
||||
$oOutput->AddHtml('</select>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<select id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" ' . ( ($this->oField->GetMultipleValuesEnabled()) ? 'multiple' : '' ) . ' class="form-control">');
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel)
|
||||
{
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sSelectedAtt = ($this->oField->GetCurrentValue() == $sChoice) ? 'selected' : '';
|
||||
$oOutput->AddHtml('<option value="' . $sChoice . '" ' . $sSelectedAtt . ' >' . $sLabel . '</option>');
|
||||
}
|
||||
$oOutput->AddHtml('</select>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$sFieldType = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\RadioField') ? 'radio' : 'checkbox';
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$sFieldType = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\RadioField') ? 'radio' : 'checkbox';
|
||||
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '" id="' . $sFieldId . '">');
|
||||
$oOutput->AddHtml('<div class="form-group ' . $sFieldMandatoryClass . '" id="' . $this->oField->GetGlobalId() . '">');
|
||||
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<div><label class="control-label">' . $this->oField->GetLabel() . '</label></div>');
|
||||
}
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<div><label class="control-label">' . $this->oField->GetLabel() . '</label></div>');
|
||||
}
|
||||
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<div class="btn-group" data-toggle="buttons">');
|
||||
$i = 0;
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel)
|
||||
{
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sCheckedAtt = ($this->oField->IsAmongValues($sChoice)) ? 'checked' : '';
|
||||
$sCheckedClass = ($this->oField->IsAmongValues($sChoice)) ? 'active' : '';
|
||||
$oOutput->AddHtml('<label class="btn btn-default ' . $sCheckedClass . '"><input type="' . $sFieldType . '" name="' . $this->oField->GetId() . '" id="' . $this->oField->GetId() . $i . '" value="' . $sChoice . '" ' . $sCheckedAtt . ' />' . $sLabel . '</label>');
|
||||
$i++;
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
$oOutput->AddHtml('<div class="btn-group" data-toggle="buttons">');
|
||||
$i = 0;
|
||||
foreach ($this->oField->GetChoices() as $sChoice => $sLabel)
|
||||
{
|
||||
// Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int)
|
||||
$sCheckedAtt = ($this->oField->IsAmongValues($sChoice)) ? 'checked' : '';
|
||||
$sCheckedClass = ($this->oField->IsAmongValues($sChoice)) ? 'active' : '';
|
||||
$oOutput->AddHtml('<label class="btn btn-default ' . $sCheckedClass . '"><input type="' . $sFieldType . '" name="' . $this->oField->GetId() . '" id="' . $this->oField->GetId() . $i . '" value="' . $sChoice . '" ' . $sCheckedAtt . ' />' . $sLabel . '</label>');
|
||||
$i++;
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $sFieldId . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '"/>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... and in read-only mode
|
||||
else
|
||||
{
|
||||
// ... specific rendering for fields with mulltiple values
|
||||
if (($this->oField instanceof Combodo\iTop\Form\Field\MultipleChoicesField) && ($this->oField->GetMultipleValuesEnabled()))
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
// ... clasic rendering for fields with only one value
|
||||
else
|
||||
{
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $sFieldId . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="form-control-static">' . $this->oField->GetCurrentValue() . '</div>');
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $sFieldId . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '" class="form-control" />');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '"/>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... and in read-only mode
|
||||
else
|
||||
{
|
||||
// ... specific rendering for fields with mulltiple values
|
||||
if (($this->oField instanceof Combodo\iTop\Form\Field\MultipleChoicesField) && ($this->oField->GetMultipleValuesEnabled()))
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
// ... clasic rendering for fields with only one value
|
||||
else
|
||||
{
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="form-control-static">' . $this->oField->GetCurrentValue() . '</div>');
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '" class="form-control" />');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField': // TODO : This should be check for external key, as we would display it differently
|
||||
$aFieldChoices = $this->oField->GetChoices();
|
||||
$sFieldValue = (isset($aFieldChoices[$this->oField->GetCurrentValue()])) ? $aFieldChoices[$this->oField->GetCurrentValue()] : Dict::S('UI:UndefinedObject');
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField': // TODO : This should be check for external key, as we would display it differently
|
||||
$aFieldChoices = $this->oField->GetChoices();
|
||||
$sFieldValue = (isset($aFieldChoices[$this->oField->GetCurrentValue()])) ? $aFieldChoices[$this->oField->GetCurrentValue()] : Dict::S('UI:UndefinedObject');
|
||||
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $sFieldId . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="form-control-static">' . $sFieldValue . '</div>');
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $sFieldId . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '" class="form-control" />');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$oOutput->AddHtml('<div class="form-group">');
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<div class="form-control-static">' . $sFieldValue . '</div>');
|
||||
$oOutput->AddHtml('<input type="hidden" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="' . $this->oField->GetCurrentValue() . '" class="form-control" />');
|
||||
$oOutput->AddHtml('</div>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JS FieldChange trigger (:input are not always at the same depth)
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#$sFieldId").off("change").on("change", function(){
|
||||
$(this).closest(".form_handler").trigger("field_change", {
|
||||
id: $(this).attr("id"),
|
||||
name: $(this).attr("name"),
|
||||
value: $(this).val()
|
||||
});
|
||||
});
|
||||
// JS FieldChange trigger (:input are not always at the same depth)
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#{$this->oField->GetGlobalId()}").off("change keyup").on("change keyup", function(){
|
||||
var me = this;
|
||||
|
||||
$(this).closest(".field_set").trigger("field_change", {
|
||||
id: $(me).attr("id"),
|
||||
name: $(me).closest(".form_field").attr("data-field-id"),
|
||||
value: $(me).val()
|
||||
});
|
||||
});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#$sFieldId input").off("change").on("change", function(){
|
||||
$(this).closest(".form_handler").trigger("field_change", {
|
||||
id: $(this).closest("#$sFieldId").attr("id"),
|
||||
name: $(this).attr("name"),
|
||||
value: $(this).val()
|
||||
});
|
||||
});
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#{$this->oField->GetGlobalId()} input").off("change").on("change", function(){
|
||||
var me = this;
|
||||
|
||||
$(this).closest(".field_set").trigger("field_change", {
|
||||
id: $(me).closest("#{$this->oField->GetGlobalId()}").attr("id"),
|
||||
name: $(me).attr("name"),
|
||||
value: $(me).val()
|
||||
});
|
||||
});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// JS Form field widget construct
|
||||
$aValidators = array();
|
||||
foreach ($this->oField->GetValidators() as $oValidator)
|
||||
{
|
||||
$aValidators[$oValidator::GetName()] = array(
|
||||
'reg_exp' => $oValidator->GetRegExp(),
|
||||
'message' => Dict::S($oValidator->GetErrorMessage())
|
||||
);
|
||||
}
|
||||
// JS Form field widget construct
|
||||
$aValidators = array();
|
||||
foreach ($this->oField->GetValidators() as $oValidator)
|
||||
{
|
||||
$aValidators[$oValidator::GetName()] = array(
|
||||
'reg_exp' => $oValidator->GetRegExp(),
|
||||
'message' => Dict::S($oValidator->GetErrorMessage())
|
||||
);
|
||||
}
|
||||
|
||||
$sFormFieldOptions = json_encode(array(
|
||||
'validators' => $aValidators
|
||||
));
|
||||
$sFormFieldOptions = json_encode(array(
|
||||
'validators' => $aValidators
|
||||
));
|
||||
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("[data-field-id='{$this->oField->GetId()}']").form_field($sFormFieldOptions);
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\TextAreaField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\HiddenField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\RadioField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\CheckboxField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").portal_form_field($sFormFieldOptions);
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return $oOutput;
|
||||
}
|
||||
return $oOutput;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,33 +28,41 @@ use \Combodo\iTop\Form\Field\Field;
|
||||
*/
|
||||
abstract class FieldRenderer
|
||||
{
|
||||
protected $oField;
|
||||
protected $sEndpoint;
|
||||
protected $oField;
|
||||
protected $sEndpoint;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
*/
|
||||
public function __construct(Field $oField)
|
||||
{
|
||||
$this->oField = $oField;
|
||||
}
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
*/
|
||||
public function __construct(Field $oField)
|
||||
{
|
||||
$this->oField = $oField;
|
||||
}
|
||||
|
||||
public function GetEndpoint()
|
||||
{
|
||||
return $this->sEndpoint;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetEndpoint()
|
||||
{
|
||||
return $this->sEndpoint;
|
||||
}
|
||||
|
||||
public function SetEndpoint($sEndpoint)
|
||||
{
|
||||
$this->sEndpoint = $sEndpoint;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sEndpoint
|
||||
*/
|
||||
public function SetEndpoint($sEndpoint)
|
||||
{
|
||||
$this->sEndpoint = $sEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a Field as a RenderingOutput
|
||||
*
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
abstract public function Render();
|
||||
/**
|
||||
* Renders a Field as a RenderingOutput
|
||||
*
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
abstract public function Render();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Combodo\iTop\Renderer;
|
||||
use \Exception;
|
||||
use \Dict;
|
||||
use \Combodo\iTop\Form\Form;
|
||||
use \Combodo\iTop\Form\Field\Field;
|
||||
|
||||
/**
|
||||
* Description of FormRenderer
|
||||
@@ -30,231 +31,272 @@ use \Combodo\iTop\Form\Form;
|
||||
*/
|
||||
abstract class FormRenderer
|
||||
{
|
||||
const ENUM_RENDER_MODE_EXPLODED = 'exploded';
|
||||
const ENUM_RENDER_MODE_JOINED = 'joined';
|
||||
const DEFAULT_RENDERER_NAMESPACE = '';
|
||||
const ENUM_RENDER_MODE_EXPLODED = 'exploded';
|
||||
const ENUM_RENDER_MODE_JOINED = 'joined';
|
||||
const DEFAULT_RENDERER_NAMESPACE = '';
|
||||
|
||||
protected $oForm;
|
||||
protected $sEndpoint;
|
||||
protected $aSupportedFields;
|
||||
protected $sBaseLayout;
|
||||
protected $aOutputs;
|
||||
protected $oForm;
|
||||
protected $sEndpoint;
|
||||
protected $aSupportedFields;
|
||||
protected $sBaseLayout;
|
||||
protected $aOutputs;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Form $oForm
|
||||
*/
|
||||
public function __construct(Form $oForm = null)
|
||||
{
|
||||
if ($oForm !== null)
|
||||
{
|
||||
$this->oForm = $oForm;
|
||||
}
|
||||
$this->sBaseLayout = '';
|
||||
$this->InitOutputs();
|
||||
}
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Form $oForm
|
||||
*/
|
||||
public function __construct(Form $oForm = null)
|
||||
{
|
||||
if ($oForm !== null)
|
||||
{
|
||||
$this->oForm = $oForm;
|
||||
}
|
||||
$this->sBaseLayout = '';
|
||||
$this->InitOutputs();
|
||||
}
|
||||
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return \Combodo\iTop\Form\Form
|
||||
*/
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
}
|
||||
|
||||
public function SetForm($oForm)
|
||||
{
|
||||
$this->oForm = $oForm;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Form $oForm
|
||||
* @return \Combodo\iTop\Renderer\FormRenderer
|
||||
*/
|
||||
public function SetForm(Form $oForm)
|
||||
{
|
||||
$this->oForm = $oForm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetEndpoint()
|
||||
{
|
||||
return $this->sEndpoint;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetEndpoint()
|
||||
{
|
||||
return $this->sEndpoint;
|
||||
}
|
||||
|
||||
public function SetEndpoint($sEndpoint)
|
||||
{
|
||||
$this->sEndpoint = $sEndpoint;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sEndpoint
|
||||
* @return \Combodo\iTop\Renderer\FormRenderer
|
||||
*/
|
||||
public function SetEndpoint($sEndpoint)
|
||||
{
|
||||
$this->sEndpoint = $sEndpoint;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetBaseLayout()
|
||||
{
|
||||
return $this->sBaseLayout;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetBaseLayout()
|
||||
{
|
||||
return $this->sBaseLayout;
|
||||
}
|
||||
|
||||
public function SetBaseLayout($sBaseLayout)
|
||||
{
|
||||
$this->sBaseLayout = $sBaseLayout;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sBaseLayout
|
||||
* @return \Combodo\iTop\Renderer\FormRenderer
|
||||
*/
|
||||
public function SetBaseLayout($sBaseLayout)
|
||||
{
|
||||
$this->sBaseLayout = $sBaseLayout;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function GetFieldRendererClass($oField)
|
||||
{
|
||||
if (array_key_exists(get_class($oField), $this->aSupportedFields))
|
||||
{
|
||||
return $this->aSupportedFields[get_class($oField)];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('Field type not supported by the renderer: '.get_class($oField));
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetFieldRendererClass(Field $oField)
|
||||
{
|
||||
if (array_key_exists(get_class($oField), $this->aSupportedFields))
|
||||
{
|
||||
return $this->aSupportedFields[get_class($oField)];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('Field type not supported by the renderer: ' . get_class($oField));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field identified by the id $sId in $this->oForm.
|
||||
*
|
||||
* @param string $sId
|
||||
* @return \Combodo\iTop\Renderer\FieldRenderer
|
||||
*/
|
||||
public function GetFieldRendererClassFromId($sId)
|
||||
{
|
||||
return $this->GetFieldRendererClass($this->oForm->GetField($sId));
|
||||
}
|
||||
/**
|
||||
* Returns the field identified by the id $sId in $this->oForm.
|
||||
*
|
||||
* @param string $sId
|
||||
* @return \Combodo\iTop\Renderer\FieldRenderer
|
||||
*/
|
||||
public function GetFieldRendererClassFromId($sId)
|
||||
{
|
||||
return $this->GetFieldRendererClass($this->oForm->GetField($sId));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetOutputs()
|
||||
{
|
||||
return $this->aOutputs;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetOutputs()
|
||||
{
|
||||
return $this->aOutputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a Renderer class for the specified Field class.
|
||||
*
|
||||
* If the Field class is not fully qualified, the default "Combodo\iTop\Form\Field" will be prepend.
|
||||
* If the Field class already had a registered Renderer, it is replaced.
|
||||
*
|
||||
* @param string $sFieldClass
|
||||
* @param string $sRendererClass
|
||||
*/
|
||||
public function AddSupportedField($sFieldClass, $sRendererClass)
|
||||
{
|
||||
$sFieldClass = (strpos($sFieldClass, '\\') !== false) ? $sFieldClass : 'Combodo\\iTop\\Form\\Field\\' . $sFieldClass;
|
||||
$sRendererClass = (strpos($sRendererClass, '\\') !== false) ? $sRendererClass : static::DEFAULT_RENDERER_NAMESPACE . $sRendererClass;
|
||||
|
||||
/**
|
||||
* Registers a Renderer class for the specified Field class.
|
||||
*
|
||||
* If the Field class is not fully qualified, the default "Combodo\iTop\Form\Field" will be prepend.
|
||||
* If the Field class already had a registered Renderer, it is replaced.
|
||||
*
|
||||
* @param string $sFieldClass
|
||||
* @param string $sRendererClass
|
||||
*/
|
||||
public function AddSupportedField($sFieldClass, $sRendererClass)
|
||||
{
|
||||
$sFieldClass = (strpos($sFieldClass, '\\') !== false) ? $sFieldClass : 'Combodo\\iTop\\Form\\Field\\' . $sFieldClass;
|
||||
$sRendererClass = (strpos($sRendererClass, '\\') !== false) ? $sRendererClass : static::DEFAULT_RENDERER_NAMESPACE . $sRendererClass;
|
||||
$this->aSupportedFields[$sFieldClass] = $sRendererClass;
|
||||
|
||||
$this->aSupportedFields[$sFieldClass] = $sRendererClass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return \Combodo\iTop\Renderer\FormRenderer
|
||||
*/
|
||||
public function InitOutputs()
|
||||
{
|
||||
$this->aOutputs = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function InitOutputs()
|
||||
{
|
||||
$this->aOutputs = array();
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function Render()
|
||||
{
|
||||
$this->InitOutputs();
|
||||
|
||||
public function Render()
|
||||
{
|
||||
$this->InitOutputs();
|
||||
foreach ($this->oForm->GetFields() as $oField)
|
||||
{
|
||||
$this->aOutputs[$oField->GetId()] = $this->PrepareOutputForField($oField);
|
||||
}
|
||||
|
||||
foreach ($this->oForm->GetFields() as $oField)
|
||||
{
|
||||
$this->aOutputs[$oField->GetId()] = $this->PrepareOutputForField($oField);
|
||||
}
|
||||
return $this->aOutputs;
|
||||
}
|
||||
|
||||
return $this->aOutputs;
|
||||
}
|
||||
/**
|
||||
* Returns the output for the $oField. Output format depends on the $sMode.
|
||||
*
|
||||
* If $sMode = 'exploded', output is an has array with id / html / js_inline / js_files / css_inline / css_files / validators
|
||||
* Else if $sMode = 'joined', output is a string with everything in it
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
* @param string $sMode 'exploded'|'joined'
|
||||
* @return mixed
|
||||
*/
|
||||
protected function PrepareOutputForField($oField, $sMode = 'exploded')
|
||||
{
|
||||
$output = array(
|
||||
'id' => $oField->GetId(),
|
||||
'html' => '',
|
||||
'js_inline' => '',
|
||||
'css_inline' => '',
|
||||
'js_files' => array(),
|
||||
'css_files' => array()
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the output for the $oField. Output format depends on the $sMode.
|
||||
*
|
||||
* If $sMode = 'exploded', output is an has array with id / html / js_inline / js_files / css_inline / css_files / validators
|
||||
* Else if $sMode = 'joined', output is a string with everything in it
|
||||
*
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
* @param string $sMode 'exploded'|'joined'
|
||||
* @return mixed
|
||||
*/
|
||||
protected function PrepareOutputForField($oField, $sMode = 'exploded')
|
||||
{
|
||||
$output = array(
|
||||
'id' => $oField->GetId(),
|
||||
'html' => '',
|
||||
'js_inline' => '',
|
||||
'css_inline' => '',
|
||||
'js_files' => array(),
|
||||
'css_files' => array()
|
||||
);
|
||||
$sFieldRendererClass = $this->GetFieldRendererClass($oField);
|
||||
|
||||
$sFieldRendererClass = $this->GetFieldRendererClass($oField);
|
||||
$oFieldRenderer = new $sFieldRendererClass($oField);
|
||||
$oFieldRenderer->SetEndpoint($this->GetEndpoint());
|
||||
|
||||
$oFieldRenderer = new $sFieldRendererClass($oField);
|
||||
$oFieldRenderer->SetEndpoint($this->GetEndpoint());
|
||||
$oRenderingOutput = $oFieldRenderer->Render();
|
||||
|
||||
$oRenderingOutput = $oFieldRenderer->Render();
|
||||
// HTML
|
||||
if ($oRenderingOutput->GetHtml() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['html'] = $oRenderingOutput->GetHtml();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= $oRenderingOutput->GetHtml();
|
||||
}
|
||||
}
|
||||
|
||||
// HTML
|
||||
if ($oRenderingOutput->GetHtml() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['html'] = $oRenderingOutput->GetHtml();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= $oRenderingOutput->GetHtml();
|
||||
}
|
||||
}
|
||||
// JS files
|
||||
foreach ($oRenderingOutput->GetJsFiles() as $sJsFile)
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
if (!in_array($sJsFile, $output['js_files']))
|
||||
{
|
||||
$output['js_files'][] = $sJsFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<script src="' . $sJsFile . '" type="text/javascript"></script>';
|
||||
}
|
||||
}
|
||||
// JS inline
|
||||
if ($oRenderingOutput->GetJs() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['js_inline'] .= ' ' . $oRenderingOutput->GetJs();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<script type="text/javascript">' . $oRenderingOutput->GetJs() . '</script>';
|
||||
}
|
||||
}
|
||||
|
||||
// JS files
|
||||
foreach ($oRenderingOutput->GetJsFiles() as $sJsFile)
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
if (!in_array($sJsFile, $output['js_files']))
|
||||
{
|
||||
$output['js_files'][] = $sJsFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<script src="' . $sJsFile . '" type="text/javascript"></script>';
|
||||
}
|
||||
}
|
||||
// JS inline
|
||||
if ($oRenderingOutput->GetJs() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['js_inline'] .= ' ' . $oRenderingOutput->GetJs();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<script type="text/javascript">' . $oRenderingOutput->GetJs() . '</script>';
|
||||
}
|
||||
}
|
||||
// CSS files
|
||||
foreach ($oRenderingOutput->GetCssFiles() as $sCssFile)
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
if (!in_array($sCssFile, $output['css_files']))
|
||||
{
|
||||
$output['css_files'][] = $sCssFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<link href="' . $sCssFile . '" rel="stylesheet" />';
|
||||
}
|
||||
}
|
||||
// CSS inline
|
||||
if ($oRenderingOutput->GetCss() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['css_inline'] .= ' ' . $oRenderingOutput->GetCss();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<style>' . $oRenderingOutput->GetCss() . '</style>';
|
||||
}
|
||||
}
|
||||
|
||||
// CSS files
|
||||
foreach ($oRenderingOutput->GetCssFiles() as $sCssFile)
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
if (!in_array($sCssFile, $output['css_files']))
|
||||
{
|
||||
$output['css_files'][] = $sCssFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<link href="' . $sCssFile . '" rel="stylesheet" />';
|
||||
}
|
||||
}
|
||||
// CSS inline
|
||||
if ($oRenderingOutput->GetCss() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['css_inline'] .= ' ' . $oRenderingOutput->GetCss();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<style>' . $oRenderingOutput->GetCss() . '</style>';
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,153 +26,153 @@ namespace Combodo\iTop\Renderer;
|
||||
*/
|
||||
class RenderingOutput
|
||||
{
|
||||
protected $sHtml;
|
||||
protected $sJsInline;
|
||||
protected $aJsFiles;
|
||||
protected $sCssInline;
|
||||
protected $aCssFiles;
|
||||
protected $sHtml;
|
||||
protected $sJsInline;
|
||||
protected $aJsFiles;
|
||||
protected $sCssInline;
|
||||
protected $aCssFiles;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->sHtml = '';
|
||||
$this->sJsInline = '';
|
||||
$this->aJsFiles = array();
|
||||
$this->sCssInline = '';
|
||||
$this->aCssFiles = array();
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
$this->sHtml = '';
|
||||
$this->sJsInline = '';
|
||||
$this->aJsFiles = array();
|
||||
$this->sCssInline = '';
|
||||
$this->aCssFiles = array();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHtml()
|
||||
{
|
||||
return $this->sHtml;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetHtml()
|
||||
{
|
||||
return $this->sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetJs()
|
||||
{
|
||||
return $this->sJsInline;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetJs()
|
||||
{
|
||||
return $this->sJsInline;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetJsFiles()
|
||||
{
|
||||
return $this->aJsFiles;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetJsFiles()
|
||||
{
|
||||
return $this->aJsFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetCss()
|
||||
{
|
||||
return $this->sCssInline;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetCss()
|
||||
{
|
||||
return $this->sCssInline;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCssFiles()
|
||||
{
|
||||
return $this->aCssFiles;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCssFiles()
|
||||
{
|
||||
return $this->aCssFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sHtml
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddHtml($sHtml)
|
||||
{
|
||||
$this->sHtml .= $sHtml;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sHtml
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddHtml($sHtml)
|
||||
{
|
||||
$this->sHtml .= $sHtml;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sJs
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddJs($sJs)
|
||||
{
|
||||
$this->sJsInline .= $sJs . "\n";
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sJs
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddJs($sJs)
|
||||
{
|
||||
$this->sJsInline .= $sJs . "\n";
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddJsFile($sFile)
|
||||
{
|
||||
if (!in_array($sFile, $this->aJsFiles))
|
||||
{
|
||||
$this->aJsFiles[] = $sFile;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddJsFile($sFile)
|
||||
{
|
||||
if (!in_array($sFile, $this->aJsFiles))
|
||||
{
|
||||
$this->aJsFiles[] = $sFile;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function RemoveJsFile($sFile)
|
||||
{
|
||||
if (in_array($sFile, $this->aJsFiles))
|
||||
{
|
||||
unset($this->aJsFiles[$sFile]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function RemoveJsFile($sFile)
|
||||
{
|
||||
if (in_array($sFile, $this->aJsFiles))
|
||||
{
|
||||
unset($this->aJsFiles[$sFile]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sCss
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddCss($sCss)
|
||||
{
|
||||
$this->sCssInline .= $sCss . "\n";
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sCss
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddCss($sCss)
|
||||
{
|
||||
$this->sCssInline .= $sCss . "\n";
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddCssFile($sFile)
|
||||
{
|
||||
if (!in_array($sFile, $this->aCssFiles))
|
||||
{
|
||||
$this->aCssFiles[] = $sFile;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function AddCssFile($sFile)
|
||||
{
|
||||
if (!in_array($sFile, $this->aCssFiles))
|
||||
{
|
||||
$this->aCssFiles[] = $sFile;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function RemoveCssFile($sFile)
|
||||
{
|
||||
if (in_array($sFile, $this->aCssFiles))
|
||||
{
|
||||
unset($this->aCssFiles[$sFile]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
*/
|
||||
public function RemoveCssFile($sFile)
|
||||
{
|
||||
if (in_array($sFile, $this->aCssFiles))
|
||||
{
|
||||
unset($this->aCssFiles[$sFile]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user