как разделить данные по категориям в <select></select>

Ekaterina

Новичок
как разделить данные по категориям в <select></select>

Здравствуйте всем!
Дано:

Необходимо заполнить раскрывающийся список значениями из таблицы. Эти значения берутся из одного столбца таблицы , отличаются только типами: post и page.

Вопрос:
Как в раскрывающемся списке разделить их чертой, то есть чтобы сначала шли значения с post, затем разделительная черта , затем значения с page.

Пока есть скрипт, который выводит все подряд:
PHP:
<select name="list_page" width="200" tabindex="1">
   <? 
      global $wpdb;
   
      $sql = 'SELECT id, post_title FROM wp_posts WHERE post_type="post" OR post_type="page"';
      $res = $wpdb->get_results($sql, ARRAY_A) ; if (isset($res))
      
      foreach ($res as $name) {?>
         <option value=".<?echo $name['id'];?>."><? echo $name['post_title'];?></option>
      <?}?>   
    </select>
 

Фанат

oncle terrible
Команда форума
прописать в запросе сортировку, а внутри цикла - условие?
 

Ekaterina

Новичок
Почему то при таком запросе возвращаются в список только первые значения из групп page и post.
PHP:
$sql = 'SELECT id, post_title, post_type FROM wp_posts WHERE post_type="post" OR post_type="page" GROUP BY post_type ';
 

Ekaterina

Новичок
Спасибо, это я ступила. Теперь все работает как надо, правда, как-то очень громоздко, получается двойной перебор цикла из-за того, что надо отображать разделитель, поэтому возникли такие вопросы:
1. Может это можно как-то сократить.
3. Можно ли как-то менять длину разделителя динамически, в зависимости от длины самого длинного элемента списка.
PHP:
<select name="list_page" width="200" tabindex="1">
   <? 
      global $wpdb;
   
      $sql = 'SELECT id, post_title, post_type FROM wp_posts WHERE post_type="post" OR post_type="page" ORDER BY post_type';
      $res = $wpdb->get_results($sql, ARRAY_A) ; 
      //
      foreach ($res as $name) {
      	if ($name['post_type'] == 'page'){?>
      
            <option value=".<?echo $name['id'];?>."><? echo $name['post_title'];?></option>
         <?}
      }?>
      <option value="line"><? echo "---------------";?></option>
      <?foreach ($res as $name) {
      	if ($name['post_type'] == 'post'){?>
      
            <option value=".<?echo $name['id'];?>."><? echo $name['post_title'];?></option>
         <?}
      }?>
              
    </select>
 

Фанат

oncle terrible
Команда форума
1. Может это можно как-то сократить.
ну, если немного подумать, то условие можно поместить внутри цикла, а не снаружи.
Отслеживать, разумеется, изменение типа, запоминая предыдущий.
3. Можно ли как-то менять длину разделителя динамически,
никто не мешает прогнать $res в цикле и найти слово с максимальной длиной.
 

Ekaterina

Новичок
Автор оригинала: *****
ну, если немного подумать, то условие можно поместить внутри цикла, а не снаружи.
Отслеживать, разумеется, изменение типа, запоминая предыдущий.
Честно говоря, я не совсем понимаю, что Вы имеете ввиду. Ведь условие
PHP:
if ($name['post_type'] == 'page')
и так в цикле. Не могли бы Вы объяснить, если не трудно.
 

Фанат

oncle terrible
Команда форума
Сделать цикл, как было.
один, общий.

внутрь цикла поместить одно простое условие:
если тип поменялся и при этом был не пустой - вывести черточки.
 

Ekaterina

Новичок
Да, но черточки мне надо вывести один раз, а из за цикла они повторятся для каждого элемента из второй группы:
PHP:
<?foreach ($res as $name) {
      	if ($name['post_type'] != 'page'){?>
      
            <option value="line"><? echo "---------------";?></option>
         <?} ?>
            <option value=".<?echo $name['id'];?>."><? echo $name['post_title'];?></option>
            
      <?}?>
 

Фанат

oncle terrible
Команда форума
здесь проверка "если тип - не page"
а надо "если тип поменялся".
т.е. не равен предыдущему.
чтобы сравнить, надо этот предыдущий записывать
 

Ekaterina

Новичок
Спасибо огромное за терпение :), все получилось:
PHP:
foreach ($res as $name) {
      	
      	if ($type != $name['post_type'] && $type != "" ) { ?>
      	   <option value="line"><? for ($i=0; $i<$max; $i++) {echo "_";}?></option>  
      	<?}?>
      	<option value=".<?$name['id'];?>."><? echo $name['post_title'];?></option>
        <? $type = $name['post_type']; ?>
      
      <?}?>
Но еще возник вопрос: Сейчас у меня выбранным оказывается последний элемент списка. Правильно ли я рассуждаю, чтобы сделать выбранным первый элемент:
1. Создаем массив из id элементов, потому что это у меня имена <option>.
2. Сохранить в переменную первый элемент из этого массива.
3. Выводить
PHP:
<option <?$select?>>
4. Сравнивать все id c переменной = id первого элемента, и в зависимости от этого присваивать $select = selected либо $select = "";
 

Фанат

oncle terrible
Команда форума
примерно так, только никакой массив не нужен.
у нас как раз есть $type пустая :)
 

Ekaterina

Новичок
И в правду, $type же пустой, как все просто :).
Спасибо большое, еще раз, Вы мне очень помогли.
 

Ekaterina

Новичок
Возможно, я не совсем правильно выразилась: под категориями я имела ввиду группы записей, которые отличаются по типу и которые необходимо отделить чертой. Но спасибо за ссылку мне в дальнейшем это пригодиться.
 
Сверху