Last active
October 31, 2023 04:32
-
-
Save jumperchen/f8342cf3b288989f0121 to your computer and use it in GitHub Desktop.
ZK MVVM with Spring MVC Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Book { | |
private Set<Category> categories = new LinkedHashSet<Category>(); | |
private String author; | |
private String name; | |
public Book() {} | |
public void setCategories(Set<Category> categories) { | |
this.categories = categories; | |
} | |
public Set<Category> getCategories() { | |
return categories; | |
} | |
public void setAuthor(String author) { | |
this.author = author; | |
} | |
public String getAuthor() { | |
return author; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getName() { | |
return name; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Controller | |
@RequestMapping("/mvvm/books") | |
@SessionAttributes({"booksVM"}) | |
public class BooksController { | |
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET) | |
public String index(ModelMap model) { | |
String[][] BOOKS = {{"The Very Hungry Caterpillar", "Eric Carle", | |
"Children,Classics,Animals"}, | |
{"The New Way Things Work", "David Macaulay", | |
"Education,Science,Computers"}, | |
{"The DASH Diet Younger You", "Marla Heller", | |
"Health,Fitness,Diets"}}; | |
BooksVM books = new BooksVM(); | |
books.setBooks(init(BOOKS)); | |
books.setCurrentBook(books.getBooks().get(0)); | |
model.addAttribute(books); | |
return "mvvm/index.zul"; | |
} | |
private LinkedList<Book> init(String[][] BOOKS) { | |
LinkedList<Book> books = new LinkedList<Book>(); | |
for (String[] book : BOOKS) { | |
books.add(initBook(book[0], book[1], book[2])); | |
} | |
return books; | |
} | |
private Book initBook(String name, String author, String categories) { | |
Book book = new Book(); | |
book.setName(name); | |
book.setAuthor(author); | |
String[] cates = categories.split(","); | |
Set<Category> sets = new LinkedHashSet<Category>(); | |
for (String cate : cates) { | |
Category c = new Category(); | |
c.setName(cate); | |
sets.add(c); | |
} | |
book.setCategories(sets); | |
return book; | |
} | |
@RequestMapping(value = "/addCate", method = RequestMethod.POST) | |
@ZKCommandLifecycle | |
public String doAddCategory(@ZKVariable Book fx, | |
@ZKSelector String cateName) { | |
Set<Category> categories = (Set<Category>) fx.getCategories(); | |
categories.add(new Category(cateName)); | |
return ZKModelAndView.SELF; | |
} | |
@RequestMapping(value = "/removeCate", method = RequestMethod.POST) | |
public String doRemoveCategory(@ZKVariable Book fx, | |
@ZKVariable Category each) { | |
Set<Category> categories = (Set<Category>) fx.getCategories(); | |
categories.remove(each); | |
return ZKModelAndView.SELF; | |
} | |
@RequestMapping(value = "/reset", method = RequestMethod.POST) | |
@ZKCommandLifecycle | |
public @ZKNotifyChange({"vm.currentBook"}) | |
ZKModelAndView onReset(@ModelAttribute BooksVM booksVM) { | |
ZKModelAndView model = new ZKModelAndView(); | |
model.addObject("vm", booksVM); | |
return model; | |
} | |
@RequestMapping(value = "/save", method = RequestMethod.POST) | |
@ZKCommandLifecycle | |
public @ZKNotifyChange({"editable", "currentBook"}) | |
BooksVM onSave(@ModelAttribute BooksVM booksVM) { | |
booksVM.setEditable(false); | |
return booksVM; | |
} | |
@RequestMapping(value = "/edit", method = RequestMethod.POST) | |
public @ZKNotifyChange("editable") | |
BooksVM edit(@ModelAttribute BooksVM booksVM) { | |
booksVM.setEditable(true); | |
return booksVM; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BooksVM { | |
private List<Book> books; | |
private Book currentBook; | |
private boolean editable; | |
public void setEditable(boolean editable) { | |
this.editable = editable; | |
} | |
public boolean getEditable() { | |
return editable; | |
} | |
public void setCurrentBook(Book book) { | |
currentBook = book; | |
} | |
public Book getCurrentBook() { | |
return currentBook; | |
} | |
public List<Book> getBooks() { | |
return books; | |
} | |
public void setBooks(List<Book> book) { | |
books = book; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Category { | |
private String name; | |
public Category() {} | |
public Category(String name) { | |
this.name = name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getName() { | |
return this.name; | |
} | |
public int hashCode() { | |
String name = getName(); | |
if (name == null) { | |
return 0; | |
} | |
return name.hashCode(); | |
} | |
public boolean equals(Object obj) { | |
if (obj == null) | |
return false; | |
if (obj instanceof Category) { | |
String oname = ((Category) obj).getName(); | |
String name = getName(); | |
if (oname == null) | |
return name == oname; | |
else | |
return oname.equals(name); | |
} | |
return false; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<zk xmlns:n="native" xmlns:x="xhtml"> | |
<style> | |
.z-listcell-content ul { padding: 10px 20px; margin: 0px; } | |
.icon-red { | |
color: red; | |
} | |
.icon-green { | |
color: green; | |
} | |
.edit-title { | |
position: absolute; | |
left: 0; | |
top: 12px; | |
font-size: 16px !important; | |
font-weight: bold; | |
} | |
button[disabled] .z-icon-undo { | |
color: grey; | |
} | |
</style> | |
<window border="normal" title="Books Management" xmlns:ca="client/attribute" | |
viewModel="@id('vm') @init(booksVM)"> | |
<hlayout> | |
<listbox id="list" model="@load(vm.books)" | |
selectedItem="@bind(vm.currentBook)" hflex="2"> | |
<listhead> | |
<listheader label="Name" /> | |
<listheader label="Author" /> | |
<listheader label="Categories" /> | |
</listhead> | |
<template name="model"> | |
<listitem> | |
<listcell label="@load(each.name)" /> | |
<listcell label="@load(each.author)"/> | |
<listcell> | |
<x:ul children="@load(each.categories)"> | |
<template name="children"> | |
<n:li> | |
<label value="@load(each.name)" /> | |
</n:li> | |
</template> | |
</x:ul> | |
</listcell> | |
</listitem> | |
</template> | |
</listbox> | |
<vlayout form="@id('fx') @load(vm.currentBook) @save(vm.currentBook, before='/save')" hflex="3"> | |
<toolbar align="end" mold="panel"> | |
<label sclass="edit-title" value="Book's Details"/> | |
<button iconSclass="z-icon-edit" tooltiptext="edit" | |
visible="@load(not vm.editable)" | |
ca:data-springmvc-action="edit" /> | |
<button iconSclass="z-icon-undo" | |
disabled="@load(not fxStatus.dirty)" | |
tooltiptext="reset" visible="@load(vm.editable)" | |
ca:data-springmvc-action="reset"/> | |
<button iconSclass="z-icon-save" | |
tooltiptext="submit" visible="@load(vm.editable)" | |
ca:data-springmvc-action="save"/> | |
</toolbar> | |
<grid hflex="1"> | |
<columns> | |
<column width="120px" /> | |
<column /> | |
</columns> | |
<rows children="@load(1) @template(vm.editable ? 'edit' : 'read')"> | |
<template name="read"> | |
<row> | |
Name: | |
<label value="@load(vm.currentBook.name)" /> | |
</row> | |
<row> | |
Author: | |
<label value="@load(vm.currentBook.author)" /> | |
</row> | |
<row> | |
Categories: | |
<x:ul | |
children="@load(vm.currentBook.categories)"> | |
<template name="children"> | |
<n:li> | |
<label value="@load(each.name)" /> | |
</n:li> | |
</template> | |
</x:ul> | |
</row> | |
</template> | |
<template name="edit"> | |
<row> | |
Name: | |
<textbox value="@bind(fx.name)" width="200px"/> | |
</row> | |
<row> | |
Author: | |
<textbox value="@bind(fx.author)" /> | |
</row> | |
<row> | |
Categories: | |
<cell> | |
<listbox model="@load(fx.categories)"> | |
<template name="model"> | |
<listitem> | |
<listcell> | |
<hlayout> | |
<textbox value="@bind(each.name)" /> | |
<a iconSclass="z-icon-minus-circle icon-red" | |
ca:data-springmvc-action="removeCate"/> | |
</hlayout> | |
</listcell> | |
</listitem> | |
</template> | |
</listbox> | |
<hlayout> | |
Add Category | |
<textbox id="cateName" width="150px" | |
value="@load(fx.resetEmptyStringValue, after={'/addCate', '/reset'})" /> | |
<a iconSclass="z-icon-plus-circle icon-green" | |
ca:data-springmvc-action="addCate" /> | |
</hlayout> | |
</cell> | |
</row> | |
</template> | |
</rows> | |
</grid> | |
</vlayout> | |
</hlayout> | |
</window> | |
</zk> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment