Данные типа select
(выбор данных из списка)

 

Несвязанные (независимые) выборные списки

Если вы хотите, чтобы при редактировании какого-то поля, можно было выбирать значения из фиксированного списка, то самый простой способ — это применить стандартные mysql-типы SET или ENUM, например:

.tdd
$types[2] = "set('красный', 'желтый', 'зеленый')";
Однако, этот список задается разработчиком, и пользователь не может его редактировать (если он не имеет доступ к файлу .tdd). Как быть, когда этот список должен часто изменяться? Например, на одной из страниц сайта вы ведете таблицу заказов, в одном из полей которого вы хотите иметь выпадающий список с названием региона (области, республики, края), из которого поступил заказ. Было бы разумнее иметь отдельный редактируемый блок с названиями регионов, чтобы редактор мог легко добавлять новые регионы. Для таких случаев используется тип select.

Как создать данное типа select?

Допустим, в дескрипторе шаблона заказов accounts.tdd, мы хотим объявить поле, значения которого должны выбираться из списка регионов (шаблон regions). Пусть названия регионов записываются в поле 2 шаблона regions. Тогда в дескрипторе шаблона accounts.tdd нужно объявить тип select:

accounts.tdd
$titles[1] = 'Клиент';
$titles[2] = 'Выберите регион';

$types[1] = 'varchar(99)';
$types[2] = "select template('regions') edit(1)"; // Устаревшее обозначение: field(1)

где regions - это имя шаблона, на основе которого отдельно на любой странице должен быть создан блок со списком регионов. В блоке со списком регионов может быть несколько полей, но в качестве списка будет использоваться только поле 1.

regions.tdd
$titles[1] = 'Название региона';
$types[1] = 'varchar(255)';
$params['isMultiRec'] = true;

В дескрипторе заказов (accounts.tdd) указывается шаблон (regions), но ничего не говорится о блоке, из которого формируется список регионов — его должен назначить сам пользователь системы управления.

Когда редактор в блоке заказов начинает редактировать первую запись, то в поле для выбора региона еще нет никакого списка. Чтобы его назначить, нужно щелкнуть по небольшой кнопке (см. снимок), которая находится справа от поля с соответствующим select–данным (кнопка видна только администратору и главному редактору). Откроется окно для выбора списка. В этом окне будут представлены все блоки, созданные на основе шаблона regions.

Текущий блок в качестве выборного списка

В качестве выборного списка можно назначить "самого себя". Когда может возникнуть такая ситуация? Например, в древовидном меню, как правило, одно из полей отводится под идентификатор родителя - туда записывается recId другой записи из того же блока. Все, что нужно сделать в этом случае, это указать в параметре template тот же шаблон.
См. пример древовидного меню навигации
menu.tdd
<?php
$titles = [
    1 => 'Родительская категория',
    2 => 'Название пункта списка',
];
$types = [
    1 => 'select template(menu) edit(2)',
    2 => 'varchar(255)',
];
$params = [
    'isMultiRec' => true,
];

 

Связанные (зависимые) выборные списки

Замена списка в Blox CMS

Что такое связанные списки? Это когда список значений одного выпадающего списка зависит от значения, выбранного в другом выпадающем списке. Такие списки очень удобны, если вам надо выбрать некий объект с определенными характеристиками.

Усложним предыдущую задачу. Теперь в каждом заказе, кроме региона, будем указывать и город. То есть, после выбора того или иного региона, в другом поле можно выбрать город из этого региона.

Как создать данное типа select, зависимое от другого select–данного?

Продолжим работать с теми же шаблонами. Дескриптор шаблона заказов (accounts.tdd) будет таким же, как в предыдущем примере, только добавится новое данное в поле 3. Его тип объявляется аналогично select–данному в поле 2. То есть, указывается шаблон, который должен иметь блок–претендент на список городов (в нашем случае — это шаблон cities), и указывается поле, из которого формируется список.

accounts.tdd
$titles[1] = 'Клиент';
$titles[2] = 'Выберите регион';
$titles[3] = 'Выберите город';

$types[1] = 'varchar(99)';
$types[2] = "select template('regions') edit(1)";
$types[3] = "select template('cities')  edit(1) parentField(2)";

В зависимых select–данных, кроме этого, добавляется параметр parentField — родительское поле редактирования, то есть, поле 2, от значения которого будет зависеть список значений поля 3.

Внимание! Тип зависимого select–данного должен быть объявлен после объявления типа родительского данного. При этом, значение ключа массива $types не важно.

Например, поле для выбора региона в дескрипторе accounts.tdd могло бы находиться и в поле 4. Но тогда переменная $types[4] должна быть обязательно записана выше переменной $types[3], в которой задается город.

cities.tdd
$titles[1] = 'Название города';
$types[1] = 'varchar(255)';
$params['isMultiRec'] = true;

Структура данных шаблона cities такая же, как у шаблона regions.

regions.tdd
$titles[1] = 'Название региона';
$types[1] = 'varchar(255)';
$params['isMultiRec'] = true;

Так же, как и для списка регионов, для списков городов на любой странице нужно создать блок на шаблоне cities.

На этот раз таких блоков будет очень много (один блок со списком городов на каждый регион). Поэтому имеет смысл создать отдельную, так сказать, географическую страничку. Такую страничку можно построить, например, на блоке, каждая запись которого, кроме наименования региона, будет включать в себя блок со списком городов.

Блоки со списками абсолютно не зависят от select–данных — это select–данные зависят от них, используюя один из столбцов в качестве списка. Записи о регионах и городах могут иметь и дополнительные поля, например, поля с информацей о площади территории, численности населения и т.п. В этих блоках можно добавлять и удалять записи, сохранять сортировки, и всё это будет отражаться на выпадающем списке select–данного.

Если регион не связан с соответствующим списком городов, поле для выбора города будет пустым.

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

Откроется окно для выбора списка. В этом окне будут представлены все блоки, созданные на основе шаблона cities.

Зависимый список привязывается к опции из родительского списка только один раз. При редактировании другого данного, после выбора такой же опции, в зависимом поле автоматически будет сформирован нужный список.

Альтернативная (короткая) форма записи параметров данных типа select

Существует альтернативная форма записи, когда названия параметров не используются (кроме параметра controls). Значения этих параметров можно записать в скобках после имени типа (то есть, после слова select).

.tdd

$types[2] = "select template('regions') edit(1)  controls('edit','add')";
$types[2] = "select('regions', 1) controls('edit','add')";

$types[3] = "select template('cities')  edit(1) parentField(2)  parentIdField(2)";
$types[3] = "select('cities', 1, 2, 2)";

Значения нужно записывать через запятую в такой последовательности: template, edit, parentField, parentIdField.

Различные варианты отображения пунктов списка

В качестве идентификатора пункта из выборного списка (в окне редактирования), системой используется номер записи. Этот номер записи и хранится в таблице базы данных данного шаблона. Существует несколько вариантов подстановки этого номера значениями из выборного списка, в зависимости от режима работы сайта (редактирование блока, вывод блока, запрос к блоку). Для этих целей служат параметры подстановки: edit(), output(), pick(), search(), sort(),

Параметр edit() — обычный случай

$types[2] = "select template('regions') edit(1)";

В окне редактирования (в выпадающем списке) мы увидим значения из поля 1, а не номера записей. При выводе блока на странице сайта будут также применены данные из поля 1.

Если параметр edit() не указан, то и в окно редактирования и в блок будут выведены номера записей:

$types[2] = "select template('regions')";

Параметр output() — комплексный случай

Если мы хотим, чтобы в выпадающем списке окна редактирования видеть замещенные значения одного поля, а в выводимом на странице блоке значения другого поля, то нужно применять два параметра:

$types[2] = "select template('regions') edit(1) output(2)";

Параметры подстановки для спец.запросов

Запросы pick, search, sort производятся к определенным полям. Возникает вопрос — если запрос производится к полю с данным типа select, то какое значение использовать: номер записи или замещенное значение? Для разрешения этого вопроса служат одноименные параметры подстановки: pick(), search(), sort(), в которых нужно указать поля, которыми нужно замещать номер записи.

По умолчанию для параметров search и sort в качестве значения применяется номер поля, заданный в параметре edit. По умолчанию для параметра pick применяется значение "rec".
Поэтому приведенные ниже два кода эквиваленты:

$types[2] = "select template('regions') edit(1)";
$types[2] = "select template('regions') edit(1) pick('rec') search(1) sort(1)";

Значение "rec" — отмена подстановки

Вместо номера поля, для всех параметров подстановки можно использовать значение "rec", Это означает, что будет использоваться номер записи, то есть замена вообще не производится.

Пример 1
В окне редактирования в выпадающем списке используются данные поля 1, а в блоке будут выводиться номера записей:

$types[2] = "select template('regions') edit(1) output('rec')";

Пример 2

$types[2] = "select template('regions') edit('rec')";
# Это эквивалентно
$types[2] = "select template('regions')";

 


 

Параметры select–данного

Имя параметраНазначение параметраЗначение
template
обязательный параметр
Шаблон блока, из которого берется список.Имя шаблона
edit
желательный параметр
Поле выборного шаблона (шаблона, указанного в параметре template), значения которого будут использоваться в выпадающем списке в окне редактирования.Номер поля
или "rec"
outputПоле выборного шаблона (шаблона, указанного в параметре template), значения которого будут выводиться в блоке вместо данных объявляемого поля.Номер поля
или "rec"
pickПоле выборного шаблона (шаблона, указанного в параметре template), к которому будут обращены pick-запросы.Номер поля
или "rec"
searchПоле выборного шаблона (шаблона, указанного в параметре template), к которому будут обращены search-запросы.Номер поля
или "rec"
sortПоле выборного шаблона (шаблона, указанного в параметре template), к которому будут обращены sort-запросы.Номер поля
или "rec"
parentField
для зависимых списков
Поле текущего шаблона, от которого будет зависеть выборный список данного поля. Номер поля
parentIdField
для зависимых списков
Этот параметр применяется, если вы собираетесь хранить все зависимые списки не в отдельных блоках, а в одном блоке. В этом случае в шаблоне, указанном в параметре template, нужно создать целочисленное поле, в которое будет автоматически записываться номер родительской записи. Номер поля
controlsПеречень дополнительных кнопок управления списком в окне редактирования (редактировать пункт, добавить пункт, удалить пункт)Полный возможный перечень: 'edit','add','delete'

 


 

Примечания

  • Число зависимых уровней select–данных в записи не ограничено. То есть, зависимый список можно связать не только с опцией из независимого списка, но и с опцией из зависимого списка. Например, в рассмотренном выше примере можно добавить третье select–данное со списком улиц города.

  • В таблице базы данных в качестве значения данного типа select хранится идентификатор строки из блока со списком, однако, на страничке будут отображаться не идентификаторы, а подставляться значение из блока со списком.

    Более того, запросы сортировки и поиска к полям select будут производиться так, как будто там храняться не идентификаторы, а данные.

  • При выводе select-данного в блоке, номер выбранной записи заменяется другим данным из той же записи. Но как быть, если нам нужно узнать этот номер?

    Это можно сделать через переменную шаблона $dat. Дело в том, что номера записей передаются в любом случае в элементе $dat['selects'].

  • Если пользователю приходится вводить много записей с одинаковыми данными из полей типа select, то можно сделать так, чтобы эти данные вводились автоматически.

    Предлагаемый метод будет работать только в том случае, если к этим полям производится запрос условной выборки. Значения полей будут браться с помощью метода Request::get($block,'pick'); и сохраняться с помощью массива $defaults (значения по умолчанию) в дескрипторе. Пример применения $defaults можно посмотреть в коде "Каталог товаров (pick-навигация)"

  • При применении вложенных шаблонов правильно указывайте путь в параметре template. Примеры:

    Файл: templates/shop/accounts.tdd
    $types[2] = "select template(regions) edit(1)       # Правильный относительный путь
    $types[2] = "select template(/shop/regions) edit(1) # Правильный абсолютный путь
    $types[2] = "select template(shop/regions) edit(1)  # Неправильный относительный путь
    # Шаблон regions находится в той же папке: templates/shop/
    


См. также

 

   



В данных типа select воплощены принципы реляционных баз данных.

Реляционная модель данных представляет информацию в виде совокупности таблиц, связанных между собой посредством совместно используемых полей данных, называемых ключами.