diff --git a/application/nicewebpage.class.inc.php b/application/nicewebpage.class.inc.php
index a97d97b00..8c2da2264 100644
--- a/application/nicewebpage.class.inc.php
+++ b/application/nicewebpage.class.inc.php
@@ -56,6 +56,7 @@ class NiceWebPage extends WebPage
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_raw.js');
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_string.js');
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_enum.js');
+ $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_numeric.js');
$this->add_ready_script(
<<< EOF
diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php
index 5f69811ca..6ad50fb44 100644
--- a/dictionaries/en.dictionary.itop.ui.php
+++ b/dictionaries/en.dictionary.itop.ui.php
@@ -1393,6 +1393,14 @@ When associated with a trigger, each action is given an "order" number, specifyi
'UI:Search:Criteria:Operator:String:Contains' => 'Contains:',
'UI:Search:Criteria:Operator:String:StartsWith' => 'Starts with:',
'UI:Search:Criteria:Operator:String:EndsWith' => 'Ends with:',
+ 'UI:Search:Criteria:Operator:Numeric:Equals' => '=',
+ 'UI:Search:Criteria:Operator:Numeric:GreaterThan' => '>',
+ 'UI:Search:Criteria:Operator:Numeric:GreaterThanOrEquals' => '>=',
+ 'UI:Search:Criteria:Operator:Numeric:LessThan' => '<',
+ 'UI:Search:Criteria:Operator:Numeric:LessThanOrEquals' => '<=',
+ 'UI:Search:Criteria:Operator:Numeric:DifferentThan' => 'Different than:',
+ 'UI:Search:Criteria:Operator:Numeric:Between' => 'Between:',
+
// - Criteria titles
'UI:Search:Criteria:Title:Default:Empty' => '%1$s is empty',
'UI:Search:Criteria:Title:Default:NotEmpty' => '%1$s is not empty',
diff --git a/js/search/search_form_criteria_numeric.js b/js/search/search_form_criteria_numeric.js
new file mode 100644
index 000000000..91c8b4463
--- /dev/null
+++ b/js/search/search_form_criteria_numeric.js
@@ -0,0 +1,162 @@
+//iTop Search form criteria numeric
+;
+$(function()
+{
+ // the widget definition, where 'itop' is the namespace,
+ // 'search_form_criteria_numeric' the widget name
+ $.widget( 'itop.search_form_criteria_numeric', $.itop.search_form_criteria,
+ {
+ // default options
+ options:
+ {
+ // Overload default operator
+ 'operator': '=',
+ // Available operators
+ 'available_operators': {
+ '=': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:Equals'),//pre-existing, label changed
+ 'dropdown_group':1,
+ },
+ '>': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:GreaterThan'),
+ 'code': 'greater_than',
+ 'rank': 100,
+ 'dropdown_group':1,
+ },
+ '>=': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:GreaterThanOrEquals'),
+ 'code': 'greater_than_or_equals',
+ 'rank': 200,
+ 'dropdown_group':1,
+ },
+ '<': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:LessThan'),
+ 'code': 'less_than',
+ 'rank': 300,
+ 'dropdown_group':1,
+ },
+ '<=': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:LessThanOrEquals'),
+ 'code': 'less_than_or_equals',
+ 'rank': 400,
+ 'dropdown_group':1,
+ },
+ '!=': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:DifferentThan'),
+ 'code': 'different',
+ 'rank': 500,
+ 'dropdown_group':1,
+ },
+ 'between': {
+ 'label': Dict.S('UI:Search:Criteria:Operator:Numeric:Between'),
+ 'code': 'between',
+ 'rank': 600,
+ },
+ 'empty': {
+ 'rank': 700,//pre-existing, reordered
+ },
+ 'not_empty': {
+ 'rank': 800,//pre-existing, reordered
+ },
+ },
+ },
+
+
+ // the constructor
+ _create: function()
+ {
+ var me = this;
+
+ this._super();
+ this.element.addClass('search_form_criteria_numeric');
+ },
+ // 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('search_form_criteria_numeric');
+ this._super();
+ },
+ // _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 );
+ },
+
+ //------------------
+ // Inherited methods
+ //------------------
+
+ //
+ // // Prepare operator's DOM element
+ // // - Base preparation, always called
+ // _prepareOperator: function(oOpElem, sOpIdx, oOp)
+ // {
+ // var me = this;
+ // if (typeof oOp.dropdown_group == 'undefined')
+ // {
+ // return this._super(oOpElem, sOpIdx, oOp);
+ // }
+ //
+ // this._super(oOpElem, sOpIdx, oOp);
+ // oOpElem.addClass('force_hide')
+ //
+ // // DOM element
+ // oDropdown = this.element.find('select.dropdown_group_'+oOp.dropdown_group);
+ // if (oDropdown.length == 0)
+ // {
+ // oDropdown = $('');
+ //
+ // oDropdown.on('change', function(){
+ // $option = $(this);
+ // this.element.find('.sfc_op_radio').val($option.val());
+ //
+ // oOptionOp = $option.data('oOp');
+ // $option.attr('data-operator-code', oOptionOp.code);
+ // });
+ //
+ //
+ // // Create DOM element from template
+ // var oOpElemDropdown = $(this._getOperatorTemplate()).uniqueId();
+ //
+ // oOpElemDropdown
+ // .addClass('sfc_fg_operator_dropdown_group')
+ // .data('data-operator-code', 'dropdown_group')
+ // .find('.sfc_op_name')
+ // .append(oDropdown)
+ // .end()
+ // .find('.sfc_op_radio')
+ // .val(sOpIdx)
+ // .end()
+ // .on('click', function(){
+ // var bIsChecked = oOpElemDropdown.find('.sfc_op_radio').prop('checked');
+ //
+ // if(bIsChecked === false)
+ // {
+ // oOpElemDropdown.find('.sfc_op_radio').prop('checked', true);
+ // me._markAsDraft();
+ // }
+ // })
+ // .appendTo(this.element.find('.sfc_fg_operators'));
+ // }
+ //
+ // oDropdown
+ // .append('')
+ // .data('oOp', oOp)
+ // ;
+ // },
+
+
+ });
+});