Persist search terms across grid/list modes:

* In `grid` mode, when the page loads and `s` is in the URL, all attachments are loaded and then the search value is set, which will filter the attachments. If the page loads with the attachments already filtered, the library will have to be requery'd to get the full set, which will require weirder code.
* When a user searches, the mode-switcher link for `list` view is updated dynamically to represent the current `location.href` in the proper `mode=` and `s=` context.

Fixes #30583.


git-svn-id: https://develop.svn.wordpress.org/trunk@31562 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Scott Taylor 2015-02-26 23:00:20 +00:00
parent 2f86fcd9a9
commit 41f89a3c14
3 changed files with 68 additions and 14 deletions

View File

@ -25,7 +25,10 @@ if ( 'grid' === $mode ) {
wp_enqueue_script( 'media-grid' ); wp_enqueue_script( 'media-grid' );
wp_enqueue_script( 'media' ); wp_enqueue_script( 'media' );
$vars = wp_edit_attachments_query_vars(); $q = $_GET;
// let JS handle this
unset( $q['s'] );
$vars = wp_edit_attachments_query_vars( $q );
$ignore = array( 'mode', 'post_type', 'post_status', 'posts_per_page' ); $ignore = array( 'mode', 'post_type', 'post_status', 'posts_per_page' );
foreach ( $vars as $key => $value ) { foreach ( $vars as $key => $value ) {
if ( ! $value || in_array( $key, $ignore ) ) { if ( ! $value || in_array( $key, $ignore ) ) {
@ -67,7 +70,7 @@ if ( 'grid' === $mode ) {
require_once( ABSPATH . 'wp-admin/admin-header.php' ); require_once( ABSPATH . 'wp-admin/admin-header.php' );
?> ?>
<div class="wrap" id="wp-media-grid"> <div class="wrap" id="wp-media-grid" data-search="<?php _admin_search_query() ?>">
<h2> <h2>
<?php <?php
echo esc_html( $title ); echo esc_html( $title );

View File

@ -682,15 +682,42 @@ Manage = MediaFrame.extend({
this.createStates(); this.createStates();
this.bindRegionModeHandlers(); this.bindRegionModeHandlers();
this.render(); this.render();
this.bindSearchHandler();
},
/**
* The views must interact with form controls that are not part of a frame
*/
bindSearchHandler: function() {
var search = this.$( '#media-search-input' ),
currentSearch = this.options.container.data( 'search' ),
searchView = this.browserView.toolbar.get( 'search' ).$el,
listMode = this.$( '.view-list' ),
input = _.debounce( function (e) {
var val = $( e.currentTarget ).val(),
url = '';
if ( val ) {
url += '?search=' + val;
}
this.gridRouter.navigate( this.gridRouter.baseUrl( url ) );
}, 1000 );
// Update the URL when entering search string (at most once per second) // Update the URL when entering search string (at most once per second)
$( '#media-search-input' ).on( 'input', _.debounce( function(e) { search.on( 'input', _.bind( input, this ) );
var val = $( e.currentTarget ).val(), url = ''; searchView.val( currentSearch ).trigger( 'input' );
if ( val ) {
url += '?search=' + val; this.gridRouter.on( 'route:search', function () {
var href = window.location.href;
if ( href.indexOf( 'mode=' ) > -1 ) {
href = href.replace( /mode=[^&]+/g, 'mode=list' );
} else {
href += href.indexOf( '?' ) > -1 ? '&mode=list' : '?mode=list';
} }
self.gridRouter.navigate( self.gridRouter.baseUrl( url ) ); href = href.replace( 'search=', 's=' );
}, 1000 ) ); listMode.prop( 'href', href );
} );
}, },
/** /**

View File

@ -83,15 +83,39 @@ Manage = MediaFrame.extend({
this.createStates(); this.createStates();
this.bindRegionModeHandlers(); this.bindRegionModeHandlers();
this.render(); this.render();
this.bindSearchHandler();
},
bindSearchHandler: function() {
var search = this.$( '#media-search-input' ),
currentSearch = this.options.container.data( 'search' ),
searchView = this.browserView.toolbar.get( 'search' ).$el,
listMode = this.$( '.view-list' ),
input = _.debounce( function (e) {
var val = $( e.currentTarget ).val(),
url = '';
if ( val ) {
url += '?search=' + val;
}
this.gridRouter.navigate( this.gridRouter.baseUrl( url ) );
}, 1000 );
// Update the URL when entering search string (at most once per second) // Update the URL when entering search string (at most once per second)
$( '#media-search-input' ).on( 'input', _.debounce( function(e) { search.on( 'input', _.bind( input, this ) );
var val = $( e.currentTarget ).val(), url = ''; searchView.val( currentSearch ).trigger( 'input' );
if ( val ) {
url += '?search=' + val; this.gridRouter.on( 'route:search', function () {
var href = window.location.href;
if ( href.indexOf( 'mode=' ) > -1 ) {
href = href.replace( /mode=[^&]+/g, 'mode=list' );
} else {
href += href.indexOf( '?' ) > -1 ? '&mode=list' : '?mode=list';
} }
self.gridRouter.navigate( self.gridRouter.baseUrl( url ) ); href = href.replace( 'search=', 's=' );
}, 1000 ) ); listMode.prop( 'href', href );
} );
}, },
/** /**