From 5b055bdf5bc5bb2127097006d8e5b63c85676bbe Mon Sep 17 00:00:00 2001 From: pginer Date: Wed, 25 Jul 2012 16:00:05 +0200 Subject: [PATCH] (bug 38670) Provide a no results found view Provide a view showing: - A feedback message where the current search term is displayed. - Suggested options: based on likely languages and languages with one additional level of editing distance than the used in the search algorithm. - Instructions for search and browse including links to all the sub-regions available. * Introduced success, noresults callbacks for language and region filters * Region filter can be a link for a region alone. Change-Id: I713b62911bb32e1b1427320ced767b144180c5c4 --- UniversalLanguageSelector.hooks.php | 16 +++++++ examples/index.html | 17 ++++++- examples/resources/demo.css | 2 +- resources/css/ext.uls.css | 8 ++++ resources/css/ext.uls.lcd.css | 20 ++++++--- resources/ext.uls.core.js | 33 ++++++++++---- resources/ext.uls.languagefilter.js | 69 +++++++++++++++++++++-------- 7 files changed, 131 insertions(+), 34 deletions(-) diff --git a/UniversalLanguageSelector.hooks.php b/UniversalLanguageSelector.hooks.php index 506371b4..a61cfba2 100644 --- a/UniversalLanguageSelector.hooks.php +++ b/UniversalLanguageSelector.hooks.php @@ -113,6 +113,22 @@ class UniversalLanguageSelectorHooks {
+
+

No results found for \"\"

+
+
+

You can search by language name, script name, ISO code of language or you can browse by region: + America, + Europe, + Middle East, + Africa, + Asia, + Pacific or + Worldwide languages. +

+
+
+
"; return true; } diff --git a/examples/index.html b/examples/index.html index 544c3723..52c9c761 100644 --- a/examples/index.html +++ b/examples/index.html @@ -101,8 +101,23 @@
+
+

No results found for "Esapnol"

+
+
+

You can search by language name, script name, ISO code of language or you can browse by region: + America, + Europe, + Middle East, + Africa, + Asia, + Pacific or + Worldwide languages. +

+
+
+
- diff --git a/examples/resources/demo.css b/examples/resources/demo.css index c20ab58e..f1350578 100644 --- a/examples/resources/demo.css +++ b/examples/resources/demo.css @@ -17,4 +17,4 @@ span.uls-trigger { span.uls-trigger a { color: #FFFFFF; font-weight: bold; -} +} \ No newline at end of file diff --git a/resources/css/ext.uls.css b/resources/css/ext.uls.css index 02188e1f..dc2dce37 100644 --- a/resources/css/ext.uls.css +++ b/resources/css/ext.uls.css @@ -42,10 +42,18 @@ padding-left: 15px; color: #777; } +.uls-menu h2 { + padding-left: 6px; + margin-top: 0px; + margin-bottom: 15px; + border-bottom: none; + color: #777; +} .uls-menu h3 { padding-left: 0px; margin-top: 0px; margin-bottom: 15px; + border-bottom: none; } .uls-worldmap { /* @embed */ diff --git a/resources/css/ext.uls.lcd.css b/resources/css/ext.uls.lcd.css index d27cb612..74e02c31 100644 --- a/resources/css/ext.uls.lcd.css +++ b/resources/css/ext.uls.lcd.css @@ -34,15 +34,25 @@ .uls-language-block .three.columns { width: 22%; - } .uls-language-list-footer .three.columns { width: 22%; - } - -.uls-language-block{ - width:100%; +.uls-language-block { + width: 100%; +} + +.uls-no-results-view { + color: #777; +} + +#uls-no-found-more { + font-size: 0.9em; + background: #F8F8F8; + display: inline-block; + width: 100%; + margin-top: 1.6em; + line-height: 1.6em; } diff --git a/resources/ext.uls.core.js b/resources/ext.uls.core.js index 4c02ef28..a07604a6 100644 --- a/resources/ext.uls.core.js +++ b/resources/ext.uls.core.js @@ -33,6 +33,9 @@ } this.shown = false; this.$languageFilter = $( 'input#languagefilter' ); + this.$noResultsView = $( 'div.uls-no-results-view' ); + this.$resultsView = $( 'div.uls-language-list' ); + this.$noResultsView.hide(); this.render(); this.listen(); this.ready(); @@ -70,8 +73,20 @@ // Rendering stuff here }, + noresults: function( search ) { + this.$noResultsView.show(); + // FIXME i18n + this.$noResultsView.find( 'span#uls-no-found-search-term' ).text( search ); + this.$resultsView.hide(); + }, + + success: function() { + this.$noResultsView.hide(); + this.$resultsView.show(); + }, + listen: function() { - var that = this, $lcd; + var that = this, lcd; // Register all event listeners to the ULS here. that.$element.on( 'click', $.proxy( that.click, that ) ); @@ -85,7 +100,7 @@ this.$menu.on( 'keydown', $.proxy( this.keypress, this ) ) } - $lcd = $( 'div.uls-language-list' ).lcd( { + lcd = that.$resultsView.lcd( { languages: that.languages, clickhandler: function( langCode ) { if ( that.options.onSelect ) { @@ -95,19 +110,21 @@ } ).data( "lcd" ); that.$languageFilter.languagefilter( { - $target: $lcd, //$( 'ul.uls-language-filter-result' ), + $target: lcd, languages: that.languages, + success: $.proxy( that.success, that ), + noresults: $.proxy( that.noresults, that ), searchAPI: that.options.searchAPI } ); // Create region selectors, one per region - $( '.uls-region' ).regionselector( { - $target: $lcd, - // FIXME This is confusing: languages and source are actually data for ULS. + $( '.uls-region, .uls-region-link' ).regionselector( { + $target: lcd, languages: that.languages, - callback: function () { + success: function() { // clear the search field. - that.$languageFilter.val( "" ); + that.$languageFilter.val( '' ); + that.success(); } } ); diff --git a/resources/ext.uls.languagefilter.js b/resources/ext.uls.languagefilter.js index b1b354b4..82e0fd28 100644 --- a/resources/ext.uls.languagefilter.js +++ b/resources/ext.uls.languagefilter.js @@ -30,6 +30,7 @@ this.$element = $( element ); this.options = $.extend( {}, $.fn.regionselector.defaults, options ); this.$element.addClass( 'languagefilter' ); + this.resultCount = 0; this.listen(); }; @@ -51,17 +52,21 @@ var query = $.trim( this.$element.val() ), languages = $.uls.data.languagesByScriptGroup( this.options.languages ), scriptGroup, langNum, langCode; + this.resultCount = 0; for ( scriptGroup in languages ) { for ( langNum = 0; langNum < languages[scriptGroup].length; langNum++ ) { langCode = languages[scriptGroup][langNum]; if ( query === "" || this.filter( langCode, query ) ) { this.render( langCode ); + this.resultCount++; } } } - // Also do a search to search API - if( this.options.searchAPI && query){ + // Also do a search by search API + if( this.options.searchAPI && query ) { this.searchAPI( query ); + } else { + this.resultHandler( query ); } }, @@ -70,10 +75,25 @@ $.get( that.options.searchAPI, { search: query }, function( result ) { $.each( result['languagesearch'], function( code, name ) { that.render( code, name ); + that.resultCount++; } ); + that.resultHandler( query ); } ); }, + /** + * Handler method to be called once search is over. + * Based on search result call success or noresults callbacks + * @param String query + */ + resultHandler: function( query ) { + if ( this.resultCount === 0 && this.options.noresults ) { + this.options.noresults.call( this, query ); + } else if ( this.options.success ) { + this.options.success( this, query, this.resultCount ); + } + }, + render: function( langCode, languageName ) { var $target = this.options.$target; if ( !$target ) { @@ -122,14 +142,15 @@ $.fn.languagefilter.defaults = { $target: null, // Where to append the results - languages: null, // Languages as code:name format. Default values come from data.languages. - clickhandler: null, - searchAPI: null + searchAPI: null, + languages: null, // Languages as code:name format. + noresults: null, // callback for no results found case + success: null // callback if any results found. }; $.fn.languagefilter.Constructor = LanguageFilter; - /* RegionSelector Plugin Definition */ + /* RegionSelector plugin definition */ /** * Region selector is a language selector based on regions. @@ -141,19 +162,28 @@ this.$element = $( element ); this.options = $.extend( {}, $.fn.regionselector.defaults, options ); this.$element.addClass( 'regionselector' ); - this.listen(); + this.regions = []; this.regionGroup = this.$element.data( 'regiongroup' ); + this.init(); + this.listen(); }; RegionSelector.prototype = { constructor: RegionSelector, + init: function() { + var region = this.$element.data( 'region' ); + this.regions = $.uls.data.regionsInGroup( this.regionGroup ); + if ( region ) { + this.regions.push( region ); + } + }, + test: function( langCode ) { - var regions = $.uls.data.regionsInGroup( this.regionGroup ), - langRegions = $.uls.data.regions( langCode ), + var langRegions = $.uls.data.regions( langCode ), region; - for ( var i = 0; i < regions.length; i++ ) { - region = regions[i]; + for ( var i = 0; i < this.regions.length; i++ ) { + region = this.regions[i]; if ( $.inArray( region, langRegions ) >= 0 ) { this.render( langCode, region ); return; @@ -165,11 +195,12 @@ var i, regions, language, languagesByScriptGroup, scriptGroup, languages; // Make the selected region (and it only) active $( '.regionselector' ).removeClass( 'active' ); - this.$element.addClass( 'active' ); - + if( this.regionGroup ) { + // if there is a region group, make it active. + this.$element.addClass( 'active' ); + } // Re-populate the list of languages this.options.$target.empty(); - regions = $.uls.data.regionsInGroup( this.regionGroup ); languagesByScriptGroup = $.uls.data.languagesByScriptGroup( this.options.languages ); for ( scriptGroup in languagesByScriptGroup ) { languages = languagesByScriptGroup[scriptGroup]; @@ -179,8 +210,8 @@ } } - if ( this.options.callback ) { - this.options.callback.call(); + if ( this.options.success ) { + this.options.success.call(); } }, @@ -203,7 +234,7 @@ } }; - /* RegionSelector Plugin Definition */ + /* RegionSelector plugin definition */ $.fn.regionselector = function( option ) { return this.each( function() { @@ -221,8 +252,8 @@ }; $.fn.regionselector.defaults = { - $target: null, // Where to render the results. Must be a ul element - callback: null, // Callback - will be called after results are displayed. + $target: null, // Where to render the results + success: null, // callback if any results found. languages: null };