Skip to content

Instantly share code, notes, and snippets.

@jumperchen
Last active October 31, 2023 04:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jumperchen/f8342cf3b288989f0121 to your computer and use it in GitHub Desktop.
Save jumperchen/f8342cf3b288989f0121 to your computer and use it in GitHub Desktop.
ZK MVVM with Spring MVC Example
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;
}
}
@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;
}
}
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;
}
}
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;
};
}
<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