RCFilters UI: Select filter when searching and add it on 'enter'
authorMoriel Schottlender <moriel@gmail.com>
Wed, 1 Mar 2017 18:35:12 +0000 (10:35 -0800)
committerCatrope <roan@wikimedia.org>
Fri, 3 Mar 2017 19:40:45 +0000 (19:40 +0000)
Bug: T149435
Change-Id: Idc88cae9f5ee0a6128bd7936df02f102ff3b71fb

resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js

index 1df31a2..ec14aa6 100644 (file)
        };
 
        /**
-        * Update the state of a filter
+        * Update the selected state of a filter
         *
         * @param {string} filterName Filter name
-        * @param {boolean} isSelected Filter selected state
+        * @param {boolean} [isSelected] Filter selected state
         */
-       mw.rcfilters.Controller.prototype.updateFilter = function ( filterName, isSelected ) {
+       mw.rcfilters.Controller.prototype.toggleFilterSelect = function ( filterName, isSelected ) {
                var obj = {},
                        filterItem = this.filtersModel.getItemByName( filterName );
 
+               isSelected = isSelected === undefined ? !filterItem.isSelected() : isSelected;
+
                if ( filterItem.isSelected() !== isSelected ) {
                        obj[ filterName ] = isSelected;
                        this.filtersModel.updateFilters( obj );
index 800e7ea..4a0e595 100644 (file)
                }
 
                // Respond to user removing the filter
-               this.controller.updateFilter( this.model.getName(), false );
+               this.controller.toggleFilterSelect( this.model.getName(), false );
                this.controller.clearHighlightColor( this.model.getName() );
        };
 
index 6aa514e..81b856d 100644 (file)
@@ -94,7 +94,7 @@
         * @param {boolean} isSelected The checkbox is selected
         */
        mw.rcfilters.ui.FilterItemWidget.prototype.onCheckboxChange = function ( isSelected ) {
-               this.controller.updateFilter( this.model.getName(), isSelected );
+               this.controller.toggleFilterSelect( this.model.getName(), isSelected );
        };
 
        /**
index 02ddb54..8afdc8a 100644 (file)
@@ -66,7 +66,8 @@
                        itemUpdate: 'onModelItemUpdate'
                } );
                this.textInput.connect( this, {
-                       change: 'onTextInputChange'
+                       change: 'onTextInputChange',
+                       enter: 'onTextInputEnter'
                } );
                this.capsule.connect( this, { capsuleItemClick: 'onCapsuleItemClick' } );
                this.capsule.popup.connect( this, { toggle: 'onCapsulePopupToggle' } );
         */
        mw.rcfilters.ui.FilterWrapperWidget.prototype.onCapsulePopupToggle = function ( isVisible ) {
                if ( !isVisible ) {
-                       this.filterPopup.resetSelection();
-                       this.capsule.resetSelection();
+                       if ( !this.textInput.getValue() ) {
+                               // Only reset selection if we are not filtering
+                               this.filterPopup.resetSelection();
+                               this.capsule.resetSelection();
+                       }
                } else {
                        this.scrollToTop( this.capsule.$element, 10 );
                }
         * @param {string} newValue Current value
         */
        mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputChange = function ( newValue ) {
-               this.filterPopup.resetSelection();
-
                // Filter the results
                this.filterPopup.filter( this.model.findMatches( newValue ) );
+
+               if ( !newValue ) {
+                       // If the value is empty, we didn't actually
+                       // filter anything. the filter method will run
+                       // and show all, but then will select the
+                       // top item - but in this case, no selection
+                       // should be made.
+                       this.filterPopup.resetSelection();
+               }
                this.capsule.popup.clip();
        };
 
+       /**
+        * Respond to text input enter event
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputEnter = function () {
+               var filter = this.filterPopup.getSelectedFilter();
+
+               // Toggle the filter
+               this.controller.toggleFilterSelect( filter );
+       };
+
        /**
         * Respond to model update event and set up the available filters to choose
         * from.
         * any actual interaction with the system resets the selection state of any item.
         */
        mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelItemUpdate = function () {
-               this.filterPopup.resetSelection();
+               if ( !this.textInput.getValue() ) {
+                       this.filterPopup.resetSelection();
+               }
        };
 
        /**
index 38679d7..8c730a2 100644 (file)
                return groupWidget.getItemWidget( itemName );
        };
 
+       /**
+        * Get the current selection
+        *
+        * @return {string|null} Selected filter. Null if none is selected.
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.getSelectedFilter = function () {
+               return this.selected;
+       };
+
        /**
         * Mark an item widget as selected
         *
         *  arranged by their group names
         */
        mw.rcfilters.ui.FiltersListWidget.prototype.filter = function ( groupItems ) {
-               var i, j, groupName, itemWidgets,
+               var i, j, groupName, itemWidgets, topItem, isVisible,
                        groupWidgets = this.getItems(),
                        hasItemWithName = function ( itemArr, name ) {
                                return !!itemArr.filter( function ( item ) {
                                } ).length;
                        };
 
+               this.resetSelection();
+
                if ( $.isEmptyObject( groupItems ) ) {
                        // No results. Hide everything, show only 'no results'
                        // message
                        // We have items to show
                        itemWidgets = groupWidgets[ i ].getItems();
                        for ( j = 0; j < itemWidgets.length; j++ ) {
+                               isVisible = hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() );
                                // Only show items that are in the filtered list
-                               itemWidgets[ j ].toggle(
-                                       hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() )
-                               );
+                               itemWidgets[ j ].toggle( isVisible );
+
+                               if ( !topItem && isVisible ) {
+                                       topItem = itemWidgets[ j ];
+                               }
                        }
                }
+
+               // Select the first item
+               if ( topItem ) {
+                       this.select( topItem.getName() );
+               }
        };
 }( mediaWiki, jQuery ) );