Advanced search: More criteria UX WIP.

SVN:b1162[5510]
This commit is contained in:
Guillaume Lajarige
2018-03-23 14:23:32 +00:00
parent c1adf880a4
commit 3a32bd62ef
6 changed files with 201 additions and 71 deletions

View File

@@ -718,6 +718,7 @@ input.dp-applied {
/* Sizing reset */
/* Hyperlink reset */
/* Input reset */
/* List helpers */
}
.search_form_handler * {
box-sizing: border-box;
@@ -897,24 +898,6 @@ input.dp-applied {
margin-left: 0px;
margin-right: 8px;
}
.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group .sfc_fg_operators .sfc_fg_operator .sfc_opc_multichoices .sfc_opc_mc_filter {
position: relative;
margin-top: 8px;
margin-bottom: 8px;
}
.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group .sfc_fg_operators .sfc_fg_operator .sfc_opc_multichoices .sfc_opc_mc_filter input {
width: 100%;
}
.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group .sfc_fg_operators .sfc_fg_operator .sfc_opc_multichoices .sfc_opc_mc_filter .sfc_opc_mcf_picto {
position: absolute;
right: 5px;
top: 5px;
opacity: 0.6;
user-select: none;
}
.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group .sfc_fg_operators .sfc_fg_operator .sfc_opc_multichoices .sfc_opc_mc_filter .sfc_opc_mc_reset {
display: none;
}
.search_form_handler .sf_criterion_area .search_form_criteria .sfc_form_group .sfc_fg_operators .sfc_fg_operator .sfc_opc_multichoices .sfc_opc_mc_items {
max-height: 445px;
/* Must be less than .sfc_form_group:max-height - .sfc_opc_mc_toggler:height - .sfc_opc_mc_filter:height */
@@ -1049,6 +1032,50 @@ input.dp-applied {
cursor: pointer;
white-space: nowrap;
}
.search_form_handler .sf_list .sfl_title {
font-weight: bold;
}
.search_form_handler .sf_list .sfl_items {
margin: 5px -8px 0px -8px;
padding: 0px;
}
.search_form_handler .sf_list .sfl_items > li {
padding: 4px 8px;
list-style: none;
white-space: nowrap;
}
.search_form_handler .sf_list .sfl_items > li:hover {
background-color: #fff;
}
.search_form_handler .sf_list .sfl_items > li > label {
display: inline-block;
width: 100%;
}
.search_form_handler .sf_list .sfl_items > li > label > * {
vertical-align: middle;
}
.search_form_handler .sf_list .sfl_items > li > label > input[type="checkbox"] {
margin-left: 0px;
margin-right: 8px;
}
.search_form_handler .sf_filter {
position: relative;
margin-top: 8px;
margin-bottom: 8px;
}
.search_form_handler .sf_filter input {
width: 100%;
}
.search_form_handler .sf_filter .sff_picto {
position: absolute;
right: 5px;
top: 5px;
opacity: 0.6;
user-select: none;
}
.search_form_handler .sf_filter .sff_reset {
display: none;
}
.sf_results_area .sf_results_placeholder {
margin-top: 100px;
text-align: center;

View File

@@ -1004,25 +1004,6 @@ input.dp-applied {
}
.sfc_opc_mc_toggler{
}
.sfc_opc_mc_filter{
position: relative;
margin-top: 8px;
margin-bottom: 8px;
input{
width: 100%;
}
.sfc_opc_mcf_picto{
position: absolute;
right: 5px;
top: 5px;
opacity: 0.6;
user-select: none;
}
.sfc_opc_mc_reset{
display: none;
}
}
.sfc_opc_mc_items{
max-height: 445px; /* Must be less than .sfc_form_group:max-height - .sfc_opc_mc_toggler:height - .sfc_opc_mc_filter:height */
@@ -1223,6 +1204,60 @@ input.dp-applied {
}
}
}
/* List helpers */
.sf_list{
.sfl_title{
font-weight: bold;
}
.sfl_items{
margin: 5px -8px 0px -8px;
padding: 0px;
> li{
padding: 4px 8px;
list-style: none;
white-space: nowrap;
&:hover{
background-color: $white;
}
> label{
display: inline-block;
width: 100%;
> *{
vertical-align: middle;
}
> input[type="checkbox"]{
margin-left: 0px;
margin-right: 8px;
}
}
}
}
}
.sf_filter{
position: relative;
margin-top: 8px;
margin-bottom: 8px;
input{
width: 100%;
}
.sff_picto{
position: absolute;
right: 5px;
top: 5px;
opacity: 0.6;
user-select: none;
}
.sff_reset{
display: none;
}
}
}
.sf_results_area{
.sf_results_placeholder{

View File

@@ -1386,6 +1386,11 @@ When associated with a trigger, each action is given an "order" number, specifyi
// Search form
'UI:Search:Toggle' => 'Minimize / Expand',
'UI:Search:Criterion:MoreMenu:AddCriteria' => 'Add new criteria',
// - Add new criteria button
'UI:Search:AddCriteria:List:RecentlyUsed:Title' => 'Recently used',
'UI:Search:AddCriteria:List:MostPopular:Title' => 'Most popular',
'UI:Search:AddCriteria:List:Others:Title' => 'Others',
// - Criteria operators
// - Default widget
'UI:Search:Criteria:Operator:Default:Empty' => 'Is empty',
@@ -1438,7 +1443,8 @@ When associated with a trigger, each action is given an "order" number, specifyi
'UI:Search:Criteria:Title:Enum:In' => '%1$s: %2$s',
'UI:Search:Criteria:Title:Enum:In:Many' => '%1$s: %2$s and %3$s others',
'UI:Search:Criteria:Title:Enum:In:All' => '%1$s: Any',
// -
// - Other translations
'UI:Search:Value:Filter:Placeholder' => 'Filter...',
'UI:Search:Value:Toggler:CheckAllNone' => 'Check all / none',

View File

@@ -95,8 +95,8 @@ $(function()
// - Filter
var sFilterId = 'filter_' + sOpId;
var oFilterElem = $('<div class="sfc_opc_mc_filter"></div>')
.append('<input type="text" id="' + sFilterId + '" placeholder="' + Dict.S('UI:Search:Value:Filter:Placeholder') + '" /><span class="sfc_opc_mcf_picto sfc_opc_mcf_filter fa fa-filter"></span><span class="sfc_opc_mcf_picto sfc_opc_mcf_reset fa fa-times"></span>')
var oFilterElem = $('<div class="sf_filter"></div>')
.append('<input type="text" id="' + sFilterId + '" placeholder="' + Dict.S('UI:Search:Value:Filter:Placeholder') + '" /><span class="sff_picto sff_filter fa fa-filter"></span><span class="sff_picto sff_reset fa fa-times"></span>')
.appendTo(oOpContentElem);
// - Allowed values
@@ -108,11 +108,12 @@ $(function()
// - It is not give by neither the autocomplete or the pre-filled values, so we would need to manually add it in both cases, all operations.
if(this.options.field.is_null_allowed === true)
{
var sItemId = 'value_' + sOpId + '_null';
var sValCode = this.options.null_value.code;
var sValLabel = this.options.null_value.label;
var oValueElem = $('<div class="sfc_opc_mc_item" data-value-code="' + sValCode + '"></div>')
.append('<label for="' + sItemId + '"><input type="checkbox" id="' + sItemId + '" value="' + sValCode + '"/>' + sValLabel + '</label>')
var oValueElem = $('<div></div>')
.addClass('sfc_opc_mc_item')
.attr('data-value-code', sValCode)
.append('<label><input type="checkbox" value="' + sValCode + '"/>' + sValLabel + '</label>')
.appendTo(oAllowedValuesElem);
}
@@ -120,23 +121,20 @@ $(function()
if(this.options.field.allowed_values.values !== undefined)
{
var aSortedValues = this._sortValuesByLabel(this.options.field.allowed_values.values);
var iValCounter = 0;
for(var i in aSortedValues)
{
var sItemId = 'value_' + sOpId + '_' + iValCounter;
var sValCode = aSortedValues[i][0];
var sValLabel = aSortedValues[i][1];
var oValueElem = $('<div class="sfc_opc_mc_item" data-value-code="' + sValCode + '"></div>')
.append('<label for="' + sItemId + '"><input type="checkbox" id="' + sItemId + '" value="' + sValCode + '"/>' + sValLabel + '</label>')
var oValueElem = $('<div></div>')
.addClass('sfc_opc_mc_item')
.attr('data-value-code', sValCode)
.append('<label><input type="checkbox" value="' + sValCode + '"/>' + sValLabel + '</label>')
.appendTo(oAllowedValuesElem);
if(this._isSelectedValues(sValCode))
{
oValueElem.find(':checkbox').prop('checked', true);
}
iValCounter++;
}
}
oAllowedValuesElem.appendTo(oOpContentElem);
@@ -162,8 +160,8 @@ $(function()
if(sFilter === '')
{
oOpContentElem.find('.sfc_opc_mc_item').show();
oFilterElem.find('.sfc_opc_mcf_filter').show();
oFilterElem.find('.sfc_opc_mcf_reset').hide();
oFilterElem.find('.sff_filter').show();
oFilterElem.find('.sff_reset').hide();
}
else
{
@@ -181,14 +179,14 @@ $(function()
$(this).hide();
}
});
oFilterElem.find('.sfc_opc_mcf_filter').hide();
oFilterElem.find('.sfc_opc_mcf_reset').show();
oFilterElem.find('.sff_filter').hide();
oFilterElem.find('.sff_reset').show();
}
});
oFilterElem.find('.sfc_opc_mcf_filter').on('click', function(){
oFilterElem.find('.sff_filter').on('click', function(){
oFilterElem.find('input').trigger('focus');
});
oFilterElem.find('.sfc_opc_mcf_reset').on('click', function(){
oFilterElem.find('.sff_reset').on('click', function(){
oFilterElem.find('input')
.val('')
.trigger('focus');

View File

@@ -11,6 +11,7 @@ $(function()
{
// Null value
'null_value': {
'code': 0,
'label': Dict.S('UI:UndefinedObject'),
}
},

View File

@@ -298,36 +298,57 @@ $(function()
var oContentElem = $('<div class="sfm_content"></div>')
.appendTo(this.elements.more_criterion);
// - Add list
var oListElem = $('<ul class="sfm_list"></ul>')
// - Filter
var oFilterElem = $('<div class="sf_filter"></div>')
.append('<input type="text" placeholder="' + Dict.S('UI:Search:Value:Filter:Placeholder') + '" /><span class="sff_picto sff_filter fa fa-filter"></span><span class="sff_picto sff_reset fa fa-times"></span>')
.appendTo(oContentElem);
// - Add fields
// TODO: Find a widget to handle dropdown menu
// - From "search" zlist
// - Add fields from zlist list
var oZlistElem = $('<div></div>')
.addClass('sf_list')
.addClass('sf_list_zlist')
.appendTo(oContentElem);
$('<div class="sfl_title"></div>')
.text(Dict.S('UI:Search:AddCriteria:List:MostPopular:Title'))
.appendTo(oZlistElem);
var oZListItemsElem = $('<ul class="sfl_items"></ul>')
.appendTo(oZlistElem);
for(var sFieldRef in this.options.search.fields.zlist)
{
var oField = this.options.search.fields.zlist[sFieldRef];
var oFieldElem = $('<li></li>')
.addClass('sfm_field')
.attr('data-field-ref', sFieldRef)
.text(oField.label);
oListElem.append(oFieldElem);
.append('<label><input type="checkbox" value="' + sFieldRef + '" />' + oField.label + '</label>')
.appendTo(oZListItemsElem);
}
// - Others
// - Add fields remaining
if(this.options.search.fields.others !== undefined)
{
oListElem.append('<li>==================</li>');
oListElem.append('<li>|| TODO: Better separation ||</li>');
oListElem.append('<li>==================</li>');
var oOthersElem = $('<div></div>')
.addClass('sf_list')
.addClass('sf_list_others')
.appendTo(oContentElem);
$('<div class="sfl_title"></div>')
.text(Dict.S('UI:Search:AddCriteria:List:Others:Title'))
.appendTo(oOthersElem);
var oOthersItemsElem = $('<ul class="sfl_items"></ul>')
.appendTo(oOthersElem);
for(var sFieldRef in this.options.search.fields.others)
{
var oField = this.options.search.fields.others[sFieldRef];
var oFieldElem = $('<li></li>')
.addClass('sfm_field')
.attr('data-field-ref', sFieldRef)
.text(oField.label);
oListElem.append(oFieldElem);
.append('<label><input type="checkbox" value="' + sFieldRef + '" />' + oField.label + '</label>')
.appendTo(oOthersItemsElem);
}
}
@@ -347,10 +368,11 @@ $(function()
}
else
{
//if using the datetimepicker, do not close anything
// TODO: Try to put this back in the date widget as it introduced a non necessary coupling.
// If using the datetimepicker, do not close anything
if (oEventTargetElem.closest('#ui-datepicker-div, .ui-datepicker-prev, .ui-datepicker-next').length > 0 )
{
//no closing in this case
// No closing in this case
}
// //if the context is not document, then we have encountered a bug : the css ::after elements do have a context on click and thus, we cannot check if they are inside a #ui-datepicker-div
// else if (typeof oEventTargetElem.context != 'undefined' && $(oEventTargetElem.context).is('.ui-icon'))
@@ -377,6 +399,47 @@ $(function()
me._toggleMoreCriterion();
});
// - Filter
// Note: "keyup" event is use instead of "keydown", otherwise, the inpu value would not be set yet.
oFilterElem.find('input').on('keyup focus', function(oEvent){
// TODO: Move on values with up and down arrow keys; select with space or enter.
var sFilter = $(this).val();
if(sFilter === '')
{
oContentElem.find('.sfl_items > li').show();
oFilterElem.find('.sff_filter').show();
oFilterElem.find('.sff_reset').hide();
}
else
{
oContentElem.find('.sfl_items > li').each(function(){
var oRegExp = new RegExp(sFilter, 'ig');
var sValue = $(this).find('input').val();
var sLabel = $(this).text();
if( (sValue.match(oRegExp) !== null) || (sLabel.match(oRegExp) !== null) )
{
$(this).show();
}
else
{
$(this).hide();
}
});
oFilterElem.find('.sff_filter').hide();
oFilterElem.find('.sff_reset').show();
}
});
oFilterElem.find('.sff_filter').on('click', function(){
oFilterElem.find('input').trigger('focus');
});
oFilterElem.find('.sff_reset').on('click', function(){
oFilterElem.find('input')
.val('')
.trigger('focus');
});
// - Add criteria
this.elements.more_criterion.find('.sfm_field').on('click', function(oEvent){
// Prevent anchor