Статьи

Grails Dynamic Dropdown

Недавно у меня было требование к пользовательскому интерфейсу, когда клиент хотел выбрать значения из двух отдельных раскрывающихся списков. Значение первого раскрывающегося списка по существу фильтрует значения для второго раскрывающегося списка. Учитывая, что финансовые проекты, которые мы поддерживаем, не сильно зависят от требований пользовательского интерфейса, мне пришлось провести некоторое начальное обучение и экспериментировать, чтобы получить хорошую реализацию. В этой записи блога подробно рассказывается, как реализовать динамические выпадающие списки в Grails с помощью ajax и минимального JavaScript.

Пример задачи

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

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

  • Пользователь выбирает Даллас в качестве города в первом раскрывающемся списке. Второй выпадающий список теперь отображает значения: Mavericks, Cowboys и Rangers.
  • Пользователь выбирает Питтсбург в качестве города в первом раскрывающемся списке. Второй выпадающий список теперь отображает значения Стилерс, Пираты и Пингвины.

Дизайн высокого уровня в Grails

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

  • На странице gsp создайте выпадающий список со списком городов.
  • При изменении выпадающего списка городов отправьте вызов ajax на сервер с выбранным параметром города.
  • Контроллер на сервере получает параметр и ищет команды в зависимости от выбранного города.
  • Верните шаблон с новым выпадающим списком для команд, предоставив модель с отфильтрованным списком команд.

Мы продолжим ниже с фрагментами кода. Код был продемонстрирован в Grails 2.0.

Доменные объекты

Объекты домена для этого примера довольно просты: объект City с именем и объект Team.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package dropdown
 
class City {
 
  String name
 
  static hasMany = [teams: Team]
 
  static constraints = {
  }
}
 
package dropdown
 
class Team {
   
  String name
 
  static belongsTo = [city: City]
 
  static constraints = {
  }
   
  String toString() {
    name
  }
}

Gsp Page

Страница gsp содержит список городов непосредственно из вызова GORM. Это обычно выполняется и демонстрируется сгенерированными по умолчанию страницами Grails GSP. Обратите внимание на использование функции remoteFunction. Это утилита Grails GSP, которая выполняет ajax-вызов на сервер и предоставляет «update» для раздела dom, который будет обновляться по возвращении.

Для выпадающего списка команды мы начнем с пустого тега выбора. Ниже приведен фрагмент.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<g:select name="city.id" from="${City.list()}" optionKey="id" optionValue="name"
                noSelection="['':'Choose City']"
                onchange="${remoteFunction (
                        controller: 'city',
                        action: 'findTeamsForCity',
                        params: ''city.id=' + this.value',
                        update: 'teamSelection'
                )}" />
  ....
   
  <td id="teamSelection" valign="top">
    <select>
   <option>Choose Team</option>
    </select>
  </td>

Контроллер используется для фильтрации

Контроллер будет иметь замыкание, которое принимает идентификатор города, а затем использует его для предоставления групп, связанных с городом. Это закрытие вызывается через ajax. Закрытие отображает шаблон и модель.

Закрытие def dynamicDropdown используется только для навигации. По соглашению он делает GSP с тем же именем.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
package dropdown
 
class CityController {
 
  static scaffold = City
 
  // just navigation to the gsp
  def dynamicDropdown = {
  }
 
  def findTeamsForCity = {
    def city = City.get(params.city.id)
    render(template: 'teamSelection', model:  [teams: city.teams])
  }
}

шаблон

Шаблон используется для замены раздела DOM в GSP. Он принимает любую модель, которая предоставляется.

1
2
3
4
<!-- This template renders a drop down after a city is selected -->
 
<g:select name="team.id" from="${teams}" optionValue="name"
          optionKey="id"/>

Вывод

Есть несколько способов выполнить динамическое раскрытие. Можно использовать нативный jQuery или даже нативный JavaScript. Я решил использовать встроенные функции grails и уменьшить свою зависимость от программирования на стороне клиента. Это оказалось чистым, быстрым и довольно простым!

Ссылка: Grails Dynamic Dropdown от нашего партнера JCG Нирава Ассара в блоге Assar Java Consulting .