T5中使用自定义SelectMultiple组件
刚把东西都整理好了,已经贴进来了,不小心又给弄没了,气死我了,这次只把主要部分写出来,过程就不做过多描述,看代码是最直接的事情:
1,SelectMultiple类:
import org.apache.tapestry.MarkupWriter;import org.apache.tapestry.OptionModel;import org.apache.tapestry.SelectModel;import org.apache.tapestry.SelectModelVisitor;import org.apache.tapestry.annotations.BeforeRenderTemplate;import org.apache.tapestry.annotations.Parameter;import org.apache.tapestry.corelib.base.AbstractField;import org.apache.tapestry.ioc.annotations.Inject;import org.apache.tapestry.services.FormSupport;import org.apache.tapestry.services.Request;import xxx.models.SelectMultipleModelRenderer;/** * Multiple Select组件 * * @author guanyq * */public final class SelectMultiple extends AbstractField {private class Renderer extends SelectMultipleModelRenderer {public Renderer(MarkupWriter writer) {super(writer);}@Overrideprotected boolean isOptionSelected(OptionModel optionModel) {Object value = optionModel.getValue();return (_values == null) ? false : hasValue(value);}}private boolean hasValue(Object obj) {boolean bo = false;for (int i = 0; i < _values.length; i++) {if (_values[i].equals(obj)) {bo = true;break;}}return bo;}// 请求request@Injectprivate Request _request;// model@Parameter(required = true)private SelectModel _model;// 提交页面时,提交的值@Parameterprivate Object[] _values;// 选择框行数@Parameterprivate String _size;// 选择框样式@Parameterprivate String _style;@Override@SuppressWarnings("unchecked")protected void processSubmission(FormSupport formSupport, String elementName) {_values = _request.getParameters(elementName);}void afterRender(MarkupWriter writer) {writer.end();}void beginRender(MarkupWriter writer) {if (_size != null && _style != null)writer.element("select", "name", getElementName(), "id", getClientId(), "multiple", "multiple", "size", _size, "style", _style);else if (_size != null)writer.element("select", "name", getElementName(), "id", getClientId(), "multiple", "multiple", "size", _size);else if (_style != null)writer.element("select", "name", getElementName(), "id", getClientId(), "multiple", "multiple", "style", _style);else if (_style != null)writer.element("select", "name", getElementName(), "id", getClientId(), "multiple", "multiple");}@BeforeRenderTemplatevoid options(MarkupWriter writer) {SelectModelVisitor renderer = new Renderer(writer);_model.visit(renderer);}void setModel(SelectModel model) {_model = model;}void setValues(Object[] values) {_values = values;}}
?这个类切记要放在项目的components包下,否则页面使用时找不到该组件
?
2,SelectMultipleModelRenderer类:
import java.util.Map;import org.apache.tapestry.MarkupWriter;import org.apache.tapestry.OptionGroupModel;import org.apache.tapestry.OptionModel;import org.apache.tapestry.SelectModelVisitor;/** * 页面元素输出类 * * @author guanyq * */public class SelectMultipleModelRenderer implements SelectModelVisitor {private final MarkupWriter _writer;public SelectMultipleModelRenderer(final MarkupWriter writer) {_writer = writer;}public void beginOptionGroup(OptionGroupModel groupModel) {_writer.element("optgroup", "label", groupModel.getLabel());writeDisabled(groupModel.isDisabled());writeAttributes(groupModel.getAttributes());}public void endOptionGroup(OptionGroupModel groupModel) {_writer.end();}@SuppressWarnings("unchecked")public void option(OptionModel optionModel) {// 取得optionModel中存放的对象值(option的value)Object optionValue = optionModel.getValue();// 取得optionModel中存放的对象key(option的text)String optionLabel = optionModel.getLabel();_writer.element("option", "value", optionValue.toString());if (isOptionSelected(optionModel))_writer.attributes("selected", "selected");writeDisabled(optionModel.isDisabled());writeAttributes(optionModel.getAttributes());_writer.write(optionLabel);_writer.end();}private void writeDisabled(boolean disabled) {if (disabled)_writer.attributes("disabled", "disabled");}private void writeAttributes(Map<String, String> attributes) {if (attributes == null)return;for (Map.Entry<String, String> e : attributes.entrySet())_writer.attributes(e.getKey(), e.getValue());}protected boolean isOptionSelected(OptionModel optionModel) {return false;}}
?
3,GenericSelectionModel类:
import java.util.ArrayList;import java.util.List;import org.apache.tapestry.OptionGroupModel;import org.apache.tapestry.OptionModel;import org.apache.tapestry.internal.OptionModelImpl;import org.apache.tapestry.ioc.services.PropertyAccess;import org.apache.tapestry.util.AbstractSelectModel;/** * * @author guanyq * * @param <T> */public class GenericSelectionModel<T> extends AbstractSelectModel {// option textprivate String labelField;// option valueprivate String keyField;// 组装option的对象listprivate List<T> list;// 获取对象属性对象private final PropertyAccess adapter;public GenericSelectionModel(List<T> list, String labelField, String keyField, PropertyAccess adapter) {this.labelField = labelField;this.keyField = keyField;this.list = list;this.adapter = adapter;}public List<OptionGroupModel> getOptionGroups() {return null;}public List<OptionModel> getOptions() {if (list == null) {return null;}List<OptionModel> optionModelList = new ArrayList<OptionModel>();for (T obj : list) {if (labelField == null || labelField.equals("") || keyField == null || keyField.equals("")) {optionModelList.add(new OptionModelImpl(obj + "", false, obj, new String[0]));} else {optionModelList.add(new OptionModelImpl(adapter.get(obj, labelField) + "", false, adapter.get(obj, keyField) + "", new String[0]));}}return optionModelList;}}
??2和3两个类可以随便放在你想放的位置,只要程序能找到
页面类使用方法:
//原数据列表@SuppressWarnings("unchecked")public GenericSelectionModel getActSelect() {return new GenericSelectionModel<Act>((List) col, "alias", "ActId", adapter);}//空数据列表(选中后的保存列表)@SuppressWarnings("unchecked")public GenericSelectionModel getNullSelect() {return new GenericSelectionModel<Act>(null, "", "", null);}
?注意页面类要引入?
@Inject
?private PropertyAccess adapter;
?
其中col中存放的的是bean列表,如Act列表值,alias是需要在select中显示的text,ActId是select中的value(这2个值都是通过adapter读取bean获得对应值)
?
tml文件是否方法:
<!---原数据列表-><t:selectmultiple t:id="select1" model="ActSelect" size="4" style="literal:width:120px"/><!---空数据列表-><t:selectmultiple values="ActIds" t:id="select2" model="NullSelect" size="4" style="literal:width:120px">
?其中ActIds在页面类中定义一个list接受提交值即可
?
顺便贴出js代码:
/** * 多选下拉框,添加选项 */function addmen(){ var d = document.getElementById('select1'); var s = document.getElementById('select2'); for (var i = 0; i < d.options.length; i++) { if (d.options[i].selected) { var obj = new Option(d.options[i].text, d.options[i].value); s.options.add(obj); d.removeChild(d.options[i]); } } return false;}/** * 全部添加 */function allmen(){ var d = document.getElementById('select1'); var s = document.getElementById('select2'); for (var i = 0; i < d.options.length; i++) { s.options.add(new Option(d.options[i].text, d.options[i].value)); } for (var i = d.options.length - 1; i >= 0; i--) { d.removeChild(d.options[i]); }}/** * 取消选中项 */function returnmen(){ var d = document.getElementById('select1'); var r = document.getElementById('select2'); for (i = 0; i < r.options.length; i++) { if (true == r.options[i].selected) { var obj = new Option(r.options[i].text, r.options[i].value); r.removeChild(r.options[i]); d.options.add(obj); } } return false;}
?