mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-20 15:52:24 +02:00
Advanced search: WIP POC, integration with endpoint.
SVN:b1162[5412]
This commit is contained in:
@@ -9,6 +9,7 @@ $(function()
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
// Default values for the criteria
|
||||
ref: '',
|
||||
operator: '=',
|
||||
values: [],
|
||||
@@ -18,9 +19,33 @@ $(function()
|
||||
field: {
|
||||
label: '',
|
||||
},
|
||||
|
||||
// Available operators (merged with derived widgets, ordered and then copied to this.operators)
|
||||
available_operators: {
|
||||
'=': {
|
||||
'label': Dict.S('UI:Search:Criteria:Operator:Default:Equals'),
|
||||
'code': 'equals',
|
||||
'rank': 10,
|
||||
},
|
||||
'empty': {
|
||||
'label': Dict.S('UI:Search:Criteria:Operator:Default:Empty'),
|
||||
'code': 'empty',
|
||||
'rank': 90,
|
||||
},
|
||||
'not_empty': {
|
||||
'label': Dict.S('UI:Search:Criteria:Operator:Default:NotEmpty'),
|
||||
'code': 'not_empty',
|
||||
'rank': 100,
|
||||
},
|
||||
},
|
||||
|
||||
is_modified: false, // TODO: change this on value change and remove oql property value
|
||||
},
|
||||
|
||||
// Operators
|
||||
operators: {},
|
||||
|
||||
// Form handler
|
||||
handler: null,
|
||||
|
||||
// the constructor
|
||||
@@ -30,33 +55,13 @@ $(function()
|
||||
|
||||
this.element.addClass('search_form_criteria');
|
||||
|
||||
this._orderOperators();
|
||||
|
||||
// Link search form handler
|
||||
this.handler = this.element.closest('.search_form_handler');
|
||||
|
||||
// GetData
|
||||
this.element.bind('itop.search.criteria.get_data', function(oEvent, oData){
|
||||
return me._onGetData(oData);
|
||||
});
|
||||
// Get/SetCurrentValues callbacks handler
|
||||
this.element.bind('itop.search.criteria.get_current_values itop.search.criteria.set_current_values', 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('search form criteria: callback type must be a function or a existing function name of the widget');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// Bind events
|
||||
this._bindEvents();
|
||||
|
||||
this._prepareElement();
|
||||
},
|
||||
@@ -85,6 +90,43 @@ $(function()
|
||||
|
||||
|
||||
// Protected methods
|
||||
// - Order available operators
|
||||
_orderOperators: function()
|
||||
{
|
||||
console.log(this.options.available_operators);
|
||||
|
||||
},
|
||||
// - Bind external events
|
||||
_bindEvents: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
// Get criteria data
|
||||
this.element.bind('itop.search.criteria.get_data', function(oEvent, oData){
|
||||
return me._onGetData(oData);
|
||||
});
|
||||
|
||||
// Get/SetCurrentValues callbacks handler
|
||||
this.element.bind('itop.search.criteria.get_current_values itop.search.criteria.set_current_values', 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('search form criteria: callback type must be a function or a existing function name of the widget');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
_remove: function()
|
||||
{
|
||||
this.element.remove();
|
||||
@@ -93,6 +135,25 @@ $(function()
|
||||
|
||||
|
||||
// Event callbacks
|
||||
// - Internal events
|
||||
_onButtonApply: function()
|
||||
{
|
||||
this._trace('TODO: Apply button');
|
||||
this.handler.triggerHandler('itop.search.criteria.value_changed');
|
||||
},
|
||||
_onButtonCancel: function()
|
||||
{
|
||||
this._trace('TODO: Cancel button');
|
||||
},
|
||||
_onButtonMore: function()
|
||||
{
|
||||
this.element.find('.sfc_form_group').addClass('advanced');
|
||||
},
|
||||
_onButtonLess: function()
|
||||
{
|
||||
this.element.find('.sfc_form_group').removeClass('advanced');
|
||||
},
|
||||
// - External events
|
||||
_onGetData: function(oData)
|
||||
{
|
||||
var oCriteriaData = {
|
||||
@@ -113,16 +174,16 @@ $(function()
|
||||
var me = this;
|
||||
|
||||
// Prepare base DOM structure
|
||||
//this.options.ref+' '+this.options.operator+' '+this.options.values
|
||||
this.element
|
||||
.append('<div class="sfc_title"></div>')
|
||||
.append('<div class="sfc_form_group"></div>')
|
||||
.append('<div class="sfc_form_group"><div class="sfc_fg_operators"></div><div class="sfc_fg_buttons"></div></div>')
|
||||
.append('<span class="sfc_toggle"><a class="fa fa-caret-down" href="#"></a></span>');
|
||||
|
||||
// Bind events
|
||||
// - Toggler
|
||||
this.element.find('.sfc_toggle, .sfc_title').on('click', function(){
|
||||
me.element.find('.sfc_form_group').toggle();
|
||||
me.element.find('.sfc_toggle').toggleClass('opened');
|
||||
});
|
||||
|
||||
// Removable / locked decoration
|
||||
@@ -138,9 +199,64 @@ $(function()
|
||||
this.element.append('<div class="sfc_locked"><span class="fa fa-lock"></span></div>');
|
||||
}
|
||||
|
||||
// Form group
|
||||
this._prepareOperators();
|
||||
this._prepareButtons();
|
||||
|
||||
// Fill criteria
|
||||
// - Title
|
||||
this._setTitle();
|
||||
},
|
||||
// - Prepare the available operators for the criteria
|
||||
// Meant for overloading.
|
||||
_prepareOperators: function()
|
||||
{
|
||||
for(var sOpIdx in this.options.available_operators)
|
||||
{
|
||||
var oOp = this.options.available_operators[sOpIdx];
|
||||
var sMethod = '_prepare' + this._toCamelCase(oOp.code) + 'Operator';
|
||||
|
||||
// Create DOM element from template
|
||||
var oOpElem = $(this._getOperatorTemplate()).uniqueId();
|
||||
|
||||
// Prepare operator's base elements
|
||||
this._prepareOperator(oOpElem, oOp);
|
||||
|
||||
// Prepare operator's specific elements
|
||||
if(this[sMethod] !== undefined)
|
||||
{
|
||||
this[sMethod](oOpElem, oOp);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._prepareDefaultOperator(oOpElem, oOp);
|
||||
}
|
||||
|
||||
// Append to form group
|
||||
oOpElem.appendTo(this.element.find('.sfc_fg_operators'));
|
||||
}
|
||||
},
|
||||
// - Prepare the buttons (DOM and events) for a criteria
|
||||
_prepareButtons: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
// DOM elements
|
||||
this.element.find('.sfc_fg_buttons')
|
||||
.append('<button type="button" name="apply" class="sfc_fg_button sfc_fg_apply">' + Dict.S('UI:Button:Apply') + '</button>')
|
||||
.append('<button type="button" name="cancel" class="sfc_fg_button sfc_fg_cancel">' + Dict.S('UI:Button:Cancel') + '</button>')
|
||||
.append('<button type="button" name="more" class="sfc_fg_button sfc_fg_more">' + Dict.S('UI:Button:More') + '</button>')
|
||||
.append('<button type="button" name="less" class="sfc_fg_button sfc_fg_less">' + Dict.S('UI:Button:Less') + '</button>');
|
||||
|
||||
// Events
|
||||
this.element.find('.sfc_fg_button').on('click', function(oEvent){
|
||||
oEvent.preventDefault();
|
||||
oEvent.stopPropagation();
|
||||
|
||||
var sCallback = '_onButton' + me._toCamelCase($(this).attr('name'));
|
||||
me[sCallback]();
|
||||
});
|
||||
},
|
||||
// - Set the title element
|
||||
_setTitle: function(sTitle)
|
||||
{
|
||||
@@ -151,7 +267,49 @@ $(function()
|
||||
}
|
||||
this.element.find('.sfc_title').text(sTitle);
|
||||
},
|
||||
// - Return a HTML template for operators
|
||||
_getOperatorTemplate: function()
|
||||
{
|
||||
return '<div class="sfc_fg_operator"><label><input type="radio" class="sfc_op_radio" name="operator" value="" /><span class="sfc_op_name"></span><span class="sfc_op_content"></span></label></div>';
|
||||
},
|
||||
|
||||
// Operators helpers
|
||||
_prepareOperator: function(oOpElem, oOp)
|
||||
{
|
||||
var sInputId = oOp.code + '_' + oOpElem.attr('id');
|
||||
|
||||
// Set label
|
||||
oOpElem.find('.sfc_op_name').text(oOp.label);
|
||||
oOpElem.find('> label').attr('for', sInputId);
|
||||
|
||||
// Set value
|
||||
oOpElem.find('.sfc_op_radio').val(oOpElem.id);
|
||||
oOpElem.find('.sfc_op_radio').attr('id', sInputId);
|
||||
|
||||
// Bind events
|
||||
// - Check radio button on click
|
||||
oOpElem.on('click', function(){
|
||||
oOpElem.find('.sfc_op_radio').prop('checked', true);
|
||||
});
|
||||
},
|
||||
_prepareDefaultOperator: function(oOpElem, oOp)
|
||||
{
|
||||
var me = this;
|
||||
|
||||
// DOM element
|
||||
var oOpContentElem = $('<input type="text" />');
|
||||
oOpContentElem.val(this._getValuesAsText());
|
||||
|
||||
oOpElem.append(oOpContentElem);
|
||||
},
|
||||
_prepareEmptyOperator: function(oOpElem, oOp)
|
||||
{
|
||||
// Do nothing as only the label is necessary
|
||||
},
|
||||
_prepareNotEmptyOperator: function(oOpElem, oOp)
|
||||
{
|
||||
// Do nothing as only the label is necessary
|
||||
},
|
||||
|
||||
// Values helpers
|
||||
// - Convert values to a standard string
|
||||
@@ -181,6 +339,21 @@ $(function()
|
||||
},
|
||||
|
||||
|
||||
// Global helpers
|
||||
// - Converts a snake_case string to CamelCase
|
||||
_toCamelCase: function(sString)
|
||||
{
|
||||
var aParts = sString.split('_');
|
||||
|
||||
for(var i in aParts)
|
||||
{
|
||||
aParts[i] = aParts[i].charAt(0).toUpperCase() + aParts[i].substr(1);
|
||||
}
|
||||
|
||||
return aParts.join('');
|
||||
},
|
||||
|
||||
|
||||
// Debug helpers
|
||||
// - Show a trace in the javascript console
|
||||
_trace: function(sMessage, oData)
|
||||
|
||||
Reference in New Issue
Block a user