Make WordPress Core

Changeset 27650


Ignore:
Timestamp:
03/21/2014 09:12:32 PM (12 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.