mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 23:32:17 +02:00
Prerequisites for custom fields
SVN:trunk[3913]
This commit is contained in:
305
js/field_set.js
Normal file
305
js/field_set.js
Normal file
@@ -0,0 +1,305 @@
|
||||
//iTop Form handler
|
||||
;
|
||||
$(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
|
||||
},
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
// 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();
|
||||
}
|
||||
},
|
||||
|
||||
// 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();
|
||||
|
||||
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();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Validate the field
|
||||
var oRes = this._getField(data.name).triggerHandler('validate', {touched_fields_only: true});
|
||||
if (!oRes.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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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();
|
||||
|
||||
this.options.is_valid = true;
|
||||
|
||||
|
||||
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', 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(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 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 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(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());
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -26,19 +26,21 @@ $(function()
|
||||
|
||||
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]();
|
||||
return me[callback](event, data);
|
||||
}
|
||||
else if(typeof callback === 'function')
|
||||
{
|
||||
return callback(me);
|
||||
return callback(me, event, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -72,29 +74,29 @@ $(function()
|
||||
},
|
||||
getCurrentValue: function()
|
||||
{
|
||||
var value = {};
|
||||
var value = null;
|
||||
|
||||
this.element.find(':input').each(function(index, elem){
|
||||
if($(elem).is(':hidden') || $(elem).is(':text') || $(elem).is('textarea'))
|
||||
{
|
||||
value[$(elem).attr('name')] = $(elem).val();
|
||||
value = $(elem).val();
|
||||
}
|
||||
else if($(elem).is('select'))
|
||||
{
|
||||
value[$(elem).attr('name')] = [];
|
||||
value = [];
|
||||
$(elem).find('option:selected').each(function(){
|
||||
value[$(elem).attr('name')].push($(this).val());
|
||||
value.push($(this).val());
|
||||
});
|
||||
}
|
||||
else if($(elem).is(':checkbox') || $(elem).is(':radio'))
|
||||
{
|
||||
if(value[$(elem).attr('name')] === undefined)
|
||||
if(value === null)
|
||||
{
|
||||
value[$(elem).attr('name')] = [];
|
||||
value = [];
|
||||
}
|
||||
if($(elem).is(':checked'))
|
||||
{
|
||||
value[$(elem).attr('name')].push($(elem).val());
|
||||
value.push($(elem).val());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -105,10 +107,10 @@ $(function()
|
||||
|
||||
return value;
|
||||
},
|
||||
validate: function()
|
||||
validate: function(event, data)
|
||||
{
|
||||
var oResult = { is_valid: true, error_messages: [] };
|
||||
|
||||
|
||||
// Doing data validation
|
||||
if(this.options.validators !== null)
|
||||
{
|
||||
@@ -139,7 +141,7 @@ $(function()
|
||||
oResult.is_valid = false;
|
||||
oResult.error_messages.push(oValidator.message);
|
||||
}
|
||||
// ... In case of none empty array, we have to check is the value is not null
|
||||
// ... 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)
|
||||
@@ -190,7 +192,7 @@ $(function()
|
||||
}
|
||||
}
|
||||
|
||||
this.options.on_validation_callback();
|
||||
this.options.on_validation_callback(this, oResult);
|
||||
|
||||
return oResult;
|
||||
},
|
||||
|
||||
@@ -11,25 +11,13 @@ $(function()
|
||||
{
|
||||
formmanager_class: null,
|
||||
formmanager_data: null,
|
||||
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: [],
|
||||
submit_btn_selector: null,
|
||||
cancel_btn_selector: null,
|
||||
endpoint: null,
|
||||
is_modal: false,
|
||||
is_valid: true,
|
||||
script_element: null,
|
||||
style_element: null
|
||||
field_set: null
|
||||
},
|
||||
|
||||
buildData:
|
||||
{
|
||||
script_code: '',
|
||||
style_code: ''
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
@@ -37,30 +25,11 @@ $(function()
|
||||
|
||||
this.element
|
||||
.addClass('form_handler');
|
||||
|
||||
this.element
|
||||
.bind('field_change', function(event, data){
|
||||
me._onFieldChange(event, data);
|
||||
|
||||
this.element.bind('update_fields', function(event, data){
|
||||
this._onUpdateFields(event, data);
|
||||
});
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
||||
// Binding buttons
|
||||
if(this.options.submit_btn_selector !== null)
|
||||
{
|
||||
@@ -97,41 +66,13 @@ $(function()
|
||||
},
|
||||
getCurrentValues: function()
|
||||
{
|
||||
var result = {};
|
||||
|
||||
for(var i in this.options.fields_list)
|
||||
{
|
||||
var field = this.options.fields_list[i];
|
||||
if(this.element.find('[' + this.options.field_identifier_attr + '="'+field.id+'"]').hasClass('form_field'))
|
||||
{
|
||||
$.extend(true, result, this.element.find('[' + this.options.field_identifier_attr + '="'+field.id+'"]').triggerHandler('get_current_value'));
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Form handler : 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;
|
||||
return this.options.field_set.triggerHandler('get_current_values');
|
||||
},
|
||||
_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)
|
||||
_onUpdateFields: function(event, data)
|
||||
{
|
||||
var me = this;
|
||||
|
||||
var sFormPath = data.form_path;
|
||||
|
||||
// Data checks
|
||||
if(this.options.endpoint === null)
|
||||
{
|
||||
@@ -149,37 +90,23 @@ $(function()
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
var requestedFields = this._getRequestedFields(data.name);
|
||||
if(requestedFields.length > 0)
|
||||
{
|
||||
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: requestedFields
|
||||
},
|
||||
function(data){
|
||||
me._onUpdateSuccess(data);
|
||||
}
|
||||
)
|
||||
.fail(function(data){ me._onUpdateFailure(data); })
|
||||
.always(function(data){ me._onUpdateAlways(data); });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check self NOW as they are no ajax call
|
||||
this.element.find('[' + this.options.field_identifier_attr + '="' + data.name + '"]').trigger('validate');
|
||||
}
|
||||
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)
|
||||
@@ -190,40 +117,22 @@ $(function()
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateSuccess: function(data)
|
||||
_onUpdateSuccess: function(data, sFormPath)
|
||||
{
|
||||
if(data.form.updated_fields !== undefined)
|
||||
{
|
||||
this.buildData.script_code = '';
|
||||
this.buildData.style_code = '';
|
||||
|
||||
for (var i in data.form.updated_fields)
|
||||
{
|
||||
var updated_field = data.form.updated_fields[i];
|
||||
this.options.fields_list[updated_field.id] = updated_field;
|
||||
this._prepareField(updated_field.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);
|
||||
|
||||
// Evaluating script code as adding it to dom did not executed it (only script from update !)
|
||||
eval(this.buildData.script_code);
|
||||
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)
|
||||
_onUpdateFailure: function(data, sFormPath)
|
||||
{
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
_onUpdateAlways: function(data)
|
||||
_onUpdateAlways: function(data, sFormPath)
|
||||
{
|
||||
// Check all touched AFTER ajax is complete, otherwise the renderer will redraw the field in the mean time.
|
||||
for(var i in this.options.touched_fields)
|
||||
{
|
||||
this.element.find('[' + this.options.field_identifier_attr + '="' + this.options.touched_fields[i] + '"]').trigger('validate');
|
||||
}
|
||||
this.element.find('[data-form-path="'+sFormPath+'"]').trigger('validate');
|
||||
this._enableFormAfterLoading();
|
||||
},
|
||||
// Intended for overloading in derived classes
|
||||
@@ -234,91 +143,6 @@ $(function()
|
||||
_enableFormAfterLoading: function()
|
||||
{
|
||||
},
|
||||
_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+'"></div>').appendTo(this.element);
|
||||
},
|
||||
_prepareField: function(field_id)
|
||||
{
|
||||
var field = this.options.fields_list[field_id];
|
||||
|
||||
if(this.element.find('[' + this.options.field_identifier_attr + '="'+field.id+'"]').length === 1)
|
||||
{
|
||||
// We replace the node instead of just replacing the inner html so the previous widget is automatically destroyed.
|
||||
this.element.find('[' + this.options.field_identifier_attr + '="'+field.id+'"]').replaceWith( $('<div ' + this.options.field_identifier_attr + '="'+field.id+'"></div>') );
|
||||
}
|
||||
else
|
||||
{
|
||||
this._addField(field.id);
|
||||
}
|
||||
|
||||
var field_container = this.element.find('[' + this.options.field_identifier_attr + '="'+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 field = this.options.fields_list[i];
|
||||
if(field.id === undefined)
|
||||
{
|
||||
console.log('Form handler : An field must have at least an id property.');
|
||||
return false;
|
||||
}
|
||||
|
||||
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());
|
||||
},
|
||||
showOptions: function() // Debug helper
|
||||
{
|
||||
console.log(this.options);
|
||||
|
||||
46
js/subform_field.js
Normal file
46
js/subform_field.js
Normal file
@@ -0,0 +1,46 @@
|
||||
//iTop Form 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 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();
|
||||
},
|
||||
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: []
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -23,6 +23,7 @@
|
||||
require_once APPROOT . 'sources/form/form.class.inc.php';
|
||||
require_once APPROOT . 'sources/form/formmanager.class.inc.php';
|
||||
require_once APPROOT . 'sources/form/field/field.class.inc.php';
|
||||
require_once APPROOT . 'sources/form/field/subformfield.class.inc.php';
|
||||
require_once APPROOT . 'sources/form/field/textfield.class.inc.php';
|
||||
require_once APPROOT . 'sources/form/field/hiddenfield.class.inc.php';
|
||||
require_once APPROOT . 'sources/form/field/stringfield.class.inc.php';
|
||||
|
||||
@@ -36,6 +36,8 @@ abstract class Field
|
||||
const DEFAULT_VALID = true;
|
||||
|
||||
protected $sId;
|
||||
protected $sGlobalId;
|
||||
protected $sFormPath;
|
||||
protected $sLabel;
|
||||
protected $bReadOnly;
|
||||
protected $bMandatory;
|
||||
@@ -52,6 +54,7 @@ abstract class Field
|
||||
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;
|
||||
@@ -61,11 +64,33 @@ abstract class Field
|
||||
$this->onFinalizeCallback = $onFinalizeCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field id within its container form
|
||||
* @return string
|
||||
*/
|
||||
public function GetId()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a unique field id within the top level form
|
||||
* @return string
|
||||
*/
|
||||
public function GetGlobalId()
|
||||
{
|
||||
return $this->sGlobalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id of the container form
|
||||
* @return string
|
||||
*/
|
||||
public function GetFormPath()
|
||||
{
|
||||
return $this->sFormPath;
|
||||
}
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->sLabel;
|
||||
@@ -184,6 +209,14 @@ abstract class Field
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the form when adding the field
|
||||
*/
|
||||
public function SetFormPath($sFormPath)
|
||||
{
|
||||
$this->sFormPath = $sFormPath;
|
||||
}
|
||||
|
||||
public function AddValidator(Validator $oValidator)
|
||||
{
|
||||
$this->aValidators[] = $oValidator;
|
||||
@@ -206,7 +239,7 @@ abstract class Field
|
||||
* Note : Function is protected as aErrorMessages should not be add from outside
|
||||
*
|
||||
* @param string $sErrorMessage
|
||||
* @return \Combodo\iTop\Field\Field
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function AddErrorMessage($sErrorMessage)
|
||||
{
|
||||
@@ -217,7 +250,7 @@ abstract class Field
|
||||
/**
|
||||
* Note : Function is protected as aErrorMessages should not be set from outside
|
||||
*
|
||||
* @return \Combodo\iTop\Field\Field
|
||||
* @return \Combodo\iTop\Form\Field\Field
|
||||
*/
|
||||
protected function EmptyErrorMessages()
|
||||
{
|
||||
@@ -236,7 +269,7 @@ abstract class Field
|
||||
{
|
||||
// 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();
|
||||
$callback($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
76
sources/form/field/subformfield.class.inc.php
Normal file
76
sources/form/field/subformfield.class.inc.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Form\Field;
|
||||
|
||||
use \Closure;
|
||||
use \Combodo\iTop\Form\Field\Field;
|
||||
use \Combodo\iTop\Form\Form;
|
||||
|
||||
/**
|
||||
* Description of StringField
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
*/
|
||||
class SubFormField extends Field
|
||||
{
|
||||
protected $oForm;
|
||||
|
||||
public function __construct($sId, $sParentFormId, Closure $onFinalizeCallback = null)
|
||||
{
|
||||
$this->oForm = new \Combodo\iTop\Form\Form($sParentFormId.'-subform_'.$sId);
|
||||
parent::__construct($sId, $onFinalizeCallback);
|
||||
}
|
||||
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validators to see if the field's current value is valid.
|
||||
* Then sets $bValid and $aErrorMessages.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function Validate()
|
||||
{
|
||||
$this->oForm->Validate();
|
||||
}
|
||||
|
||||
public function GetValid()
|
||||
{
|
||||
return $this->oForm->GetValid();
|
||||
}
|
||||
|
||||
public function GetErrorMessages()
|
||||
{
|
||||
return $this->oForm->GetErrorMessages();
|
||||
}
|
||||
|
||||
public function GetCurrentValue()
|
||||
{
|
||||
return $this->oForm->GetCurrentValues();
|
||||
}
|
||||
|
||||
public function SetCurrentValue($value)
|
||||
{
|
||||
return $this->oForm->SetCurrentValues($value);
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,25 @@ class Form
|
||||
return $this->aDependencies;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current validation state of the form (true|false).
|
||||
* It DOESN'T make the validation, see Validate() instead.
|
||||
@@ -154,6 +173,7 @@ class Form
|
||||
|
||||
public function AddField(Field $oField, $aDependsOnIds = array())
|
||||
{
|
||||
$oField->SetFormPath($this->sId);
|
||||
$this->aFields[$oField->GetId()] = $oField;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -52,11 +52,17 @@ abstract class FormManager
|
||||
// Overload in child class when needed
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Form
|
||||
*/
|
||||
public function GetForm()
|
||||
{
|
||||
return $this->oForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FormRenderer
|
||||
*/
|
||||
public function GetRenderer()
|
||||
{
|
||||
return $this->oRenderer;
|
||||
|
||||
39
sources/renderer/console/consoleformrenderer.class.inc.php
Normal file
39
sources/renderer/console/consoleformrenderer.class.inc.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
// Copyright (C) 2016 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Renderer\Console;
|
||||
|
||||
use Combodo\iTop\Form\Form;
|
||||
use Combodo\iTop\Renderer\FormRenderer;
|
||||
use Combodo\iTop\Renderer\RenderingOutput;
|
||||
use \Dict;
|
||||
|
||||
require_once('fieldrenderer/consolesimplefieldrenderer.class.inc.php');
|
||||
require_once('fieldrenderer/consolesubformfieldrenderer.class.inc.php');
|
||||
|
||||
class ConsoleFormRenderer extends FormRenderer
|
||||
{
|
||||
const DEFAULT_RENDERER_NAMESPACE = 'Combodo\\iTop\\Renderer\\Console\\FieldRenderer\\';
|
||||
|
||||
public function __construct(Form $oForm)
|
||||
{
|
||||
parent::__construct($oForm);
|
||||
$this->AddSupportedField('StringField', 'ConsoleSimpleFieldRenderer');
|
||||
$this->AddSupportedField('SubFormField', 'ConsoleSubFormFieldRenderer');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
// Copyright (C) 2016 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Renderer\Console\FieldRenderer;
|
||||
|
||||
use \Dict;
|
||||
use Combodo\iTop\Renderer\FieldRenderer;
|
||||
use Combodo\iTop\Renderer\RenderingOutput;
|
||||
|
||||
class ConsoleSimpleFieldRenderer extends FieldRenderer
|
||||
{
|
||||
public function Render()
|
||||
{
|
||||
$oOutput = new RenderingOutput();
|
||||
$sFieldClass = get_class($this->oField);
|
||||
|
||||
// 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':
|
||||
if ($this->oField->GetLabel() !== '')
|
||||
{
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label">' . $this->oField->GetLabel() . '</label>');
|
||||
}
|
||||
$oOutput->AddHtml('<input type="text" id="'.$this->oField->GetGlobalId().'" value="' . $this->oField->GetCurrentValue() . '" size="30" />');
|
||||
$oOutput->AddHtml('<span class="form_validation"></span>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... and in read-only mode
|
||||
else
|
||||
{
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
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>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($sFieldClass)
|
||||
{
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#{$this->oField->GetGlobalId()}").off("change").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;
|
||||
}
|
||||
|
||||
// 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())
|
||||
);
|
||||
}
|
||||
|
||||
$sValidators = json_encode($aValidators);
|
||||
$sFormFieldOptions =
|
||||
<<<EOF
|
||||
{
|
||||
validators: $sValidators,
|
||||
on_validation_callback: function(me, oResult) {
|
||||
var oValidationElement = $(me.element).find('span.form_validation');
|
||||
if (oResult.is_valid)
|
||||
{
|
||||
oValidationElement.html('');
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: escape html entities
|
||||
var sExplain = oResult.error_messages.join(', ');
|
||||
oValidationElement.html('<img src="../images/validation_error.png" style="vertical-align:middle" data-tooltip="'+sExplain+'"/>');
|
||||
oValidationElement.tooltip({
|
||||
items: 'span',
|
||||
tooltipClass: 'form_field_error',
|
||||
content: function() {
|
||||
return $(this).find('img').attr('data-tooltip'); // As opposed to the default 'content' handler, do not escape the contents of 'title'
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
;
|
||||
|
||||
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()}']").form_field($sFormFieldOptions);
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return $oOutput;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
// Copyright (C) 2016 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
namespace Combodo\iTop\Renderer\Console\FieldRenderer;
|
||||
|
||||
use \Dict;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||
use Combodo\iTop\Renderer\FieldRenderer;
|
||||
use Combodo\iTop\Renderer\RenderingOutput;
|
||||
|
||||
class ConsoleSubFormFieldRenderer extends FieldRenderer
|
||||
{
|
||||
public function Render()
|
||||
{
|
||||
$oOutput = new RenderingOutput();
|
||||
|
||||
$oOutput->AddHtml('<div id="fieldset_'.$this->oField->GetGlobalId().'">');
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
$oRenderer = new ConsoleFormRenderer($this->oField->GetForm());
|
||||
$aRenderRes = $oRenderer->Render();
|
||||
|
||||
$aFieldSetOptions = array(
|
||||
'fields_list' => $aRenderRes,
|
||||
'fields_impacts' => $this->oField->GetForm()->GetFieldsImpacts(),
|
||||
'form_path' => $this->oField->GetForm()->GetId()
|
||||
);
|
||||
$sFieldSetOptions = json_encode($aFieldSetOptions);
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$("#fieldset_{$this->oField->GetGlobalId()}").field_set($sFieldSetOptions);
|
||||
$("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").subform_field({field_set: $("#fieldset_{$this->oField->GetGlobalId()}")});
|
||||
EOF
|
||||
);
|
||||
return $oOutput;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace Combodo\iTop\Renderer;
|
||||
|
||||
use \Exception;
|
||||
use \Dict;
|
||||
use \Combodo\iTop\Form\Form;
|
||||
|
||||
@@ -95,8 +96,7 @@ abstract class FormRenderer
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO : We might want to throw an exception.
|
||||
return null;
|
||||
throw new Exception('Field type not supported by the renderer: '.get_class($oField));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ abstract class FormRenderer
|
||||
* Returns the field identified by the id $sId in $this->oForm.
|
||||
*
|
||||
* @param string $sId
|
||||
* @return Combodo\iTop\Renderer\FieldRenderer
|
||||
* @return \Combodo\iTop\Renderer\FieldRenderer
|
||||
*/
|
||||
public function GetFieldRendererClassFromId($sId)
|
||||
{
|
||||
@@ -164,7 +164,7 @@ abstract class FormRenderer
|
||||
* 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 \Combodo\iTop\Form\Field\Field $oField
|
||||
* @param string $sMode 'exploded'|'joined'
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -180,81 +180,78 @@ abstract class FormRenderer
|
||||
);
|
||||
|
||||
$sFieldRendererClass = $this->GetFieldRendererClass($oField);
|
||||
// TODO : We might want to throw an exception instead when there is no renderer for that field
|
||||
if ($sFieldRendererClass !== null)
|
||||
|
||||
$oFieldRenderer = new $sFieldRendererClass($oField);
|
||||
$oFieldRenderer->SetEndpoint($this->GetEndpoint());
|
||||
|
||||
$oRenderingOutput = $oFieldRenderer->Render();
|
||||
|
||||
// HTML
|
||||
if ($oRenderingOutput->GetHtml() !== '')
|
||||
{
|
||||
$oFieldRenderer = new $sFieldRendererClass($oField);
|
||||
$oFieldRenderer->SetEndpoint($this->GetEndpoint());
|
||||
|
||||
$oRenderingOutput = $oFieldRenderer->Render();
|
||||
|
||||
// HTML
|
||||
if ($oRenderingOutput->GetHtml() !== '')
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
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['html'] = $oRenderingOutput->GetHtml();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= $oRenderingOutput->GetHtml();
|
||||
$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)
|
||||
// CSS files
|
||||
foreach ($oRenderingOutput->GetCssFiles() as $sCssFile)
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
if (!in_array($sCssFile, $output['css_files']))
|
||||
{
|
||||
if (!in_array($sJsFile, $output['js_files']))
|
||||
{
|
||||
$output['js_files'][] = $sJsFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<script src="' . $sJsFile . '" type="text/javascript"></script>';
|
||||
$output['css_files'][] = $sCssFile;
|
||||
}
|
||||
}
|
||||
// JS inline
|
||||
if ($oRenderingOutput->GetJs() !== '')
|
||||
else
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['js_inline'] .= ' ' . $oRenderingOutput->GetJs();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<script type="text/javascript">' . $oRenderingOutput->GetJs() . '</script>';
|
||||
}
|
||||
$output['html'] .= '<link href="' . $sCssFile . '" rel="stylesheet" />';
|
||||
}
|
||||
|
||||
// CSS files
|
||||
foreach ($oRenderingOutput->GetCssFiles() as $sCssFile)
|
||||
}
|
||||
// CSS inline
|
||||
if ($oRenderingOutput->GetCss() !== '')
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
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" />';
|
||||
}
|
||||
$output['css_inline'] .= ' ' . $oRenderingOutput->GetCss();
|
||||
}
|
||||
// CSS inline
|
||||
if ($oRenderingOutput->GetCss() !== '')
|
||||
else
|
||||
{
|
||||
if ($sMode === static::ENUM_RENDER_MODE_EXPLODED)
|
||||
{
|
||||
$output['css_inline'] .= ' ' . $oRenderingOutput->GetCss();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output['html'] .= '<style>' . $oRenderingOutput->GetCss() . '</style>';
|
||||
}
|
||||
$output['html'] .= '<style>' . $oRenderingOutput->GetCss() . '</style>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user