-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Take a java List of "employees" in a listbox or grid. User clicks on one to edit it OR to use it as a baseline to do a new "Add" of an employee. For example, I select John Doe from a list, it opens in an edit form but I change the name and a few fields and then hit "Add" and want this to be a new record.
Currently I'm constantly handling this by always creating a "copy" of the object when an object is selected from my list and then upon submit if it's an edit, I go and copy back the fields (using BeanUtils) to the appropriate list item.. of it's an add, I can now just add the new object to my list.
This works but seems quite cumbersome. I know there is the use of the form tag but I'm not sure how it could make a distinction if validation passes as to "yes go ahead and update the reference" vs "stop, make a copy and add it to the list without having modified the original object you clicked on."
I'm sure others run into this so curious how others tackle this?
You can add a "edit" property in VM, create a new instance if user click "add" button.
public class AddUpdateVM {
List<User> users;
User selected;
User edit;
public AddUpdateVM() {
users = new ArrayList<User>();
for (int i = 0; i < 5; i++) {
users.add(new User("user" + i));
}
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public void setSelected(User selected) {
this.selected = selected;
}
public User getSelected() {
return selected;
}
public User getEdit() {
return edit;
}
public void setEdit(User edit) {
this.edit = edit;
}
@Command
@NotifyChange({"edit", "selected"})
public void add() {
if (selected != null) {
edit = new User(selected.getName());
//new user not save into list yet, save into list when click "save" button
selected = null;
}
}
@Command
@NotifyChange("edit")
public void update() {
edit = selected;
}
@Command
@NotifyChange({"edit", "selected", "users"})
public void doSave() {
if (selected == null) {//add new user to list
users.add(edit);
}
selected = edit;
edit = null;
}
}
zul
<zk>
<window apply="org.zkoss.bind.BindComposer" viewmodel="@id('vm') @init('test.AddUpdateVM')" form="@id('fx') @load(vm.edit) @save(vm.edit, before='doSave')">
<textbox value="@bind(fx.name)" visible="@load(not empty vm.edit)"></textbox>
<button label="Save" onClick="@command('doSave')" visible="@load(not empty vm.edit)"></button>
<button label="Add" onClick="@command('add')" visible="@load(empty vm.edit)"></button>
<button label="Update" onClick="@command('update')" visible="@load(empty vm.edit)"></button>
<listbox model="@load(vm.users)" selectedItem="@bind(vm.selected)">
<template name="model" var="user">
<listitem label="@load(user.name)"/>
</template>
</listbox>
</window> </zk>
(admin's sorry for posting in the answer section, but I need the room to post some code that I tried and want it follow in context with samchaung's response so don't want to edit my initial post)
Thanks samchuang for your suggestions, they gave me a lot to think about. Your code works because the user is forced to decide up front if one is wants to do an "add" or "update" - the user has to first click 'add' or 'update' before doing the save. This enables you to make the copy up front when the user clicks add, and allows you keep the selected as the reference for edit when the user clicks update.
In the scenario I'm referring to, I want the user to be able to just click the User row (setSelected) and have it populate the form immediately. After its populated I want the user to be able to make the choice at that point whether they want to "save" (causing an update of the record) OR "add as new" - create a new User to the list. I still can't find a way to do this without copying first upon setUserSelected and then again on the save.
I have an example here to illustrate what I'd like to do
http://zkfiddle.org/sample/5hi2ti/2-UpdateAddFormHavingToCopy
You'll see the issue is that in setSelected, if I do not copy the User to the edit reference, when the user then does an 'add' the user is still modifying the selected reference because setting edit = selected still forces the pointer to still be there.
Asked: 2013-04-24 16:57:14 +0800
Seen: 58 times
Last updated: Sep 08 '16
Maybe it gives you a good feeling: I do exactly the same. And I am also using forms.
Matze2 ( 2013-04-27 00:19:52 +0800 )edit