Из этого туториала вы узнаете, как создать два поля выбора, в которых на элементы второго блока выбора влияет значение первого. Разработчики сталкиваются с этим обычно, и это также называется цепным выбором. Примером является выбор страны с последующим выбором штата. Выбор штатов должен основываться на том, какая страна была выбрана.
Пример вывода
Вот пример вывода. У нас есть поле выбора для категории с последующим выбором для подкатегории. Первоначально, когда ни один элемент не выбран в первом поле, второй является пустым.
Когда пользователь выбирает категорию цвета , подкатегории будут отображать различные цвета.
Когда пользователь выбирает категорию « Форма» , подкатегории будут отображать различные формы выбора.
Тестовый класс домена
В этом примере есть два класса домена.
|
1
2
3
4
5
6
7
8
|
package asia.grails.testclass Category { static hasMany = [subCategories:SubCategory] String name public String toString() { return name }} |
|
1
2
3
4
5
6
7
8
9
|
package asia.grails.testclass SubCategory { static belongsTo = Category Category category String name public String toString() { return name }} |
Это просто отношения один ко многим.
Тестовые данные
Заполняем тестовые данные через Bootstrap.groovy
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
import asia.grails.test.Categoryimport asia.grails.test.SubCategoryclass BootStrap { def init = { servletContext -> if ( Category.count() == 0 ) { Category color = new Category(name:'Color').save() new SubCategory(category:color, name:'Red').save() new SubCategory(category:color, name:'Green').save() new SubCategory(category:color, name:'Blue').save() Category shape = new Category(name:'Shape').save() new SubCategory(category:shape, name:'Square').save() new SubCategory(category:shape, name:'Circle').save() Category size = new Category(name:'Size').save() new SubCategory(category:size, name:'Small').save() new SubCategory(category:size, name:'Medium').save() new SubCategory(category:size, name:'Large').save() } } def destroy = { }} |
У нас будет 3 категории: цвет, форма и размер.
Цепная форма выбора
Мы показываем форму. Код контроллера прост:
|
1
2
3
4
5
|
package asia.grails.testclass TestController { def form() { }} |
Содержимое form.gsp это.
|
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
28
|
<%@ page import="asia.grails.test.Category" %><!DOCTYPE html><html> <head> <meta name="layout" content="main"> <title>Chained Select Test</title> <g:javascript library='jquery' /> </head> <body> <div> <b>Category: </b> <g:select id="category" name="category.id" from="${Category.listOrderByName()}" optionKey="id" noSelection="[null:' ']" onchange="categoryChanged(this.value);" /> </div> <div> <b>Sub-Category: </b> <span id="subContainer"></span> </div> <script> function categoryChanged(categoryId) { <g:remoteFunction controller="test" action="categoryChanged" update="subContainer" params="'categoryId='+categoryId"/> } </script> </body></html> |
Второе поле выбора отображается внутри диапазона с id = subContainer . Он обновляется при каждом изменении категории ( onchange = ”categoryChanged (this.value); ). Метод для отображения подкатегорий — через вызов AJAX. Тег remoteFunction может использоваться для асинхронного вызова действия контроллера.
Также важно включить библиотеку JQuery. Это делается с помощью этого кода GSP:
|
1
|
<g:javascript library='jquery' /> |
Начиная с Grails 2.4, теги Grails AJAX устарели. Альтернативой является ручное кодирование метода javascript. Вот альтернативная реализация функции categoryChanged.
|
1
2
3
4
5
|
<script> function categoryChanged(categoryId) { jQuery.ajax({type:'POST',data:'categoryId='+categoryId, url:'/forum/test/categoryChanged',success:function(data,textStatus){jQuery('#subContainer').html(data);},error:function(XMLHttpRequest,textStatus,errorThrown){}}); }</script> |
Это длиннее, но все же интуитивно понятно.
Вот остальная часть кода контроллера, который включает метод, который будет отображать второе поле выбора.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
package asia.grails.testclass TestController { def form() { } def categoryChanged(long categoryId) { Category category = Category.get(categoryId) def subCategories = [] if ( category != null ) { subCategories = SubCategory.findAllByCategory(category, [order:'name']) } render g.select(id:'subCategory', name:'subCategory.id', from:subCategories, optionKey:'id', noSelection:[null:' '] ) }} |
Метод categoryChanged контроллера вызывается функцией AJAX. Он возвращает HTML-код блока выбора и визуализирует его внутри span с id = subContainer .
| Ссылка: | Выбор Grails в цепочке — загрузите данные в одном раскрывающемся списке в зависимости от другого от нашего партнера JCG Джонатана Тана в блоге Grails . |


