Column Chooser"
Line 280: | Line 280: | ||
[https://github.com/samchuang/zkcolumnchooser/blob/master/src/test/webapp/index.zul ZUL] | [https://github.com/samchuang/zkcolumnchooser/blob/master/src/test/webapp/index.zul ZUL] | ||
− | + | <source lang="xml" high="1"> | |
+ | <zk> | ||
+ | <window apply="org.zkoss.bind.BindComposer" border="normal" | ||
+ | viewModel="@id('vm') @init('demo.ProfileViewModel')" hflex="1" vflex="1"> | ||
+ | <caption label="Column Chooser"> | ||
+ | <!-- default column chooser --> | ||
+ | <columnchooser id="columnchooser" visibleColumns="@load(vm.visibleColumnLabels)" | ||
+ | hiddenColumns="@load(vm.hiddenColumnLabels)" | ||
+ | onColumnVisibilityChange="@command('doColumnVisibilityChange', visibleColumns=event.visibleColumns, hiddenColumns=event.hiddenColumns)"></columnchooser> | ||
+ | <combobutton label="Column Chooser" | ||
+ | onClick="@command('openDefaultColumnChooser', ref=self)"> | ||
+ | <!-- custom column chooser --> | ||
+ | <columnchooser template="/customColumnChooser.zul" | ||
+ | visibleColumns="@load(vm.visibleColumnLabels)" hiddenColumns="@load(vm.hiddenColumnLabels)" | ||
+ | onColumnVisibilityChange="@command('doColumnVisibilityChange', visibleColumns=event.visibleColumns, hiddenColumns=event.hiddenColumns)"></columnchooser> | ||
+ | </combobutton> | ||
+ | </caption> | ||
+ | <grid model="@load(vm.profiles)" height="500px"> | ||
+ | <columns children="@load(vm.visibleColumns)"> | ||
+ | <template name="children" var="columnInfo"> | ||
+ | <column label="@load(columnInfo.label)"></column> | ||
+ | </template> | ||
+ | </columns> | ||
+ | <template name="model" var="profile"> | ||
+ | <row children="@init(vm.visibleColumns) @template(each.templateName)"> | ||
+ | <template name="label" var="columnInfo"> | ||
+ | <label value="@load(profile[columnInfo.value])"></label> | ||
+ | </template> | ||
+ | <template name="birth" var="columnInfo"> | ||
+ | <datebox value="@load(profile[columnInfo.value])" | ||
+ | onChange="@command('setBirth', profile=profile, birth=event.target.value)"></datebox> | ||
+ | </template> | ||
+ | <template name="married" var="columnInfo"> | ||
+ | <checkbox checked="@load(profile[columnInfo.value])" | ||
+ | onCheck="@command('setMarried', profile=profile, married=event.checked)" | ||
+ | label="Married"></checkbox> | ||
+ | </template> | ||
+ | <template name="skills" var="columnInfo"> | ||
+ | <chosenbox model="@load(vm.allSkills)" | ||
+ | onSelect="@command('setSkills', profile=profile, skills=event.selectedObjects)" | ||
+ | selectedObjects="@load(profile[columnInfo.value])" hflex="true"> | ||
+ | <template name="model" var="item"> | ||
+ | <label value="@load(item)"></label> | ||
+ | </template> | ||
+ | </chosenbox> | ||
+ | </template> | ||
+ | </row> | ||
+ | </template> | ||
+ | </grid> | ||
+ | </window> | ||
+ | </zk> | ||
+ | </source> | ||
[https://github.com/samchuang/zkcolumnchooser/blob/master/src/test/java/demo/ProfileViewModel.java ProfileViewModel.java] | [https://github.com/samchuang/zkcolumnchooser/blob/master/src/test/java/demo/ProfileViewModel.java ProfileViewModel.java] |
Revision as of 10:57, 31 May 2013
Sam Chuang, Engineer, Potix Corporation
May 30, 2013
ZK 6.5 and later
Introduction
The Columnchooser is a popup component that shows a dialog of columns, group by column visibility, can be used with Grid, Listbox or any tabluar component. User can interact with the dialog to change column order or change column's visibility.
Columnchooser is base on ZK MVVM, with it's advantage: developer can easily customize the UI (dialog) without touching ViewModel's code.
Operation
Button
OK
The OK button is used to confirm modification change. If user doesn't click OK button, the modification will be lose, revert to previsous status.
Demonstraction:
- Original view
- After modification, click OK button to confirm.
- Result
Cancel
The Cancel button is used to revert to previsous status.
Demonstraction:
- Original view
- After modification, click Cancel button to revert.
- Result
Add to Visible Column
The Add button is used to move selected hidden column to visible column
Demonstraction:
- Original view
- Select a column, then click the Add button
- Click OK button to confirm
- Result
Remove Visible Column
The Remove button is used to move visible column to hidden column
Demonstraction:
- Original view
- Select a visible column, then click the Remove button
- Click OK button to confirm
- Result
Move Visible Column Up
The Move Up button is used to change column order, move select column up.
Demonstraction:
- Original view
- Select a visible column, then click the Move Up button
- Click OK button to confirm
- Result
Move Visible Column Down
The Move Down button is used change column order, move select column down.
Demonstraction:
- Original view
- Select a visible column, then click the Move Down button
- Click OK button to confirm
- Result
Drag & Drop
Drag Hidden Column to Visible Column
Demonstraction:
- Original view
- Drag hidden column, then drop at visible column area
- Click OK button to confirm
- Result
Drag Visible Column to Hidden Column
Demonstraction:
- Original view
- Drag visible column, then drop at hidden column area
- Click OK button to confirm
- Result
Drag Column and Drop on Any Column
Demonstraction:
- Original view
- Drag visible column, then drop at hidden column area
- Click OK button to confirm
- Result
Usage
Visible Columns and Hidden Columns
Invoke Columnchooser.setVisibleColumns(List<String> columns) and Columnchooser.setHiddenColumns(List<String> columns) to setup columns.
ZUL with MVVM
<columnchooser
visibleColumns="@load(vm.visibleColumnLabels)"
hiddenColumns="@load(vm.hiddenColumnLabels)" />
Java
public ArrayList<String> getVisibleColumnLabels() {
...
}
public ArrayList<String> getHiddenColumnLabels() {
...
}
Open Dialog
The Columnchooser is a popup component, invoke Columnchooser.open(Component ref, String position) to open dialog.
Event
When user made change and confrimed, Columnchooser will fire ColumnVisibilityChangeEvent event, the name of the event is onColumnVisibilityChange
ZUL
<columnchooser
visibleColumns="@load(vm.visibleColumnLabels)"
hiddenColumns="@load(vm.hiddenColumnLabels)"
onColumnVisibilityChange="@command('doColumnVisibilityChange',
visibleColumns=event.visibleColumns,
hiddenColumns=event.hiddenColumns)"></columnchooser>
Java
@Command
public void doColumnVisibilityChange(
@BindingParam("visibleColumns") List<String> visibleColumns,
@BindingParam("hiddenColumns") List<String> hiddenColumns) {
...
}
Template
Default
The Columnchooser contains a default implementation: columnchooser.zul
<zk xmlns:n="native">
<vlayout
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('org.zkoss.addon.columnchooser.impl.ColumnchooserViewModel')">
<n:span>Choose the fields to display.</n:span>
<hlayout>
<vlayout>
Available fields:
<listbox model="@load(vm.hiddenColumns)" width="150px"
height="200px" droppable="true" selectedItem="@bind(vm.selectedHiddenColumn)"
onDrop="@command('dropToHiddenColumns', column=event.dragged.value)">
...
</listbox>
</vlayout>
...
<vlayout>
Displayed Columns:
<listbox model="@load(vm.visibleColumns)" width="150px"
height="200px" droppable="true" selectedItem="@bind(vm.selectedVisibleColumn)"
onDrop="@command('dropToVisibleColumns', column=event.dragged.value)">
...
</listbox>
</vlayout>
</hlayout>
<hbox pack="end" width="100%" spacing="5px">
<button onClick="@command('ok')" label="OK" mold="trendy" width="75px"></button>
<button onClick="@command('cancel')" label="Cancel" mold="trendy" width="75px"></button>
</hbox>
</vlayout>
</zk>
The defualt implementation group columns by column visibility into two listbox.
Custom Template
Config template per instance
Developer can easily change the view by Columnchooser.setTemplate(String uri)
ZUL
<columnchooser template="/customColumnChooser.zul"
visibleColumns="@load(vm.visibleColumnLabels)"
hiddenColumns="@load(vm.hiddenColumnLabels)"
onColumnVisibilityChange="@command('doColumnVisibilityChange',
visibleColumns=event.visibleColumns,
hiddenColumns=event.hiddenColumns)"></columnchooser>
<zk xmlns:n="native">
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('org.zkoss.addon.columnchooser.impl.ColumnchooserViewModel')"
title="Edit Columns" border="normal" mode="highlighted" position="center">
<vlayout spacing="5px">
<label>Choose the fields to display.</label>
<hlayout spacing="10px">
<vlayout>
Available fields:
<listbox model="@load(vm.hiddenColumns)" width="150px"
height="200px" droppable="true" selectedItem="@bind(vm.selectedHiddenColumn)"
onDrop="@command('dropToHiddenColumns', column=event.dragged.value)">
...
</listbox>
</vlayout>
...
<vlayout>
Displayed Columns:
<listbox model="@load(vm.visibleColumns)" width="150px"
height="200px" droppable="true" selectedItem="@bind(vm.selectedVisibleColumn)"
onDrop="@command('dropToVisibleColumns', column=event.dragged.value)">
...
</listbox>
</vlayout>
</hlayout>
<hbox pack="end" width="100%" spacing="5px">
<button onClick="@command('ok')" label="OK" mold="trendy" width="75px"></button>
<button onClick="@command('cancel')" label="Cancel" mold="trendy" width="75px"></button>
</hbox>
</vlayout>
</window>
</zk>
Config template globally
Change the template view globaly by using library property org.zkoss.addon.columnchooser.template in zk.xml
<library-property>
<name>org.zkoss.addon.columnchooser.template</name>
<value>/customColumnChooser.zul</value>
</library-property>
View Model
The default template contains a default ColumnchooserViewModel that implements from Columnchooser.ViewModel
Develper can use customize ViewModel base on ColumnchooserViewModel or implements from Columnchooser.ViewModel
Grid with Columnchooser Demo
<zk>
<window apply="org.zkoss.bind.BindComposer" border="normal"
viewModel="@id('vm') @init('demo.ProfileViewModel')" hflex="1" vflex="1">
<caption label="Column Chooser">
<!-- default column chooser -->
<columnchooser id="columnchooser" visibleColumns="@load(vm.visibleColumnLabels)"
hiddenColumns="@load(vm.hiddenColumnLabels)"
onColumnVisibilityChange="@command('doColumnVisibilityChange', visibleColumns=event.visibleColumns, hiddenColumns=event.hiddenColumns)"></columnchooser>
<combobutton label="Column Chooser"
onClick="@command('openDefaultColumnChooser', ref=self)">
<!-- custom column chooser -->
<columnchooser template="/customColumnChooser.zul"
visibleColumns="@load(vm.visibleColumnLabels)" hiddenColumns="@load(vm.hiddenColumnLabels)"
onColumnVisibilityChange="@command('doColumnVisibilityChange', visibleColumns=event.visibleColumns, hiddenColumns=event.hiddenColumns)"></columnchooser>
</combobutton>
</caption>
<grid model="@load(vm.profiles)" height="500px">
<columns children="@load(vm.visibleColumns)">
<template name="children" var="columnInfo">
<column label="@load(columnInfo.label)"></column>
</template>
</columns>
<template name="model" var="profile">
<row children="@init(vm.visibleColumns) @template(each.templateName)">
<template name="label" var="columnInfo">
<label value="@load(profile[columnInfo.value])"></label>
</template>
<template name="birth" var="columnInfo">
<datebox value="@load(profile[columnInfo.value])"
onChange="@command('setBirth', profile=profile, birth=event.target.value)"></datebox>
</template>
<template name="married" var="columnInfo">
<checkbox checked="@load(profile[columnInfo.value])"
onCheck="@command('setMarried', profile=profile, married=event.checked)"
label="Married"></checkbox>
</template>
<template name="skills" var="columnInfo">
<chosenbox model="@load(vm.allSkills)"
onSelect="@command('setSkills', profile=profile, skills=event.selectedObjects)"
selectedObjects="@load(profile[columnInfo.value])" hflex="true">
<template name="model" var="item">
<label value="@load(item)"></label>
</template>
</chosenbox>
</template>
</row>
</template>
</grid>
</window>
</zk>
public class ProfileViewModel {
...
@Wire
Columnchooser columnchooser;
@Init
public void init() {
_columns = new ArrayList<ColumnInfo>();
_columns.add(new ColumnInfo("name", "Name", true, "label"));
_columns.add(new ColumnInfo("birth", "Birth", true, "birth"));
_columns.add(new ColumnInfo("married", "Marital status", false, "married"));
_columns.add(new ColumnInfo("skills", "Professional Skill", false, "skills"));
_data = provideData();
}
@AfterCompose
public void afterCompose(@ContextParam(ContextType.VIEW) Component view) {
Selectors.wireComponents(view, this, false);
}
@Command
public void openDefaultColumnChooser(@BindingParam("ref") Component ref) {
columnchooser.open(ref, "after_end");
}
public List<Profile> getProfiles() {
return _data;
}
public ArrayList<ColumnInfo> getVisibleColumns() {
return getColumns(Filter.VISIBLE);
}
public ArrayList<String> getVisibleColumnLabels() {
return transform(getVisibleColumns(), Transformer.TO_LABEL);
}
public ArrayList<ColumnInfo> getHiddenColumns() {
return getColumns(Filter.HIDDEN);
}
public ArrayList<String> getHiddenColumnLabels() {
return transform(getHiddenColumns(), Transformer.TO_LABEL);
}
@Command
@NotifyChange({"visibleColumns", "hiddenColumnLabels",
"profiles", "visibleColumnLabels", "hiddenColumnLabels"})
public void doColumnVisibilityChange(@BindingParam("visibleColumns") List<String> visibleColumns,
@BindingParam("hiddenColumns") List<String> hiddenColumns) {
...
}
...
}
- Line 9 ~12: all columns of the grid
- Line 24: open Columnchooser dialog
- Line 35, 43: column labels for Columnchooser
- Line 50: Columnchooser onColumnVisibilityChange event
Summary
In this smalltalk I have demonstrated how application developers can easily integrate Columnchooser component with Grid. The Columnchooser component is designed for take advantage of ZK MVVM, allow application developers to customize it extremely easily.
Download
You can get the complete source for the example used in this smalltalk from its github
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |