I am trying to implement a comboBox with multi-select feature. There will be a checkBox associated with each of the string and user can select one or many from the list. In GXT 2, we had CheckBoxListView which makes things easier.
I had follwing idea of implementing it.
Using a Grid which can have one column as CheckBox and other column as the string that i wnat to display and then adding the store of this grid to the CheckBoxStore. But, as the ListStore of Grid and ComboBoxes are not same, i tried it but no success, because both store are different and acceptd different properties.
There should be an alternate way like using ListView.But, i am not getting how can i use CheckBox in ListView
Need Help
This is my code.. Not perfect, but sort of temporary workaround..
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArrayString;
import client.grid.model.IComboBoxProperties;
import client.model.ComboBoxModel;
import com.sencha.gxt.cell.core.client.form.CheckBoxCell;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction;
import com.sencha.gxt.core.client.Style.HideMode;
import com.sencha.gxt.data.shared.LabelProvider;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.Window;
import com.sencha.gxt.widget.core.client.event.ExpandEvent;
import com.sencha.gxt.widget.core.client.event.HideEvent;
import com.sencha.gxt.widget.core.client.event.HideEvent.HideHandler;
import com.sencha.gxt.widget.core.client.form.ComboBox;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
public class MultiSelectBox extends ComboBox<ComboBoxModel>{
private Window checkBoxListHolder;
private Grid<ComboBoxModel> checkBoxGrid;
private ListStore<ComboBoxModel> listStore;
private boolean readOnly;
private ColumnConfig<ComboBoxModel, String> cc1;
private ColumnConfig<ComboBoxModel, Boolean> cc2;
private ComboBoxModel setData;
IComboBoxProperties props = GWT.create(IComboBoxProperties.class);
public MultiSelectBox(ListStore<ComboBoxModel> store,
LabelProvider<? super ComboBoxModel> labelProvider) {
super(store, labelProvider);
this.listStore=getStore();
this.checkBoxGrid=getCheckBoxGrid();
checkBoxListHolder = new Window(){
};
checkBoxListHolder.setClosable(false);
checkBoxListHolder.setHeaderVisible(false);
checkBoxListHolder.setResizable(false);
checkBoxListHolder.setAutoHide(true);
checkBoxListHolder.getButtonBar().setVisible(false);
checkBoxGrid.setVisible(true);
checkBoxGrid.focus();
checkBoxListHolder.add(checkBoxGrid);
checkBoxListHolder.addHideHandler(new HideHandler() {
@Override
public void onHide(HideEvent event) {
checkBoxGrid.getView().refresh(false);
checkBoxGrid.getStore().commitChanges();
clear();
setValue(parseCheckedValues(checkBoxGrid));
getCell().setTriggerAction(TriggerAction.ALL);
}
});
addExpandHandler(new ExpandEvent.ExpandHandler() {
@Override
public void onExpand(ExpandEvent event) {
if (checkBoxListHolder.isVisible()) {
checkBoxGrid.getView().refresh(false);
checkBoxGrid.getStore().commitChanges();
checkBoxListHolder.hide();
} else {
if(getValue()!=null)
{
setData=getValue();
updateGrid(setData);
}
else
{
updateGridStore(getStore());
}
checkBoxGrid.getStore().commitChanges();
checkBoxGrid.getView().refresh(false);
checkBoxListHolder.setPosition(getAbsoluteLeft(), getAbsoluteTop()+getOffsetHeight());
checkBoxListHolder.setSize(String.valueOf(getOffsetWidth()), "200");
checkBoxListHolder.show();
}
collapse();
}
});
}
private Grid<ComboBoxModel> getCheckBoxGrid()
{
ListStore<ComboBoxModel> gridStore = new ListStore<ComboBoxModel>(props.key());
for(int i=0;i<listStore.size();i++)
{
gridStore.add(new ComboBoxModel(listStore.get(i).getKey(),listStore.get(i).getValue(),false));
}
gridStore.commitChanges();
List<ColumnConfig<ComboBoxModel,?>> configs = getColumnConfig();
ColumnModel<ComboBoxModel> cm = new ColumnModel<ComboBoxModel>(configs);
final Grid<ComboBoxModel> grid = new Grid<ComboBoxModel>(gridStore, cm){
};
grid.setBorders(false);
grid.getView().setStripeRows(false);
grid.getView().setAutoFill(true);
grid.getView().setColumnLines(false);
grid.setHideHeaders(true);
return grid;
}
private List<ColumnConfig<ComboBoxModel,?>> getColumnConfig(){
List<ColumnConfig<ComboBoxModel,?>> columns = new ArrayList<ColumnConfig<ComboBoxModel,?>>();
cc2 =new ColumnConfig<ComboBoxModel,Boolean>(props.checked(),20,"Select");
cc2.setCell(new CheckBoxCell(){
});
columns.add(cc2);
cc1 = new ColumnConfig<ComboBoxModel,String>(props.getValue(),50,"Choose Properties");
columns.add(cc1);
return columns;
}
private ComboBoxModel parseCheckedValues(Grid<ComboBoxModel> grid) {
ListStore<ComboBoxModel> list = grid.getStore();
ComboBoxModel m = new ComboBoxModel();
String buf="";
String keys="";
if (list != null) {
for(int i=0;i<list.size();i++){
if(list.get(i).getChecked().booleanValue())
{
buf=buf+list.get(i).getValue();
buf=buf+",";
keys=keys+list.get(i).getKey();
keys=keys+",";
}
}
if (buf.length() > 0 && buf.charAt(buf.length()-1)==',') {
buf = buf.substring(0, buf.length()-1);
}
if (keys.length() > 0 && keys.charAt(keys.length()-1)==',') {
keys = keys.substring(0, keys.length()-1);
}
}
m.setKey(keys);
m.setValue(buf);
return m;
}
public JsArrayString getSelectedItems() {
JsArrayString result = (JsArrayString) JsArrayString.createArray();
ListStore<ComboBoxModel> store=checkBoxGrid.getStore();
if (store != null){
for(int i=0;i<store.size();i++){
if(store.get(i).getChecked().booleanValue())
{
result.push(store.get(i).getKey());
}
}
}
return result;
}
public List<ComboBoxModel> getSelectedItemCombos() {
List<ComboBoxModel> list = new ArrayList<ComboBoxModel>();
ListStore<ComboBoxModel> store=checkBoxGrid.getStore();
if(store!=null){
for(int i=0;i<store.size();i++){
if(store.get(i).getChecked().booleanValue())
{
list.add(store.get(i));
}
}
}
return list;
}
public void setCheckedItems(List<ComboBoxModel> list){
ListStore<ComboBoxModel> liststore = checkBoxGrid.getStore();
for(int i=0;i<liststore.size();i++)
{
for(int j=0;j<list.size();j++)
{
if(checkBoxGrid.getStore().get(i).getKey().equals(list.get(j).getKey()) && checkBoxGrid.getStore().get(i).getValue().equals(list.get(j).getValue()))
{
checkBoxGrid.getStore().get(i).setChecked(true);
break;
}
else
checkBoxGrid.getStore().get(i).setChecked(false);
}
}
checkBoxGrid.getStore().commitChanges();
setValue(parseCheckedValues(checkBoxGrid));
}
public void clearCheckedItems(){
for (int i =0; i< checkBoxGrid.getStore().size(); i++){
checkBoxGrid.getStore().get(i).setChecked(false);
}
}
private ArrayList<ComboBoxModel> getSelectedValues(ComboBoxModel model)
{
ArrayList<ComboBoxModel> list = new ArrayList<ComboBoxModel>();
String [] values=model.getValue().split(",");
String [] keys = model.getKey().split(",");
int i=0;
int len=values.length;
for(i=0;i<len;i++)
{
list.add(new ComboBoxModel(keys[i],values[i],true));
}
return list;
}
private void updateGrid(ComboBoxModel model)
{
String [] values=model.getValue().split(",");
String [] keys = model.getKey().split(",");
int i=0;
int len=values.length;
ListStore<ComboBoxModel> list = checkBoxGrid.getStore();
for(i=0;i<list.size();i++)
{
for(int j=0;j<len;j++)
{
if(checkBoxGrid.getStore().get(i).getKey().equals(keys[j]) && checkBoxGrid.getStore().get(i).getValue().equals(values[j]))
{
checkBoxGrid.getStore().get(i).setChecked(true);
break;
}
else
checkBoxGrid.getStore().get(i).setChecked(false);
}
}
checkBoxGrid.getStore().commitChanges();
}
public boolean isReadOnly() {
return readOnly;
}
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
public ListStore<ComboBoxModel> getListStore() {
return listStore;
}
public void setListStore(ListStore<ComboBoxModel> listStore) {
this.listStore = listStore;
}
private void updateGridStore(ListStore<ComboBoxModel> store)
{
checkBoxGrid.getStore().clear();
for(int i=0;i<store.size();i++)
{
checkBoxGrid.getStore().add(newComboBoxModel(listStore.get(i).getKey(),listStore.get(i).getValue(),false));
}
checkBoxGrid.getStore().commitChanges();
}
}