| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /** 2 * Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies. 3 * 4 * @output wp-admin/js/tags-suggest.js 5 * 6 * @param {JQueryStatic} $ The jQuery object. 7 */ 8 ( function( $ ) { 9 var tempID = 0; 10 var separator = wp.i18n._x( ',', 'tag delimiter' ) || ','; 11 var __ = wp.i18n.__, 12 _n = wp.i18n._n, 13 sprintf = wp.i18n.sprintf; 14 15 function split( val ) { 16 return val.split( new RegExp( separator + '\\s*' ) ); 17 } 18 19 function getLast( term ) { 20 return split( term ).pop(); 21 } 22 23 /** 24 * Add UI Autocomplete to an input or textarea element with presets for use 25 * with non-hierarchical taxonomies. 26 * 27 * Example: `$( element ).wpTagsSuggest( options )`. 28 * 29 * The taxonomy can be passed in a `data-wp-taxonomy` attribute on the element or 30 * can be in `options.taxonomy`. 31 * 32 * @since 4.7.0 33 * 34 * @param {Object} options Options that are passed to UI Autocomplete. Can be used to override the default settings. 35 * @return {Object} jQuery instance. 36 */ 37 $.fn.wpTagsSuggest = function( options ) { 38 var cache; 39 var last; 40 var $element = $( this ); 41 42 // Do not initialize if the element doesn't exist. 43 if ( ! $element.length ) { 44 return this; 45 } 46 47 options = options || {}; 48 49 var taxonomy = options.taxonomy || $element.attr( 'data-wp-taxonomy' ) || 'post_tag'; 50 51 delete( options.taxonomy ); 52 53 options = $.extend( { 54 source: function( request, response ) { 55 var term; 56 57 if ( last === request.term ) { 58 response( cache ); 59 return; 60 } 61 62 term = getLast( request.term ); 63 64 $.get( window.ajaxurl, { 65 action: 'ajax-tag-search', 66 tax: taxonomy, 67 q: term, 68 number: 20 69 } ).always( function() { 70 $element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes? 71 } ).done( function( data ) { 72 var tagName; 73 var tags = []; 74 75 if ( data ) { 76 data = data.split( '\n' ); 77 78 for ( tagName in data ) { 79 var id = ++tempID; 80 81 tags.push({ 82 id: id, 83 name: data[tagName] 84 }); 85 } 86 87 cache = tags; 88 response( tags ); 89 } else { 90 response( tags ); 91 } 92 } ); 93 94 last = request.term; 95 }, 96 focus: function( event, ui ) { 97 $element.attr( 'aria-activedescendant', 'wp-tags-autocomplete-' + ui.item.id ); 98 99 // Don't empty the input field when using the arrow keys 100 // to highlight items. See api.jqueryui.com/autocomplete/#event-focus 101 event.preventDefault(); 102 }, 103 select: function( event, ui ) { 104 var tags = split( $element.val() ); 105 // Remove the last user input. 106 tags.pop(); 107 // Append the new tag and an empty element to get one more separator at the end. 108 tags.push( ui.item.name, '' ); 109 110 $element.val( tags.join( separator + ' ' ) ); 111 112 if ( $.ui.keyCode.TAB === event.keyCode ) { 113 // Audible confirmation message when a tag has been selected. 114 window.wp.a11y.speak( wp.i18n.__( 'Term selected.' ), 'assertive' ); 115 event.preventDefault(); 116 } else if ( $.ui.keyCode.ENTER === event.keyCode ) { 117 // If we're in the edit post Tags meta box, add the tag. 118 if ( window.tagBox ) { 119 window.tagBox.userAction = 'add'; 120 window.tagBox.flushTags( $( this ).closest( '.tagsdiv' ) ); 121 } 122 123 // Do not close Quick Edit / Bulk Edit. 124 event.preventDefault(); 125 event.stopPropagation(); 126 } 127 128 return false; 129 }, 130 open: function() { 131 $element.attr( 'aria-expanded', 'true' ); 132 }, 133 close: function() { 134 $element.attr( 'aria-expanded', 'false' ); 135 }, 136 minLength: 2, 137 position: { 138 my: 'left top+2', 139 at: 'left bottom', 140 collision: 'none' 141 }, 142 messages: { 143 noResults: __( 'No results found.' ), 144 results: function( number ) { 145 return sprintf( 146 /* translators: %d: Number of search results found. */ 147 _n( 148 '%d result found. Use up and down arrow keys to navigate.', 149 '%d results found. Use up and down arrow keys to navigate.', 150 number 151 ), 152 number 153 ); 154 } 155 } 156 }, options ); 157 158 $element.on( 'keydown', function() { 159 $element.removeAttr( 'aria-activedescendant' ); 160 } ); 161 162 $element.autocomplete( options ); 163 164 // Ensure the autocomplete instance exists. 165 if ( ! $element.autocomplete( 'instance' ) ) { 166 return this; 167 } 168 169 $element.autocomplete( 'instance' )._renderItem = function( ul, item ) { 170 return $( '<li role="option" id="wp-tags-autocomplete-' + item.id + '">' ) 171 .text( item.name ) 172 .appendTo( ul ); 173 }; 174 175 $element.attr( { 176 'role': 'combobox', 177 'aria-autocomplete': 'list', 178 'aria-expanded': 'false', 179 'aria-owns': $element.autocomplete( 'widget' ).attr( 'id' ) 180 } ) 181 .on( 'focus', function() { 182 var inputValue = split( $element.val() ).pop(); 183 184 // Don't trigger a search if the field is empty. 185 // Also, avoids screen readers announce `No search results`. 186 if ( inputValue ) { 187 $element.autocomplete( 'search' ); 188 } 189 } ); 190 191 // Returns a jQuery object containing the menu element. 192 $element.autocomplete( 'widget' ) 193 .addClass( 'wp-tags-autocomplete' ) 194 .attr( 'role', 'listbox' ) 195 .removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI. 196 197 /* 198 * Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301. 199 * The `menufocus` and `menublur` events are the same events used to add and remove 200 * the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget. 201 */ 202 .on( 'menufocus', function( event, ui ) { 203 ui.item.attr( 'aria-selected', 'true' ); 204 }) 205 .on( 'menublur', function() { 206 // The `menublur` event returns an object where the item is `null`, 207 // so we need to find the active item with other means. 208 $( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' ); 209 }); 210 211 return this; 212 }; 213 214 }( jQuery ) );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Thu Sep 3 08:20:25 2026 | Cross-referenced by PHPXref |