Navigatorcompany.ru

Навигатор для Компаний
2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Html combobox пример

Комбобокс ComboBox

Комбобокс — это поле ввода со списком подсказок.

Когда использовать

  • для выбора значения из справочника,
  • для добавления своего значения в справочник.

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

Комбобокс может работать в двух режимах — обычном и в режиме автокомплита. Основное их отличие в том, что в режиме автокомплита список вариантов появляется только после ввода первого символа или изменении уже введенного значения.

Виды полей

Комбобокс со стрелкой

Поле работает по аналогии с раскрывающимся списком — при клике в поле сразу появляется список всех вариантов. Об этом подсказывает стрелка и плейсхолдер.

Используйте этот режим, если вы точно знаете, что справочник не будет содержать больше 50 строк, либо уверены, что пользователю удобней выбирать значение, просматривая список.

Комбобокс без стрелки

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

Используйте это поле, если в справочнике больше 50 строк или пользователь привык заполнять подобные поля, вводя значение с клавиатуры.

Описание работы

Комбобокс со стрелкой

Состояние по умолчанию

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

Фокус по пустому полю

При получении фокуса плейсхолдер становится чуть светлее, открывается список вариантов.

Когда курсор находится над списком, скроллинг страницы блокируется.

Начало ввода

При вводе первого символа список фильтруется. Первый пункт в списке подсвечивается:

Выбор пункта из списка

Выбор значения может быть сделан двумя способами — при управлении с клавиатуры и мышью.

При выборе значения мышью или клавишей Enter список закрывается, фокус остается в поле. Список будет показан снова при следующем клике в поле или изменении значения.

Фокус по заполненному полю

При получении фокуса введенное значение выделяется, раскрывается список, прокрученный до выбранного значения:

Нет совпадений

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

В этом состоянии, при нажатии на клавиатуре Enter ничего не происходит, фокус остается в поле.

Потеря фокуса без выбора пункта из списка

Если введенное значение совпадает со значением из справочника, при потере фокуса это значение выбирается:

Если ничего не найдено или список не успел загрузиться, покажите ошибку:

Комбобокс без стрелки

В целом комбобокс без стрелки работает так же как со стрелкой с некоторыми исключениями.

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

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

При клике или получению фокуса плейсхолдер в поле становится чуть светлее.

Поиск запускается и появляется список при вводе хотя бы одного символа.

Оптимальное количество строк в списке — 5. Если после фильтрации список может быть очень большим, это число можно увеличивать до 20.

При получении фокуса полем с уже введенным значением это значение выделяется:

Поиск запускается и список появляется только после изменения значения.

Варианты использования

Составной список

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

Основное значение — короткое, емкое и уникальное.

Начало ввода

Выбор сделан

После выбора показывайте дополнительное значение в поле серым цветом. Если оно полностью не входит, показывайте при наведении хинт:

Фокус по заполненному полю

При получении фокуса тултип должен исчезнуть.

Поиск по вхождению

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

Читайте так же:
Php if несколько значений

Чтобы понять, стоит ли использовать поиск по вхождению, задайте себе вопрос: точно ли пользователь знает начало строки? Если нет — используйте поиск по вхождению.

Подсвечивайте совпадения жирным начертанием Segoe UI Negreta .

Избранные варианты

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

Фокус по пустому полю

Эти варианты показываются над основным списком, отделяются чертой.

Если это комбобокс в режиме автокомплита сразу по фокусу показывайте список из 3-5 вариантов с заголовком. Заголовок нужен для того, чтобы было понятно, что это не полный список:

Указание значения не из справочника

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

Автоматическое добавление значения в справочник

Если пользователь сам наполняет справочник, то при вводе нового значения не показывайте текст «Нет совпадений». Добавляйте значение в список и при следующем заполнении предлагайте его наравне с остальными.

Нет соответствий

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

Добавление карточки в справочник

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

Фокус на пустом поле

Если добавление карточки частый сценарий — выбирайте пункт «Добавить» по умолчанию, чтобы пользователь мог нажать Enter и быстро перейти к добавлению новой карточки:

Ввод первого символа

В открывающемся лайтбоксе добавления карточки поле «Название» предзаполняется уже введенным значением.

Нет совпадений

Потеря фокуса

Если в предыдущем состоянии поле теряет фокус, срабатывает валидация: поле красится в красный, показывается сообщение об ошибке.

Спиннер

Если обработка запроса для построения списка занимает дольше 0,3 секунды, показываем спиннер минимум 1 секунду. Если список уже открыт, и при получении ответа возникла задержка — показываем спиннер в поле справа, список до обновления остается в прежнем состоянии.

Нажатие Enter при пустом/не загрузившемся списке ни к чему не приводит, фокус остается в этом же поле.

Лоадер специальный, серый, не привлекающий слишком много внимания:

Если происходит ошибка сервера, показываем сообщение:

Размер, расположение

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

Список с подсказками всегда открывается вниз. Оптимальная высота списка 300-450 px. Чтобы список не выходил за границу страницы, проследите чтобы под ним было достаточное количество места.

Фокус и работа с клавиатурой

При клике по полю и при переходе табом поле выглядит одинаково: появляется синяя рамка, которая сохраняется до потери фокуса.

Программирование на C, C# и Java

Уроки программирования, алгоритмы, статьи, исходники, примеры программ и полезные советы

ОСТОРОЖНО МОШЕННИКИ! В последнее время в социальных сетях участились случаи предложения помощи в написании программ от лиц, прикрывающихся сайтом vscode.ru. Мы никогда не пишем первыми и не размещаем никакие материалы в посторонних группах ВК. Для связи с нами используйте исключительно эти контакты: vscoderu@yandex.ru, https://vk.com/vscode

Как добавить в ComboBox пункты. Как использовать ComboBox

ComboBox – это элемент управления Windows Forms, который представляет собой поле со списком.

Однако при первым знакомстве с ним не все понимают, как добавить в ComboBox пункты.

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

Далее надо нажать на “Изменить элементы…”, откроется окно:

В него мы и записываем нужные нам пункты, а затем нажимаем “ОК”.

Читайте так же:
Поле со списком php

Теперь при запуске формы мы сможем выбрать в ComboBox’e нужный нам пункт.

Кроме того можно добавлять пункты в самом коде, используя свойство comboBox1.Items.Add().

В скобках мы пишем, какой пункт мы хотим добавить.

Например, можно это делать при загрузке формы, дважды щёлкнув на форму, чтобы перейти в нужный участок кода. Там мы для примера напишем:

Запускаем программу, и вот, что мы видим:

Теперь к нашим имеющимся (или вместо, если не хотите возиться в форме) добавились пункты, указанные в коде.

Но как же нам теперь использовать их?

Доступ к пунктам СomboBox’a в коде можно получить, используя свойство comboBox1.SelectedIndex.

Индексы в СomboBox’e – это и есть пункты его списка, начинающиеся сверху. В C# индексы считаются с нуля, так что самый верхний пункт списка (у нас это vscode.ru) будет иметь индекс 0, ниже его – индекс 1, ещё ниже – индекс 2 и так далее.

Сейчас мы напишем кусочек кода, который покажет действие этого свойства. В данном коде при выборе элементов, чьи индексы написаны (0 и 1), в программе появляется MessageBox с сообщением. В форме мы дважды кликам на СomboBox, а затем пишем:

Программирование Delphi

Все о программировании.

Главное меню

Изменение ширины списка открытого ComboBox

Компонент TComboBox сочетает в себе редактируемый список с возможностью прокрутки и выбора определенного пункта списка. Пользователь может выбрать какой-либо элемент из списка или ввести его непосредственно в поле редактирования.

Раскрывающийся список

Когда список находится в открытом состоянии, Windows рисует окно внизу списка с элементами, которые находятся внутри списка.

Свойство DropDownCount определяет максимальное количество элементов, которые будут отображаться в открытом списке.

Ширина открытого списка равна ширине поля ComboBox. Когда длина (или строка) превышает ширину ComboBox, элементы урезаются до ширины списка.

Компонент TComboBox не имеет свойства для расширения раскрывающегося окна списка.

Фиксированная ширина раскрывающегося поля ComboBox

Но можно самостоятельно установить ширину раскрывающегося списка, отправив специальное сообщение Windows ComboBox. Это сообщение CB_SETDROPPEDWIDTH, которое означает минимально допустимую ширину раскрывающегося списка.

Для размера окна, скажем, 200 пикселей, можно сделать так:

Это будет работать правильно, если только ширина пунктов раскрывающегося списка не будет превышать 200 пикселей.

Для того, чтобы быть уверенным, что пункты меню «влезут» в раскрывающийся список, можно будет сделать вычисления.

Вот пример функции для расчета ширины раскрывающегося списка с учетом ширины его отдельных пунктов.

Для расчета ширины раскрывающегося списка используется ширина самой длинной строки.

Откуда вызывать процедуру ComboBox_AutoWidth?

Если Вы предварительно заполняете список во время разработки, то вызывать процедуру ComboBox_AutoWidt удобно при создании формы, в обработчике события OnCreate формы.

Если же Вы динамически заполняете список во время работы приложения, то вызывать процедуру ComboBox_AutoWidth можно внутри обработчика события OnDropDown ComboBox. Это событие происходит, когда Вы открываете раскрывающийся список.

Проверяем

Для проверки, поместите компонент TComboBox на форму и заполните его свойство Items словами различной длины. Затем пишем процедуру ComboBox_AutoWidth и вызываем ее в событии формы OnCreate.

После запуска программы, Вы можете убедиться, что ширина раскрывающегося списка растянется по ширине самого длинного пункта списка.

Расширение списка влево!

Заметьте, что список расширяется вправо. Что же сделать, если ComboBox находится справа на форме, а поле со списком выходит за пределы окна?

Сообщение CB_SETDROPPEDWIDTH всегда расширяет список вправо и нет никакой возможности указать, в каком направлении нужно расширять список (вправо или влево).

Найденное решение — WM_CTLCOLORLISTBOX

Решение простое: когда открывается список, Windows отправляет сообщение WM_CTLCOLORLISTBOX.

Каждое VCL управление предоставляет свойства WindowProc — это процедура, которая реагирует на сообщения, которые отправляются на управление. Мы можем использовать свойство WindowProc, чтобы временно заменить, или сделать подкласс процедуры окна управления.

Читайте так же:
Узнать количество элементов в массиве php

Вот наш измененный WindowProc для ComboBox:

Когда наш список получит сообщение WM_CTLCOLORLISTBOX, мы получим размеры окна списка, а также прямоугольник окна раскрытого списка (GetWindowRect). Если окажется, что раскрывающийся список будет правее самого ComboBox, то мы переместим его левее, т.е. выровняем по правому краю.

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

Ну и наконец, нужно разместить все это в обработчике события OnCreate формы:

И конечно же прописать все в объявлении формы:

Программирование Delphi

Все о программировании.

Главное меню

Изменение ширины списка открытого ComboBox

Компонент TComboBox сочетает в себе редактируемый список с возможностью прокрутки и выбора определенного пункта списка. Пользователь может выбрать какой-либо элемент из списка или ввести его непосредственно в поле редактирования.

Раскрывающийся список

Когда список находится в открытом состоянии, Windows рисует окно внизу списка с элементами, которые находятся внутри списка.

Свойство DropDownCount определяет максимальное количество элементов, которые будут отображаться в открытом списке.

Ширина открытого списка равна ширине поля ComboBox. Когда длина (или строка) превышает ширину ComboBox, элементы урезаются до ширины списка.

Компонент TComboBox не имеет свойства для расширения раскрывающегося окна списка.

Фиксированная ширина раскрывающегося поля ComboBox

Но можно самостоятельно установить ширину раскрывающегося списка, отправив специальное сообщение Windows ComboBox. Это сообщение CB_SETDROPPEDWIDTH, которое означает минимально допустимую ширину раскрывающегося списка.

Для размера окна, скажем, 200 пикселей, можно сделать так:

Это будет работать правильно, если только ширина пунктов раскрывающегося списка не будет превышать 200 пикселей.

Для того, чтобы быть уверенным, что пункты меню «влезут» в раскрывающийся список, можно будет сделать вычисления.

Вот пример функции для расчета ширины раскрывающегося списка с учетом ширины его отдельных пунктов.

Для расчета ширины раскрывающегося списка используется ширина самой длинной строки.

Откуда вызывать процедуру ComboBox_AutoWidth?

Если Вы предварительно заполняете список во время разработки, то вызывать процедуру ComboBox_AutoWidt удобно при создании формы, в обработчике события OnCreate формы.

Если же Вы динамически заполняете список во время работы приложения, то вызывать процедуру ComboBox_AutoWidth можно внутри обработчика события OnDropDown ComboBox. Это событие происходит, когда Вы открываете раскрывающийся список.

Проверяем

Для проверки, поместите компонент TComboBox на форму и заполните его свойство Items словами различной длины. Затем пишем процедуру ComboBox_AutoWidth и вызываем ее в событии формы OnCreate.

После запуска программы, Вы можете убедиться, что ширина раскрывающегося списка растянется по ширине самого длинного пункта списка.

Расширение списка влево!

Заметьте, что список расширяется вправо. Что же сделать, если ComboBox находится справа на форме, а поле со списком выходит за пределы окна?

Сообщение CB_SETDROPPEDWIDTH всегда расширяет список вправо и нет никакой возможности указать, в каком направлении нужно расширять список (вправо или влево).

Найденное решение — WM_CTLCOLORLISTBOX

Решение простое: когда открывается список, Windows отправляет сообщение WM_CTLCOLORLISTBOX.

Каждое VCL управление предоставляет свойства WindowProc — это процедура, которая реагирует на сообщения, которые отправляются на управление. Мы можем использовать свойство WindowProc, чтобы временно заменить, или сделать подкласс процедуры окна управления.

Вот наш измененный WindowProc для ComboBox:

Когда наш список получит сообщение WM_CTLCOLORLISTBOX, мы получим размеры окна списка, а также прямоугольник окна раскрытого списка (GetWindowRect). Если окажется, что раскрывающийся список будет правее самого ComboBox, то мы переместим его левее, т.е. выровняем по правому краю.

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

Ну и наконец, нужно разместить все это в обработчике события OnCreate формы:

И конечно же прописать все в объявлении формы:

Поля ввода со списком выбора — combobox

Полный список свойств и функций, а так же общие правила их использования, см. здесь: Краткий обзор и правила, список функций VcorpJS.

Читайте так же:
Преобразование xml в html

Комбинированный список combobox — это блочный HTML — элемент, который содержит одновременно поле ввода и анимированный список выбора.

Плагин использует CSS-классы .pb_combobox и другие, начинающиеся с » .pb_cb_ » для вложенных элементов.

HTML — элементы combobox могут содержаться в HTML-коде или создаваться функцией . cbNew (. )
Для поиска и инициализации полей combobox, находящихся в виде HTML-кода, предназначена функция . cbUpdate (. )
Обновление выпадающего списка любого комбобокса выполняет функция . cbChange (descriptor. )
Прочитать текущее значение из текстового поля input любого комбобокса позволяет функция . cbGet (descriptor)
Задать общую callback-функцию можно через функцию . cbCallback (handler) (см. правила для callback — функций).

Каждому HTML-объекту с классом pb_combobox при его инициализации и работе с ним, присваиваются уникальные id для каждого внутреннего HTML-объекта.

Если тот или иной combobox отработал и становится не нужен, его можно спокойно удалить или затереть в HTML-коде родителя, это корректная операция, VcorpJS следит за внутренними дескрипторами combobox и безопасно устанавливает обработчики событий и внутренние параметры каждого combobox (свойства .pb_EV и .pb_CB).

. cbUpdate ( [ handler ] , [ parentNode ] , [ selector ] , [ time ] , [ step ] )

Функция ищет все HTML — элементы с классом pb_combobox внутри указанного родителя parentNode (или по всему документу) и инициализирует их, если они ещё не были инициализированы ранее.

handler — общая callback — функция, вызываемая для всех найденных комбобоксов, отдельное описание ниже по тексту.

parentNode — ссылка на родительский HTML-объект или его текстовый id (в котором будет происходить поиск)
Если родительский объект не указан или не найден, то document (VcorpJS. D ).

selector — текстовый селектор для уточнения поиска HTML-объектов, вложенных в parentNode ,
работает примерно так: parentNode .querySelectorAll( selector + » .pb_combobox» );
Селектор составляется по правилам CSS — имена классов пишутся с точкой, идентификаторы через решётку #, допустимы каскадные перечисления классов и т.д.

time — время анимации раскрытия списка выбора в миллисекундах (не менее 100, по-умолчанию 100). Задаётся для всех комбобоксов.

step — шаг анимации списка выбора в миллисекундах (не менее 20, по-умолчанию 20). Задаётся для всех комбобоксов.

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

Функцию VcorpJS. cbUpdate () можно вызывать сколько угодно раз.
При каждом новом вызове, если указан handler , он принудительно меняется для найденных комбобоксов.
При каждом вызове происходит новый поиск — согласно указанным parentNode и selector ,
если какой-либо из найденных комбобоксов ещё не был инициализирован, то навешиваются обработчики на различные вложенные элементы, а вложенное поле ввода input получает системный идентификатор в свойстве id (поэтому бесполезно заранее указывать id у вложенных input ).
Не указывайте заранее id у обязательных элементов combobox (может возникнуть ошибка инициализации). Если хотите уникальности в исходном HTML-коде, включите скрытые блочные элементы со своим id и задайте для них CSS-правила.

. cbNew ( [ parentNode ] , [ inputValue ] , [ arrayValues ] , [ handler ] , [ maxLength ] , [ time ] , [ step ] )

Функция создаёт новый combobox и инициализирует его, присваивая свободный дескриптор новому HTML-элементу (комбобоксу класса pb_combobox ).

parentNode — ссылка на родительский HTML-объект или его текстовый id
Если parentNode существует, то его содержимое полностью перезаписывается (через .innerHTML) созданным HTML-элементом класса pb_combobox

inputValue — начальное строковое значение для вложенного текстового поля input

arrayValues — массив строк со значениями (может содержать корректные HTML-строки) для выпадающего списка выбора.

handler — персональная callback — функция, вызываемая только для вновь созданного комбобокса, отдельное описание ниже по тексту.
Персональная callback — функция будет заменена на общую при последующем вызове . cbUpdate (), если комбобокс будет найден по условию поиска.

Читайте так же:
Php условие if

maxLength — числовое значение атрибута maxLength для создаваемого поля input

time и step — соответственно время и шаг анимации раскрытия списка выбора в миллисекундах. Задаются для всех комбобоксов.

Функция возвращает дескриптор, закреплённый за вновь созданным комбобоксом.

. cbChange ( [ descriptor ] , [ arrayValues ] , [ handler ] , [ maxLength ] , [ status ] , [ time ] , [ step ] )

Функция обновляет выпадающий список комбобокса, указанного дескриптором descriptor .
Так же можно поменять максимальное количество символов maxLength , параметры анимации выпадающего списка и его текущее содержание и внешний вид.

descriptor — числовой дескриптор комбобокса или ссылка на HTML-объект комбобокса или его текстовый id

arrayValues — массив строк со значениями (может содержать корректные HTML-строки) для выпадающего списка выбора.

handler — персональная callback — функция, вызываемая только для комбобокса descriptor , отдельное описание ниже по тексту.
Персональная callback — функция будет заменена на общую при последующем вызове . cbUpdate (), если комбобокс будет найден по условию поиска.

maxLength — числовое значение атрибута maxLength для вложенного поля input

status — внешний вид и поведение раскрывающегося списка вариантов быстрого выбора.
Число: если 1, то список раскрывается; если 2, то закрывается; иначе остаётся как был. Анимация.

time и step — соответственно время и шаг анимации раскрытия списка выбора в миллисекундах. Задаются для всех комбобоксов.

Функция возвращает true или false — если указанный комбобокс не найден или некорректен.

Функция возвращает текстовое содержимое поля input указанного комбобокса, или false если он не найден или некорректен.

descriptor — числовой дескриптор комбобокса или ссылка на HTML-объект комбобокса или его текстовый id

Общая callback — функция для всех combobox

Установка общей callback — функции для всех комбобоксов веб-страницы
(дополнительно см. правила для callback — функций).

handler может быть текстовой строкой содержимого функции — в этом случае имена передаваемых параметров следующие:
e, desc, obj_parent, id_combobox, id_img, id_select, id_input, arrayValues, inputValue, typeEvent

Если handler является функцией (НЕ текстовой строкой), то имена параметров произвольные, но их количество и порядок такие же.

Функция вызывается как: function (e, desc, obj_parent, id_combobox, id_img, id_select, id_input, arrayValues, inputValue, typeEvent); где:

  • this — ссылка на HTML-объект класса pb_combobox
  • e — объект event текущего события (для поля ввода — keyup, keypress, keydown, change; для строки списка — mousedown)
  • desc — числовой дескриптор комбобокса (от 1)
  • obj_parent — ссылка на родительский объект комбобокса parentNode
  • id_combobox — свойство id комбобокса (HTML-элемента класса pb_combobox )
  • id_img — свойство id вложенного HTML-элемента класса .pb_cb_image
  • id_select — свойство id вложенного HTML-элемента класса .pb_cb_select
  • id_input — свойство id вложенного HTML-элемента input
  • arrayValues — массив с текстовыми HTML-строками списка быстрого выбора (HTML-содержимое элементов класса .pb_cb_option )
  • inputValue — текущее строковое значение вложенного поля input
  • typeEvent — значение «input» или «option» (если событие mousedown)

Почему так много параметров? На всякий случай, для динамичного управления комбобоксом, а именно:

callback — функция может вернуть true (или 1) — в этом случае содержимое выпадающего списка мгновенно заменяется значениями из массива arrayValues , а поскольку этот массив передаётся по ссылке, то обновлять список можно из callback-функции, меняя количество элементов и их содержимое.
Нужно быть внимательным, чтобы не присвоить новую ссылку на массив локальной переменной.
Лучше для надёжности воспользоваться функцией . cbChange (), но можно и быстро поменять содержимое массива без вызова этой функции, вернув true ,
разумеется, можно контролировать и менять содержимое поля ввода input , да и остальные части комбобокса.

Визуальный пример комбинированного списка выбора:

Для простоты и наглядности примера, combobox сделан как HTML-фрагмент с последующей инициализацией . cbUpdate ()

голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector