Make WordPress Core

Changeset 27650


Ignore:
Timestamp:
03/21/2014 09:12:32 PM (10 years ago)
Author:
ocean90
Message:

Widget Customizer: Improve widget search.

  • Removes jQuery.liveFilter dependency
  • Filters widget collection directly
  • Widget's name, ID and description will be searched

fixes #27451.

Location:
trunk/src/wp-admin
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-widgets.css

    r27468 r27650  
    388388    border-bottom: 1px solid #e4e4e4;
    389389    cursor: pointer;
     390    display: none;
    390391}
    391392
  • trunk/src/wp-admin/js/customize-widgets.js

    r27584 r27650  
    6262
    6363    WidgetCollection = self.WidgetCollection = Backbone.Collection.extend( {
    64         model: Widget
     64        model: Widget,
     65
     66        // Controls searching on the current widget collection
     67        // and triggers an update event
     68        doSearch: function( value ) {
     69
     70            // Don't do anything if we've already done this search
     71            // Useful because the search handler fires multiple times per keystroke
     72            if ( this.terms === value ) {
     73                return;
     74            }
     75
     76            // Updates terms with the value passed
     77            this.terms = value;
     78
     79            // If we have terms, run a search...
     80            if ( this.terms.length > 0 ) {
     81                this.search( this.terms );
     82            }
     83
     84            // If search is blank, show all themes
     85            // Useful for resetting the views when you clean the input
     86            if ( this.terms === '' ) {
     87                this.reset( WidgetCustomizer_exports.available_widgets );
     88            }
     89
     90            // Trigger an 'update' event
     91            this.trigger( 'update' );
     92        },
     93
     94        // Performs a search within the collection
     95        // @uses RegExp
     96        search: function( term ) {
     97            var match, results, haystack;
     98
     99            // Start with a full collection
     100            this.reset( WidgetCustomizer_exports.available_widgets, { silent: true } );
     101
     102            // Escape the term string for RegExp meta characters
     103            term = term.replace( /[-\/\\^$*+?.()|[\]{}]/g, '\\$&' );
     104
     105            // Consider spaces as word delimiters and match the whole string
     106            // so matching terms can be combined
     107            term = term.replace( / /g, ')(?=.*' );
     108            match = new RegExp( '^(?=.*' + term + ').+', 'i' );
     109
     110            results = this.filter( function( data ) {
     111                haystack = _.union( data.get( 'name' ), data.get( 'id' ), data.get( 'description' ) );
     112
     113                return match.test( haystack );
     114            });
     115
     116            this.reset( results );
     117        }
    65118    } );
    66119    self.available_widgets = new WidgetCollection( self.available_widgets );
     
    15531606         */
    15541607        setup: function () {
    1555             var panel = this, update_available_widgets_list;
     1608            var panel = this;
    15561609
    15571610            panel.container = $( '#available-widgets' );
    15581611            panel.filter_input = $( '#available-widgets-filter' ).find( 'input' );
    15591612
    1560             update_available_widgets_list = function () {
    1561                 self.available_widgets.each( function ( widget ) {
    1562                     var widget_tpl = $( '#widget-tpl-' + widget.id );
    1563                     widget_tpl.toggle( ! widget.get( 'is_disabled' ) );
    1564                     if ( widget.get( 'is_disabled' ) && widget_tpl.is( panel.selected_widget_tpl ) ) {
    1565                         panel.selected_widget_tpl = null;
    1566                     }
    1567                 } );
    1568             };
    1569 
    1570             self.available_widgets.on( 'change', update_available_widgets_list );
    1571             update_available_widgets_list();
     1613            self.available_widgets.on( 'change update', panel.update_available_widgets_list );
     1614            panel.update_available_widgets_list();
    15721615
    15731616            // If the available widgets panel is open and the customize controls are
     
    15971640            } );
    15981641
    1599             panel.container.liveFilter(
    1600                 '#available-widgets-filter input',
    1601                 '.widget-tpl',
    1602                 {
    1603                     filterChildSelector: '.widget-title h4',
    1604                     after: function () {
    1605                         var filter_val = panel.filter_input.val(),
    1606                             first_visible_widget;
    1607 
    1608                         // Remove a widget from being selected if it is no longer visible
    1609                         if ( panel.selected_widget_tpl && ! panel.selected_widget_tpl.is( ':visible' ) ) {
    1610                             panel.selected_widget_tpl.removeClass( 'selected' );
    1611                             panel.selected_widget_tpl = null;
    1612                         }
    1613 
    1614                         // If a widget was selected but the filter value has been cleared out, clear selection
    1615                         if ( panel.selected_widget_tpl && ! filter_val ) {
    1616                             panel.selected_widget_tpl.removeClass( 'selected' );
    1617                             panel.selected_widget_tpl = null;
    1618                         }
    1619 
    1620                         // If a filter has been entered and a widget hasn't been selected, select the first one shown
    1621                         if ( ! panel.selected_widget_tpl && filter_val ) {
    1622                             first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' );
    1623                             if ( first_visible_widget.length ) {
    1624                                 panel.select( first_visible_widget );
    1625                             }
    1626                         }
    1627 
     1642            panel.filter_input.on( 'input keyup change', function( event ) {
     1643                var first_visible_widget;
     1644
     1645                self.available_widgets.doSearch( event.target.value );
     1646
     1647                // Remove a widget from being selected if it is no longer visible
     1648                if ( panel.selected_widget_tpl && ! panel.selected_widget_tpl.is( ':visible' ) ) {
     1649                    panel.selected_widget_tpl.removeClass( 'selected' );
     1650                    panel.selected_widget_tpl = null;
     1651                }
     1652
     1653                // If a widget was selected but the filter value has been cleared out, clear selection
     1654                if ( panel.selected_widget_tpl && ! event.target.value ) {
     1655                    panel.selected_widget_tpl.removeClass( 'selected' );
     1656                    panel.selected_widget_tpl = null;
     1657                }
     1658
     1659                // If a filter has been entered and a widget hasn't been selected, select the first one shown
     1660                if ( ! panel.selected_widget_tpl &&  event.target.value ) {
     1661                    first_visible_widget = panel.container.find( '> .widget-tpl:visible:first' );
     1662                    if ( first_visible_widget.length ) {
     1663                        panel.select( first_visible_widget );
    16281664                    }
    16291665                }
    1630             );
     1666            } );
    16311667
    16321668            // Select a widget when it is focused on
     
    16821718
    16831719        /**
     1720         * Updates widgets list.
     1721         */
     1722        update_available_widgets_list: function() {
     1723            var panel = self.availableWidgetsPanel;
     1724
     1725            // First hide all widgets...
     1726            panel.container.find( '.widget-tpl' ).hide();
     1727
     1728            // ..and then show only available widgets which could be filtered
     1729            self.available_widgets.each( function ( widget ) {
     1730                var widget_tpl = $( '#widget-tpl-' + widget.id );
     1731                widget_tpl.toggle( ! widget.get( 'is_disabled' ) );
     1732                if ( widget.get( 'is_disabled' ) && widget_tpl.is( panel.selected_widget_tpl ) ) {
     1733                    panel.selected_widget_tpl = null;
     1734                }
     1735            } );
     1736        },
     1737
     1738        /**
    16841739         * @param widget_tpl
    16851740         */
     
    17261781            $( 'body' ).addClass( 'adding-widget' );
    17271782            panel.container.find( '.widget-tpl' ).removeClass( 'selected' );
     1783            self.available_widgets.doSearch( '' );
    17281784            panel.filter_input.focus();
    17291785        },
     
    17811837    return self;
    17821838}( jQuery ));
    1783 
    1784 /* @todo remove this dependency */
    1785 /*
    1786  * jQuery.liveFilter
    1787  *
    1788  * Copyright (c) 2009 Mike Merritt
    1789  *
    1790  * Forked by Lim Chee Aun (cheeaun.com)
    1791  *
    1792  */
    1793 
    1794 (function($){
    1795     $.fn.liveFilter = function(inputEl, filterEl, options){
    1796         var el, filter, defaults = {
    1797             filterChildSelector: null,
    1798             filter: function(el, val){
    1799                 return $(el).text().toUpperCase().indexOf(val.toUpperCase()) >= 0;
    1800             },
    1801             before: function(){},
    1802             after: function(){}
    1803         };
    1804         options = $.extend(defaults, options);
    1805 
    1806         el = $(this).find(filterEl);
    1807         if (options.filterChildSelector) {
    1808             el = el.find(options.filterChildSelector);
    1809         }
    1810 
    1811         filter = options.filter;
    1812         $(inputEl).keyup(function(){
    1813             var val = $(this).val(), contains, containsNot;
    1814 
    1815             contains = el.filter(function(){
    1816                 return filter(this, val);
    1817             });
    1818             containsNot = el.not(contains);
    1819             if (options.filterChildSelector){
    1820                 contains = contains.parents(filterEl);
    1821                 containsNot = containsNot.parents(filterEl).hide();
    1822             }
    1823 
    1824             options.before.call(this, contains, containsNot);
    1825 
    1826             contains.show();
    1827             containsNot.hide();
    1828 
    1829             if (val === '') {
    1830                 contains.show();
    1831                 containsNot.show();
    1832             }
    1833 
    1834             options.after.call(this, contains, containsNot);
    1835         });
    1836     };
    1837 })(jQuery);
Note: See TracChangeset for help on using the changeset viewer.