Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 31e46cb

Browse files
🎨 Add @ActionsGroup and @action support #56
fix #56
1 parent 5cb2e30 commit 31e46cb

File tree

6 files changed

+151
-67
lines changed

6 files changed

+151
-67
lines changed

‎demo/src/main/java/io/asfjava/ui/demo/screen/DemoForm.java‎

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,23 @@
22

33
import java.io.Serializable;
44

5-
import io.asfjava.ui.core.form.Index;
6-
import io.asfjava.ui.core.form.Tab;
5+
import io.asfjava.ui.core.form.Action;
6+
import io.asfjava.ui.core.form.ActionsGroup;
77
import io.asfjava.ui.core.form.TextField;
88

9+
@ActionsGroup({ @Action(title = "Next", type = "button", onClick = "goToNext()"),
10+
@Action(title = "Previous", type = "button", onClick = "goToPrevious()") })
11+
@Action(title = "Previous", type = "button", onClick = "goToPrevious()")
12+
@Action(title = "Next", type = "button", onClick = "goToNext()")
13+
@Action(title = "Send", type = "submit")
914
public class DemoForm implements Serializable {
1015

11-
@Index(1)
12-
@TextField(title = "index 1")
13-
private String index1;
16+
@TextField(title = "mail", pattern="^\\S+@\\S+$")
17+
private String mail;
1418

15-
@Tab(index = 2, title = "Tab2")
16-
@Index(0)
17-
@TextField(title = "index 2")
18-
private String index2;
19-
20-
@Tab(index = 3, title = "Tab1")
21-
@Index(2)
22-
@TextField(title = "Tab1 f3 index 2")
23-
private String index3;
24-
25-
@Tab(index = 3, title = "Tab1")
26-
@Index(1)
27-
@TextField(title = "Tab1 f4 index 1")
28-
private String index4;
29-
30-
@Tab(index = 2, title = "Tab2")
31-
@TextField(title = "Tab2 f5 index 0")
32-
private String index5;
33-
34-
private static final long serialVersionUID = -5073515619469444978L;
35-
36-
public String getIndex1() {
37-
return index1;
38-
}
39-
40-
public String getIndex2() {
41-
return index2;
42-
}
43-
44-
public String getIndex4() {
45-
return index4;
46-
}
47-
48-
public String getIndex5() {
49-
return index5;
50-
}
51-
52-
public String getIndex3() {
53-
return index3;
19+
public String getMail() {
20+
return mail;
5421
}
5522

23+
private static final long serialVersionUID = -5073515619469444978L;
5624
}

‎demo/src/main/resources/static/index.html‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<script src="../bower_components/angular-schema-form-bootstrap/bootstrap-decorator.min.js"></script>
99
<script src="../bower_components/lodash/lodash.js"></script>
1010

11-
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
11+
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
1212

1313
<script>
1414

@@ -24,6 +24,13 @@
2424
function errorCallback(error){
2525
//error code
2626
}
27+
28+
$scope.goToNext = function($event,item){
29+
alert("Click on next button")
30+
}
31+
$scope.goToPrevious = function(){
32+
alert("Click on previous button")
33+
}
2734
});
2835

2936
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.asfjava.ui.core.form;
2+
3+
import java.lang.annotation.Repeatable;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
7+
@Retention(RetentionPolicy.RUNTIME)
8+
@Repeatable(Actions.class)
9+
public @interface Action {
10+
String type();
11+
12+
String title();
13+
14+
String onClick() default "";
15+
}
16+
17+
@Retention(RetentionPolicy.RUNTIME)
18+
@interface Actions {
19+
Action[] value();
20+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.asfjava.ui.core.form;
2+
3+
import static java.lang.annotation.ElementType.TYPE;
4+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
5+
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
9+
@Retention(RUNTIME)
10+
@Target(TYPE)
11+
public @interface ActionsGroup {
12+
Action[] value();
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.asfjava.ui.core.form;
2+
3+
import static java.lang.annotation.ElementType.FIELD;
4+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
5+
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
9+
@Retention(RUNTIME)
10+
@Target(FIELD)
11+
public @interface FieldSet {
12+
String title() default "";
13+
}

‎src/main/java/io/asfjava/ui/core/schema/UiFormSchemaGenerator.java‎

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.List;
1212
import java.util.Map;
1313
import java.util.Map.Entry;
14+
import java.util.Optional;
1415
import java.util.function.Predicate;
1516
import java.util.stream.Collectors;
1617

@@ -23,6 +24,9 @@
2324
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
2425

2526
import io.asfjava.ui.core.FormDefinitionGeneratorFactory;
27+
import io.asfjava.ui.core.form.Action;
28+
import io.asfjava.ui.core.form.ActionsGroup;
29+
import io.asfjava.ui.core.form.FieldSet;
2630
import io.asfjava.ui.core.form.Index;
2731
import io.asfjava.ui.core.form.Tab;
2832
import io.asfjava.ui.dto.UiForm;
@@ -38,39 +42,81 @@ public UiForm generate(Class<? extends Serializable> formDto) throws JsonMapping
3842
JsonSchemaGenerator schemaGen = initSchemaGen(mapper);
3943
JsonSchema schema = generateSchema(formDto, schemaGen);
4044

41-
Map<Field, JsonNode> nodes = initFieldFormDefinition(mapper, declaredFields);
45+
Map<Field, JsonNode> nodes = initFieldsFormDefinition(mapper, declaredFields);
4246

4347
Map<Field, JsonNode> sortedNodes = reorderFieldsBasedOnIndex(nodes);
4448

45-
handlerGroupedFields();
49+
handlerGroupedFields(mapper, declaredFields, sortedNodes);
4650

47-
ObjectNode tabbedFields = handleTabbedFields(mapper, declaredFields, sortedNodes);
51+
Optional<ObjectNode> tabbedFields = Optional
52+
.ofNullable(handleTabbedFields(mapper, declaredFields, sortedNodes));
4853

4954
ArrayNode formDefinition = mapper.createArrayNode();
50-
formDefinition.add(tabbedFields);
55+
tabbedFields.ifPresent(formDefinition::add);
5156
sortedNodes.entrySet().stream().forEach(nodesElement -> formDefinition.add(nodesElement.getValue()));
5257

58+
handleActionsAnnotation(mapper, formDto, formDefinition);
59+
5360
return new UiForm(schema, formDefinition);
5461
}
5562

56-
private Map<Field, JsonNode> reorderFieldsBasedOnIndex(Map<Field, JsonNode> nodes) {
63+
private void handleActionsAnnotation(ObjectMapper mapper, Class<? extends Serializable> formDto,
64+
ArrayNode formDefinition) {
65+
ObjectNode groupedActionsNode = mapper.createObjectNode();
66+
ObjectNode actionsNode = mapper.createObjectNode();
5767

58-
Comparator<? super Entry<Field, JsonNode>> tabIndexComparator = (entry1, entry2) -> {
68+
buildActions(mapper, formDto, actionsNode, formDefinition);
69+
buildGroupedActions(mapper, formDto, groupedActionsNode, formDefinition);
70+
}
5971

60-
Indexfield1Index = entry1.getKey().getAnnotation(Index.class);
61-
Indexfield2Index = entry2.getKey().getAnnotation(Index.class);
72+
privatevoidbuildActions(ObjectMappermapper, Class<? extendsSerializable> formDto, ObjectNodeactionsNode,
73+
ArrayNodeformDefinition) {
6274

63-
return Integer.compare((field1Index != null ? field1Index.value() : Integer.MAX_VALUE),
64-
field2Index != null ? field2Index.value() : Integer.MAX_VALUE);
65-
};
75+
Action[] actionsAnnotations = formDto.getAnnotationsByType(Action.class);
76+
Arrays.stream(actionsAnnotations).forEach(action -> {
77+
formDefinition.add(buildActionNode(mapper, action));
78+
});
79+
}
6680

67-
return nodes.entrySet().stream().sorted(tabIndexComparator).collect(Collectors.toMap(Map.Entry::getKey,
68-
Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
81+
private void buildGroupedActions(ObjectMapper mapper, Class<? extends Serializable> formDto, ObjectNode actionsNode,
82+
ArrayNode formDefinition) {
83+
Optional<ActionsGroup> actionsAnnotation = Optional.ofNullable(formDto.getAnnotation(ActionsGroup.class));
84+
actionsAnnotation.ifPresent(actions -> {
85+
actionsNode.put("type", "actions");
86+
ArrayNode items = mapper.createArrayNode();
87+
Arrays.stream(actions.value()).forEach(action -> {
88+
ObjectNode node = buildActionNode(mapper, action);
89+
items.add(node);
90+
});
91+
actionsNode.set("items", items);
92+
93+
formDefinition.add(actionsNode);
94+
});
95+
}
6996

97+
private ObjectNode buildActionNode(ObjectMapper mapper, Action action) {
98+
ObjectNode node = mapper.createObjectNode();
99+
node.put("type", action.type());
100+
node.put("title", action.title());
101+
node.put("onClick", action.onClick());
102+
return node;
70103
}
71104

72-
private void handlerGroupedFields() {
73-
// TODO Grouping fieldset must handle it
105+
private ObjectNode handlerGroupedFields(ObjectMapper mapper, Field[] declaredFields,
106+
Map<Field, JsonNode> sortedNodes) {
107+
Predicate<? super Field> checkFieldSetAnnotation = field -> field.isAnnotationPresent(FieldSet.class);
108+
109+
Map<String, List<JsonNode>> groupedFields = new LinkedHashMap<>();
110+
111+
Arrays.stream(declaredFields).filter(checkFieldSetAnnotation)
112+
.forEach(field -> groupFieldsByTab(sortedNodes, field, groupedFields));
113+
114+
ArrayNode groups = mapper.createArrayNode();
115+
116+
ObjectNode tabsNode = mapper.createObjectNode();
117+
tabsNode.put("type", "fieldset");
118+
tabsNode.set("items", groups);
119+
return tabsNode;
74120

75121
}
76122

@@ -83,7 +129,6 @@ private ObjectNode handleTabbedFields(ObjectMapper mapper, Field[] declaredField
83129
Comparator<? super Field> fieldIndexComparator = (entry1, entry2) -> {
84130
Index field1Index = entry1.getAnnotation(Index.class);
85131
Index field2Index = entry2.getAnnotation(Index.class);
86-
87132
return Integer.compare((field1Index != null ? field1Index.value() : Integer.MAX_VALUE),
88133
field2Index != null ? field2Index.value() : Integer.MAX_VALUE);
89134
};
@@ -103,15 +148,17 @@ private ObjectNode handleTabbedFields(ObjectMapper mapper, Field[] declaredField
103148
tabNode.set("items", tabItems);
104149
tabs.add(tabNode);
105150
});
106-
107-
ObjectNode tabsNode = mapper.createObjectNode();
108-
tabsNode.put("type", "tabs");
109-
tabsNode.set("tabs", tabs);
110-
return tabsNode;
151+
if (tabs.size() > 0) {
152+
ObjectNode tabsNode = mapper.createObjectNode();
153+
tabsNode.put("type", "tabs");
154+
tabsNode.set("tabs", tabs);
155+
return tabsNode;
156+
}
157+
return null;
111158

112159
}
113160

114-
private Map<Field, JsonNode> initFieldFormDefinition(ObjectMapper mapper, Field[] declaredFields) {
161+
private Map<Field, JsonNode> initFieldsFormDefinition(ObjectMapper mapper, Field[] declaredFields) {
115162
Map<Field, JsonNode> nodes = new HashMap<>();
116163

117164
Arrays.stream(declaredFields).forEach(field -> buildFormDefinition(nodes, mapper, field));
@@ -154,6 +201,22 @@ private void buildFieldDefinition(Field field, Annotation annotation, ObjectMapp
154201
});
155202
}
156203

204+
private Map<Field, JsonNode> reorderFieldsBasedOnIndex(Map<Field, JsonNode> nodes) {
205+
206+
Comparator<? super Entry<Field, JsonNode>> tabIndexComparator = (entry1, entry2) -> {
207+
208+
Index field1Index = entry1.getKey().getAnnotation(Index.class);
209+
Index field2Index = entry2.getKey().getAnnotation(Index.class);
210+
211+
return Integer.compare((field1Index != null ? field1Index.value() : Integer.MAX_VALUE),
212+
field2Index != null ? field2Index.value() : Integer.MAX_VALUE);
213+
};
214+
215+
return nodes.entrySet().stream().sorted(tabIndexComparator).collect(Collectors.toMap(Map.Entry::getKey,
216+
Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
217+
218+
}
219+
157220
public static UiFormSchemaGenerator get() {
158221
if (instance == null) {
159222
instance = new UiFormSchemaGenerator();

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /