Let us see how we can implement Moving the list box item up and down. In almost all the application, we need to change the order of the record that are displayed in the list. Say for an example, if you are defining questions for the subject/exam, then question order is very important. So this example shows how you can change the order of the question using up and down button.
Concepts used in this example
You can download the source here
Technologies Used
1. ZK 6.5 CE VersionReference
- http://www.zkoss.org/zkdemo/listbox/dual_listbox
- http://forum.zkoss.org/question/42954/listbox-refresh/
Project Name and Structure
MVVMListBoxMoveUpAndDownConcepts used in this example
- We have used List box to display two column listing.
- We also used the "emptyMessage" attribute is used to show a message when listbox contains no items.
- MVVM Design pattern
- We are using Listbox Template concept to display the data.
Step 1:
If you are new ZK, then you can setup the Development environment by downloading this document.Step 2:
Let us create the Project in eclipse. Click File -> New -> ZK Project . Let us name the project as MVVMListBoxMoveUpAndDown.Step 3:
Now let us add the domain class Questions.java as follows. Note: We will create a package called "zkMVVM" and then we will create our class "Questions" in that.package zkMVVM;
public class Questions {
private Integer questionOrder;
private String questionName;
public Questions() {
}
public Questions(Integer questionOrder, String questionName) {
this.questionOrder = questionOrder;
this.questionName = questionName;
}
public Integer getQuestionOrder() {
return questionOrder;
}
public void setQuestionOrder(Integer questionOrder) {
this.questionOrder = questionOrder;
}
public String getQuestionName() {
return questionName;
}
public void setQuestionName(String questionName) {
this.questionName = questionName;
}
}
Step 4:
We then define a service class to perform the business logic (QuestionService.java) shown below:.package zkMVVM;
import java.util.List;
public interface QuestionService {
/**
* Retrieve all questions in the catalog.
*
* @return all questions
*/
public List<Questions> findAll();
}
Step 5:
Next we create our implementation class for the above interface. For simplicity, it uses a static list object as the data model.package zkMVVM;
import java.util.LinkedList;
import java.util.List;
import org.zkoss.zul.Messagebox;
public class QuestionsServiceImpl implements QuestionService {
// data model
private List<Questions> questionsList = new LinkedList<Questions>();
private static int id = 1;
// initialize book data
public QuestionsServiceImpl() {
questionsList.add(new Questions(1, "What was your childhood nickname?"));
questionsList.add(new Questions(2, "In what city did you meet your spouse/significant other?"));
questionsList.add(new Questions(3, "What is the middle name of your oldest child?"));
questionsList.add(new Questions(4, "What is the name of the place your wedding reception was held?"));
questionsList.add(new Questions(5, "What year did you graduate from High School?"));
questionsList.add(new Questions(6, "What was the make and model of your first car?"));
questionsList.add(new Questions(7, "What is the name of the company of your first job?"));
}
public List<Questions> findAll() {
return questionsList;
}
}
Step 6:
Now we will add our listing zul file as follows<window title="Listitem MVVM Move up and Down" border="normal"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('myvm') @init('zkMVVM.QuestionsListVM')">
<hlayout>
<listbox id="questionListbox" model="@load(myvm.allQuestions)"
selectedItem="@bind(myvm.curSelectedQuestions)" width="1000px"
emptyMessage="No Question found in the result">
<listhead sizable="true">
<listheader label="Question Order" width="20%"
sort="auto(questionOrder)" />
<listheader label="Question" width="80%"
sort="auto(questionName)" />
</listhead>
<template name="model" var="p1">
<listitem>
<listcell label="@load(p1.questionOrder)" />
<listcell label="@load(p1.questionName)" />
</listitem>
</template>
</listbox>
<vbox>
<image style="cursor:pointer" id="upBtn"
onClick="@command('moveUp')" src="${imgPath}/uparrow_g.png" />
<image style="cursor:pointer" id="downBtn"
onClick="@command('moveDown')" src="${imgPath}/downarrow_g.png" />
</vbox>
</hlayout>
</window>
Step 7:
Next we will add our VM for the above zul file which will take of Move up and Move down.package zkMVVM;
import java.util.List;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
public class QuestionsListVM {
private List<Questions> result;
private QuestionService questionService = new QuestionsServiceImpl();
private Questions curSelectedQuestions;
private Integer curSelecteQuestionsIndex;
public Questions getCurSelectedQuestions() {
return curSelectedQuestions;
}
public void setCurSelectedQuestions(Questions curSelectedQuestions) {
this.curSelectedQuestions = curSelectedQuestions;
}
public Integer getCurSelecteQuestionsIndex() {
return curSelecteQuestionsIndex;
}
public void setCurSelecteQuestionsIndex(Integer curSelecteQuestionsIndex) {
this.curSelecteQuestionsIndex = curSelecteQuestionsIndex;
}
@AfterCompose
public void initSetup() {
result = questionService.findAll();
}
public List<Questions> getallQuestions() {
return result;
}
@Command
@NotifyChange("allQuestions")
public void moveUp() {
int selectedOrder;
int nextOrder;
// If no item is selected, then do nothing
if (curSelectedQuestions == null)
return;
// If selected item is in the first i.e index is eq to zero,
// then do nothing
int index = result.indexOf(curSelectedQuestions);
if (index == 0 || index < 0)
return;
// Store the currently selected item
Questions selectedItem = result.get(index);
// Take the next item
Questions nextItem = result.get(index - 1);
// Get the order for the currrently selected Item
selectedOrder = selectedItem.getQuestionOrder();
// Get the order for the next item of the selected item
nextOrder = nextItem.getQuestionOrder();
// Swap the order - In the real world, you can make a DB Call to do this
selectedItem.setQuestionOrder(nextOrder);
nextItem.setQuestionOrder(selectedOrder);
// Since we changed the order of the next item, we need to refresh the
// ZUL
result.set(result.indexOf(nextItem), nextItem);
// Remove the selected item from the list
result.remove(selectedItem);
// Add the selected item to the list in the next idex position
result.add(--index, selectedItem);
// Very Important, select the same item once we move down
setCurSelectedQuestions(selectedItem);
}
@Command
@NotifyChange("allQuestions")
public void moveDown() {
int selectedOrder;
int nextOrder;
// If no item is selected, then do nothing
if (curSelectedQuestions == null)
return;
// If selected item is in the last i.e index is eq to size of the list,
// then do nothing
int index = result.indexOf(curSelectedQuestions);
if (index == result.size() - 1 || index < 0)
return;
// Store the currently selected item
Questions selectedItem = result.get(index);
// Take the next item
Questions nextItem = result.get(index + 1);
// Get the order for the currrently selected Item
selectedOrder = selectedItem.getQuestionOrder();
// Get the order for the next item of the selected item
nextOrder = nextItem.getQuestionOrder();
// Swap the order - In the real world, you can make a DB Call to do this
selectedItem.setQuestionOrder(nextOrder);
nextItem.setQuestionOrder(selectedOrder);
// Since we changed the order of the next item, we need to refresh the
// ZUL
result.set(result.indexOf(nextItem), nextItem);
// Remove the selected item from the list
result.remove(selectedItem);
// Add the selected item to the list in the next idex position
result.add(++index, selectedItem);
// Very Important, select the same item once we move down
setCurSelectedQuestions(selectedItem);
}
}