PDA

View Full Version : Radio button ListView



VadimV1144
25 Jan 2010, 12:37 AM
Here is a little widget that may be useful. I have modified the CheckBoxListView to :
a) Allow user to check multiple boxes without holding down the 'Ctrl' key.
b) Display the Radio buttons instead of the Checkboxes.



import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.core.XTemplate;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ListViewEvent;
import com.extjs.gxt.ui.client.widget.CheckBoxListView;
import com.extjs.gxt.ui.client.widget.ListViewSelectionModel;
import com.google.gwt.user.client.Element;

import java.util.Arrays;
import java.util.List;

public class XRadioListView<M extends ModelData> extends CheckBoxListView<M> {
private Boolean isRadio = false;
private String groupName = "";
private String selectionProperty = "";

private static final String CHECKED_PROPERTY_ID = "checked";

/**
* Default Constructor. Sets the XListViewSelectionModel as default model
* for this instance.
*/
public XRadioListView(){
super();
setSelectionModel(new XListViewSelectionModel<M>());
}

/**
* Sets the type of the buttons that will be displayed by this view.
* As wells as the button group name.
* @param isRadio - if true Radio buttons are displayed, otherwise display CheckBoxes
* @param groupName - button group name
*/
public void setRadio(Boolean isRadio, String groupName){
this.isRadio = isRadio;
this.groupName = groupName == null?"":groupName;
if(getSelectionModel() instanceof XListViewSelectionModel){
((XListViewSelectionModel)getSelectionModel()).setKeepExisting(!isRadio);
}
}

/**
* Return the selection property
* @return property of the model that will be set/unset on the selection event
*/
public String getSelectionProperty() {
return selectionProperty;
}

/**
* Set the selection property
* @param selectionProperty will be set/unset on every selection event
*/
public void setSelectionProperty(String selectionProperty) {
if(selectionProperty != null && !selectionProperty.isEmpty())
this.selectionProperty = selectionProperty;
}

/**
* Initialise the button based on the selectionProperty
* If the selectionProperty is set, the button will be selected
* @param model is the bean model that associated with the given button
*/
public void initSelection(M model){
if(!selectionProperty.isEmpty()){
if(model.<Boolean>get(selectionProperty)) {
this.getSelectionModel().select(model, true);
}
//model.set(CHECKED_PROPERTY_ID, getCheckedValue());
}
}

/**
* Sets the selectionProperty on the model based on the select value (true or false)
* Sets the button selection based on the select value (this is necessary to handle the case
* when the user clicks on the label and not the actual button)
*
* @param model - selected model
* @param select - selection type - true if selected, false if deselected
*/
protected void onSelectChange(M model, boolean select){
if(!selectionProperty.isEmpty()){
model.set(selectionProperty, select);
}
model.set(CHECKED_PROPERTY_ID,getCheckedValue(select));
super.onSelectChange(model, select);
}

protected void onRender(Element target, int index) {
String spacing = GXT.isIE ? "0" : "3";
String type = isRadio?"radio":"checkbox";
setTemplate(XTemplate.create("<tpl for=\".\"><div class='x-view-item x-view-item-check'>"
+ "<table cellspacing='" + spacing + "' cellpadding=0> "
+ "<tr>"
+ "<td>"
+ "<input class=\"x-view-item-checkbox\" type=\"" + type + "\" name=\"" + groupName + "\" {" + CHECKED_PROPERTY_ID + "}/>"
+ "</td>"
+ "<td>{" + getDisplayProperty() + "}"
+ "</td>"
+ "</tr></table></div></tpl>"));
super.onRender(target, index);
}

private String getCheckedValue(boolean checked){
return checked?"checked":"";
}

public class XListViewSelectionModel<M extends ModelData> extends ListViewSelectionModel<M> {
private Boolean keepExisting = false;

public Boolean isKeepExisting() {
return keepExisting;
}

public void setKeepExisting(Boolean keepExisting) {
this.keepExisting = keepExisting;
}

/**
* Replaces the passed argument keepExisting with the local keepExisting.
*
* Note: This is necessary to allow user to select multiple options without
* holding the Ctrl button
*/
protected void doSelect(List<M> models, boolean keepExisting, boolean supressEvent) {
super.doSelect(models, this.keepExisting, supressEvent);
}

/**
* Bypass the check for the Ctrl button press.
*
* Note: This is necessary to allow user to select multiple options without
* holding the Ctrl button
*/
@SuppressWarnings("unchecked")
protected void handleMouseClick(ListViewEvent<M> e) {
if (isLocked() || e.getIndex() == -1) {
return;
}
if (!e.isRightClick() && selectionMode == Style.SelectionMode.MULTI) {
M sel = listStore.getAt(e.getIndex());
if (isSelected(sel)) {
doDeselect(Arrays.asList(sel), false);
} else {
handleMouseClick(e);
}
}
}
}
}


In order for the checkboxes to display in a ListView format add the following to your CSS:


#checkbox-view .x-view-item {
float: left;
margin: 4px;
margin-right: 0;
padding: 5px;
}

Arno.Nyhm
26 Jan 2010, 9:35 AM
interesting. you have a screenshot?

VadimV1144
26 Jan 2010, 9:45 AM
Here is a screen, both the radio buttons list and check boxes list are XRadioListView instances.

18448

Arno.Nyhm
26 Jan 2010, 10:20 AM
i replay your example with a copy of checkboxlistview and get not so nice results.

it is also possible to post your example code for creating the items?

chould the "#checkbox-view" not be better a css class .checkbox-view so i can addStyleName this to many objects?

VadimV1144
26 Jan 2010, 11:07 AM
Oh yes, I call
panel.setId("checkbox-view");, where panel is a ContentPanel that contains the radio button list.

VadimV1144
26 Jan 2010, 11:40 AM
Here is a full example, just import for the XRadioListView



import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.data.*;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.layout.FlowData;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

import java.util.ArrayList;
import java.util.List;

public class RadioButtonListViewEntry implements EntryPoint {
@Override
public void onModuleLoad() {
LayoutContainer lc = new LayoutContainer();

Modifier ex1 = new Modifier();
ex1.setName("Exclusive Mod 1");
ex1.setItems(getModItemsList(true));
lc.add(getModifierPanel(ex1, true),new FlowData(10));

Modifier com1 = new Modifier();
com1.setName("Combinatorial Mod 1");
com1.setItems(getModItemsList(true));
lc.add(getModifierPanel(com1, false),new FlowData(10));
RootPanel.get().add(lc);
}


private ContentPanel getModifierPanel(final Modifier mod, final Boolean isRadio){

MemoryProxy<List<ModifierItemRecord>> proxy = new MemoryProxy<List<ModifierItemRecord>>(mod.getItems());
ListLoader<ListLoadResult<ModifierItemRecord>> loader = new BaseListLoader<ListLoadResult<ModifierItemRecord>>(proxy, new BeanModelReader());
ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
loader.load();
final XRadioListView<BeanModel> view = new XRadioListView<BeanModel>() {
@Override
protected BeanModel prepareData(BeanModel model) {
String s = model.get("name");
model.set("shortName", s + " ()");
initSelection(model);
return model;
}

};
view.setRadio(isRadio, mod.getName());
view.setStore(store);
view.setWidth(370);
view.setSelectionProperty("selected");
view.setDisplayProperty("shortName");

view.getSelectionModel().setSelectionMode(isRadio? Style.SelectionMode.SINGLE:Style.SelectionMode.MULTI);
view.getSelectionModel().addListener(Events.SelectionChange,
new Listener<SelectionChangedEvent<BeanModel>>() {
public void handleEvent(SelectionChangedEvent<BeanModel> be) {
view.refresh();
}

});

final ContentPanel panel = new ContentPanel();
panel.setId("checkbox-view");
panel.setCollapsible(false);
panel.setHideCollapseTool(true);
panel.setAnimCollapse(false);
panel.setFrame(true);
panel.setHeading(mod.getName());
panel.setWidth(400);
panel.setHeight(400);
panel.setAutoHeight(true);
panel.setBodyBorder(false);
panel.add(view);

return panel;
}
class Modifier implements BeanModelTag {
protected String name = "";
protected List<ModifierItemRecord> items = new ArrayList<ModifierItemRecord>();

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List<ModifierItemRecord> getItems() {
return items;
}

public void setItems(List<ModifierItemRecord> items) {
this.items = items;
}
}

class ModifierItemRecord implements BeanModelTag {
private String name = "";
private Boolean selected = false;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Boolean isSelected() {
return selected;
}

public void setSelected(Boolean selected) {
this.selected = selected;
}
}

private List<ModifierItemRecord> getModItemsList(boolean selected){
List<ModifierItemRecord> list = new ArrayList<ModifierItemRecord>();

ModifierItemRecord mod1 = new ModifierItemRecord();
mod1.setSelected(selected);
mod1.setName("Modifier 1");
list.add(mod1);

ModifierItemRecord mod2 = new ModifierItemRecord();
mod2.setName("Modifier 2");
list.add(mod2);

ModifierItemRecord mod3 = new ModifierItemRecord();
mod3.setName("Modifier 3");
list.add(mod3);

ModifierItemRecord mod4 = new ModifierItemRecord();
mod4.setName("Modifier 4");
list.add(mod4);

ModifierItemRecord mod5 = new ModifierItemRecord();
mod5.setName("Modifier 5");
list.add(mod5);

return list;
}
}