Custom search and filter for taxonomies in Admin Bar
Glossary overview

Custom search and filter for taxonomies in Admin Bar

Custom Filter on Post List page

add_action('restrict_manage_posts', function() {
	global $typenow;

	if ($typenow !== 'experience') return;

	$taxonomies = ['type', 'location-experience'];

	foreach ($taxonomies as $taxonomy) {
		$taxonomy_obj = get_taxonomy($taxonomy);
		if (!$taxonomy_obj) continue;

		$terms = get_terms([
			'taxonomy' => $taxonomy,
			'hide_empty' => false,
		]);

		if (!empty($terms) && !is_wp_error($terms)) {
			$selected = $_GET[$taxonomy] ?? '';
			echo '<select name="' . esc_attr($taxonomy) . '">';
			echo '<option value="">' . esc_html($taxonomy_obj->labels->all_items) . '</option>';
			foreach ($terms as $term) {
				printf(
					'<option value="%s"%s>%s</option>',
					esc_attr($term->slug),
					selected($selected, $term->slug, false),
					esc_html($term->name)
				);
			}
			echo '</select>';
		}
	}
});

Результат:

Поиск по термам

add_action('admin_footer', 'add_taxonomy_search_field_script');
function add_taxonomy_search_field_script() {
	if (!is_admin()) return;

	$screen = get_current_screen();

	if (
		!$screen ||
		$screen->base !== 'post' ||
		$screen->post_type !== 'experience'
	) {
		return;
	}
	?>
	<script>
		document.addEventListener('DOMContentLoaded', function () {
			try {
				const taxonomies = [
					{ containerId: 'type-all', checklistId: 'typechecklist', placeholder: 'Search type' },
					{ containerId: 'location-experience-all', checklistId: 'location-experiencechecklist', placeholder: 'Search location' },
					{ containerId: 'cuisine-all', checklistId: 'cuisinechecklist', placeholder: 'Search cuisine' }
				];

				taxonomies.forEach(tax => {
					const container = document.getElementById(tax.containerId);
					const checklist = document.getElementById(tax.checklistId);

					if (!container || !checklist) return;
					
					if (container.querySelector('input[data-tax-search="true"]')) return;

					const searchInput = document.createElement('input');
					searchInput.type = 'text';
					searchInput.placeholder = tax.placeholder;
					searchInput.dataset.taxSearch = 'true';
					searchInput.style.marginTop = '13px';
					searchInput.style.width = '100%';
					searchInput.style.boxSizing = 'border-box';

					container.insertBefore(searchInput, checklist);

					searchInput.addEventListener('input', function () {
						const filter = this.value.toLowerCase();
						const items = checklist.querySelectorAll('li');

						items.forEach(item => {
							const label = item.textContent.toLowerCase();
							item.style.display = label.includes(filter) ? '' : 'none';
						});
					});
				});
			} catch (error) {
				console.warn('Taxonomy filter script failed:', error);
			}
		});
	</script>
	<?php
}

Результат: