Поддержка Проблемы и решения Select в виде аккордеона

  • Помогите с решением такого вопроса. Есть ли способы,чтобы сделать select в виде аккордеона? На сайте есть очень много категорий и подкатегорий. Для пользователя выбор категории осуществлён с помощью выпадающего списка <select></select>.
    В файле функций есть функция, которая создаёт таксономию для select-а из массива категорий. Вот эта функция:

    /*
    * Display category hierarchy in select category dropdown on advert form
    */
    if( !function_exists('addifier_hierarchy_select_taxonomy') ){
    function addifier_hierarchy_select_taxonomy( $terms, $depth = 0, $selected = array(), $allow_parent = false ){
    	foreach( $terms as $term ){
    		if( !empty( $term->children ) && !$allow_parent ){
    			echo '<optgroup label="'.str_repeat('&nbsp;', $depth).$term->name.'">';
    				addifier_hierarchy_select_taxonomy( $term->children, $depth + 2, $selected );
    			echo '</optgroup>';
    		}
    		else{
    			echo '<option value="'.esc_attr( $term->term_id ).'" '.( in_array( trim( $term->term_id ), $selected ) ? 'selected="selected"' : '' ).'>'.str_repeat('&nbsp;', $depth).$term->name.'</option>';
    		}
    
    		if( !empty( $term->children ) && $allow_parent ){
    			addifier_hierarchy_select_taxonomy( $term->children, $depth + 2, $selected, true );
    		}
    	}
    }
    }

    Далее, в файле, который управляет формами, есть код, который добавляет форму выбора категорий и в этом коде используется предыдущая функция. Вот код формы:

    <div class="white-block white-block-extra-padding">
    						<div class="white-block-title">
    							<h5><?php esc_html_e( 'Категории объявления', 'adifier' ) ?></h5>
    						</div>
    						<div class="white-block-content">
    							<?php
    							$categories = adifier_get_taxonomy_hierarchy( 'advert-category' );
    							if( !empty( $categories ) ){
    								?>
    								<div class="form-group no-margin">
    									<label for="category"><?php esc_html_e( 'Категория *', 'adifier' ) ?></label>
    									<select name="category" id="category" class="select2-enabled">
    										<option value=""><?php esc_html_e( '- Выбрать -', 'adifier' ) ?></option>
    										<?php
    										if( !empty($categories) ){
    											addifier_hierarchy_select_taxonomy( $categories, 0, $category_ids );
    										}
    										?>
    									</select>
    								</div>						
    								<?php
    							}
    							?>
    							<div class="category-custom-fields form-group no-margin">
    								<?php
    								if( !empty( $category_ids ) ){
    									Adifier_Custom_Fields_Advert::get_cf( $category_ids, $id );
    								}
    								?>
    							</div>						
    						</div>
    					</div>

    В функции родительские категории добавляются в optgroups, а дочерние в options.
    Даже если придумать код для свёртывания optgroups, я знаю, что optgroups нельзя выбрать, кликать по ним.
    Если в функции везде заменить значение $allow_parent на true, в форме все найденные категории будут в виде options и тогда родительские категории доступны для выбора.
    Multiple для select не тоже не вариант.
    После кучи всего вышесказанного, поясню. Заменять select, допустим, на ul li или что-то другое, затруднительно. Код в файлах заточен под select (css тоже). Нужно, чтобы optgroups можно было свернуть и развернуть. Так как категорий и подкатегорий очень много и пользователю будет очень трудно найти нужную категорию, и также будет трудно сразу определить к какому «родителю» она относится. То есть, нужно сделать оптгруппы и опции выпадающего списка в виде аккордеона.
    В PHP и JS не силён. Помогите разрешить эту ситуацию.
    Заранее большое спасибо!

Просмотр 1 ответа (всего 1)
  • Я нашёл способ заменить select на список из ul li в виде аккордеона. Функцию я переделал на вот такую:

    /*
    * Display category hierarchy in select category dropdown on advert form
    */
    if( !function_exists('addifier_hierarchy_select_taxonomy') ){
    function addifier_hierarchy_select_taxonomy( $terms, $depth = 0, $selected = array(), $allow_parent = false ){
    	foreach( $terms as $term ){
    		if( !empty( $term->children ) && !$allow_parent ){
    			echo '<li><a href="#">'.str_repeat('&nbsp;', $depth).$term->name.'</a><ul>';
    				addifier_hierarchy_select_taxonomy( $term->children, $depth + 2, $selected );
    			echo '</ul></li>';
    		}
    		else{
    			echo '<li><a href="#" onclick="post" id="category" value="'.esc_attr( $term->term_id ).'" '.( in_array( trim( $term->term_id ), $selected ) ? 'selected="selected"' : '' ).'>'.str_repeat('&nbsp;', $depth).$term->name.'</a></li>';
    		}
    
    		if( !empty( $term->children ) && $allow_parent ){
    			addifier_hierarchy_select_taxonomy( $term->children, $depth + 2, $selected, true );
    		}
    	}
    }
    }

    В php файле для формы код переделал на этот:

    <div class="white-block white-block-extra-padding">
    		<div class="white-block-title">
    			<h5><?php esc_html_e( 'Ad Category', 'adifier' ) ?></h5>
    		</div>
    		<div class="white-block-content">
    						
    			<?php
    			$categories = adifier_get_taxonomy_hierarchy( 'advert-category' );
    			if( !empty( $categories ) ){
    				?>
    				<div class="form-group no-margin">
    				<div id="wrapper">
    						
    					<label for="category"><?php esc_html_e( 'Category *', 'adifier' ) ?></label>
    					<ul class="menu">
    						<?php
    						if( !empty($categories) ){
    							addifier_hierarchy_select_taxonomy( $categories, 0, $category_ids );
    						}
    						?>
    					</ul>
    		                </div>
    				</div>						
    				<?php
    			}
    			?>
    			<div class="category-custom-fields form-group no-margin">
    				<?php
    				if( !empty( $category_ids ) ){
    					Adifier_Custom_Fields_Advert::get_cf( $category_ids, $id );
    				}
    				?>
    			</div>	
    						
    		</div>
    	</div>

    В старом коде, после выбора одного из option, ниже формы выбора категорий должны появляться пользовательские поля, которые различаются в зависимости от выбранного option. Проще говоря, каждой дочерней категории соответствуют свои пользовательские поля.
    В этом случае возникла другая проблема. Теперь они не выводятся.
    Есть ещё 2 файла — profile.js и custom-fields-advert.class.php
    В этих файлах есть код, связанный с выводом пользовательских полей. Ниже покажу нужные части кода из этих файлов.

    profile.js:

    /* MY ACCOUNT CF */
    	var $cFieldsWrapper = $('.category-custom-fields');
    	if( $cFieldsWrapper.length > 0 ){
    		$('.cf-field').adifierCustomFields();
    		$('#category').on('change', function(){
    			var $this = $(this);
    			var $label = $this.parents('.form-group').find('label');
    			$label.prepend('<i class="aficon-spin aficon-circle-notch" style="margin-'+( $('body').hasClass('rtl') ? 'left' : 'right' )+':2px;"></i>');
    			$cFieldsWrapper.html( '' );
    			$this.prop( 'disabled', true );
    			$.ajax({
    				url: adifier_data.ajaxurl,
    				method: 'POST',
    				data: {
    					action: 'adifier_get_cf',
    					terms: [$(this).val()],
    					post_id: $('input[name="advert_id"]').val()
    				},
    				success: function(response){
    					$cFieldsWrapper.html( response );
    					$('.cf-field').adifierCustomFields();
    					$this.prop( 'disabled', false );
    					$cFieldsWrapper.find( ".select2-multiple").select2();
    					$cFieldsWrapper.find( ".select2-single").select2();
    				},
    				complete: function(){
    					$label.find('i').remove();
    				}
    			});
    		});
    	}

    custom-fields-advert.class.php:

    class Adifier_Custom_Fields_Advert{
    
    	public static function launch(){
    		add_action( 'adifier_amb_action', 'Adifier_Custom_Fields_Advert::cf_meta_box' );
    		add_action( 'wp_ajax_adifier_get_cf', 'Adifier_Custom_Fields_Advert::get_cf' );
    		add_action( 'wp_ajax_adifier_get_subfield', 'Adifier_Custom_Fields_Advert::get_subfield' );
    		add_action( 'save_post_advert', 'Adifier_Custom_Fields_Advert::save_post', 10, 2 );
    	}
    
    	/*
    	* Add fields on the project edit page
    	*/
    	public static function cf_meta_box(){
    		adifier_amb(
    			'adifier_advert_custom_fields',
    			esc_html__( 'Additional Information', 'adifier' ),
    			'Adifier_Custom_Fields_Advert::advert_custom_fields',
    			'advert'
    		);
    	}
    
    	/*
    	* Print div wrapper for fields on advert edit page
    	*/
    	public static function advert_custom_fields(){
    		?>
    		<div class="adifier-advert-custom-fields">
    			<?php self::no_custom_fields() ?>
    		</div>
    		<?php
    	}
    
    	private static function no_custom_fields(){
    		?>
    		<div class="no-custom-fields">
    			<?php esc_html_e( 'Select categories to show custom fields', 'adifier' ); ?>
    		</div>
    		<?php
    	}
    
           /*
    	* Fetch custom fields (Выбрать пользовательские поля)
    	*/
    	public static function get_cf( $terms = array(), $post_id = 0 ){
    		global $wpdb;
    		$terms = !empty( $_POST['terms'] ) ? $_POST['terms'] : $terms;
    		$post_id = !empty( $_POST['post_id'] ) ? $_POST['post_id'] : $post_id;
    		if( !empty( $terms ) ){
    			$fields = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}adifier_cf AS cf LEFT JOIN {$wpdb->prefix}adifier_cf_groups AS cf_groups ON cf.group_id = cf_groups.group_id WHERE CONCAT( ',', categories, ',' ) REGEXP ',(".esc_sql( implode('|', $terms) )."),' ORDER BY cf_order ASC");
    			if( !empty( $fields ) ){
    				foreach( $fields as $field ){
    					$selected_terms = wp_get_object_terms( $post_id, $field->cf_slug );
    					self::generate_field( $field, $selected_terms );
    				}
    			}
    		}
    		else{
    			self::no_custom_fields();
    		}
    		
    		if( isset( $_POST['post_id'] ) || isset( $_POST['terms'] ) ){
    			die();
    		}
    	}

    В файле profile.js в строчке $('#category').on('change', function() я заменил на change на click, а в функции в тег li добавил [HTML]id=»category»[/HTML], чтобы клик срабатывал только на ссылках для дочерних категорий.

    Проблема в том, что при клике пользовательские поля не появляются и выходит надпись, что надо выбрать категории. Эта надпись вылазит вроде из-за этого кода:

    private static function no_custom_fields(){
    		?>
    		<div class="no-custom-fields">
    			<?php esc_html_e( 'Select categories to show custom fields', 'adifier' ); ?>
    		</div>
    		<?php
    	}

    Как уже говорил, в php и js я не силён. Я так понял, что это связано с действием adifier_get_cf и что POST подходит для select, а не для ссылок и списков.

    Помогите разобраться, почему не выводятся пользовательские поля при нажатии по ссылке. Может быть это связано с POTS, отсутствием name (он был в select), неправильно построенной формой выбора категории или ещё с чем-то. Если код в последних двух файлах не совсем ясен, я могу закинуть их сюда целиком.
    Заранее большое спасибо.

    • Ответ изменён 8 месяцев, 2 недели назад пользователем dmitriy85.
Просмотр 1 ответа (всего 1)
  • Тема «Select в виде аккордеона» закрыта для новых ответов.