我正在学习构建JSF自定义组件,我想我可以尝试构建一个jQuery的Drag& amp; Drop ..所以我阅读了大部分内容并且实际上可以构建一个足够简单的Draggable和Droppable组件,基本上生成适当数量的jQuery js来支持Drag&直到我可以将“draggable”对象和“droppable”容器关联起来并且几乎可以拖拽/放下东西..
这很简单,我的问题是如何获取被删除内容的“数据”,或者如何绑定到jQuery生成的drop事件...我知道它应该很容易,所以如果有人能指出我在正确的方向(文件/代码样本)我非常感谢...
我会像我想的那样粘贴很少的代码......只是这样你就可以看到我做了什么..我可以分享很多东西(真的粘贴的东西不多......)如果有人需要的话......
(正如你所看到的,我可以绑定一个ajax事件..我只是无法弄清楚如何调用它。)。
TIA ..
...成分
@FacesComponent(Draggable.COMPONENT_TYPE)
public class Draggable extends UIComponentBase {
public static final String COMPONENT_TYPE = "ar.com.easytech.Draggable";
public static final String DEFAULT_RENDERER_TYPE = "ar.com.easytech.DraggableRenderer";
public static final String COMPONENT_FAMILY = "javax.faces.Output";
public String getFamily() {
return COMPONENT_FAMILY;
}
public String getFor() {
return (String) getStateHelper().eval(PropertyKeys.forVal);
}
...
protected enum PropertyKeys {
forVal("for"), draggableSelector, revert, containTo;
String c;
PropertyKeys() {
}
PropertyKeys(String c) {
this.c = c;
}
public String toString() {
return ((this.c != null) ? this.c : super.toString());
}
}
@Override
public void encodeEnd(FacesContext facesContext) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
String clientId = getClientId(facesContext);
UIComponent targetComponent = findComponent(getFor());
if(targetComponent == null)
throw new FacesException("Cannot find component \"" + getFor());
String target = targetComponent.getClientId();
writer.startElement("script", null);
writer.writeAttribute("id", clientId + "_s", null);
writer.writeAttribute("type", "text/javascript", null);
writer.write("$(function() {");
writer.write("$( '#" + target.replace(":", "\\\\:") + "').draggable({");
if (getRevert() != null) writer.write(" revert: '" + getRevert() + "', ");
if (getContainTo() != null) writer.write(" containment: '" + getContainTo() + "',");
writer.write("});");
writer.write("});");
writer.endElement("script");
}
}
Droppable.java
@FacesComponent(Droppable.COMPONENT_TYPE)
public class Droppable extends UIComponentBase implements ClientBehaviorHolder {
public static final String COMPONENT_TYPE = "ar.com.easytech.Droppable";
public static final String DEFAULT_RENDERER_TYPE = "ar.com.easytech.DroppableRenderer";
public static final String COMPONENT_FAMILY = "javax.faces.Output";
private final static String DEFAULT_EVENT = "drop";
private static final Collection<String> EVENT_NAMES = Collections.unmodifiableCollection(Arrays.asList(DEFAULT_EVENT));
public String getFamily() {
return COMPONENT_FAMILY;
}
// Property: for
public String getFor() {
return (String) getStateHelper().eval(PropertyKeys.forVal);
}
...
protected enum PropertyKeys {
forVal("for"), droppableSelector, activeClass, hoverClass, accept, tolerance, source;
String c;
PropertyKeys() {
}
// Constructor needed by "for" property
PropertyKeys(String c) {
this.c = c;
}
public String toString() {
return ((this.c != null) ? this.c : super.toString());
}
}
@Override
public void queueEvent(FacesEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
if (isRequestSource(context)) {
Map<String, String> params = context.getExternalContext()
.getRequestParameterMap();
String eventName = params.get("javax.faces.behavior.event");
String clientId = getClientId(context);
AjaxBehaviorEvent behaviorEvent = (AjaxBehaviorEvent) event;
if (eventName.equals("drop")) {
String dragId = params.get(clientId + "_sourceId");
String dropId = params.get(clientId + "_targetId");
DragDropEvent dndEvent = null;
String datasourceId = getSource();
if (datasourceId != null) {
UIData datasource = (UIData) findComponent(datasourceId);
String[] idTokens = dragId.split(String
.valueOf(UINamingContainer
.getSeparatorChar(context)));
int rowIndex = Integer
.parseInt(idTokens[idTokens.length - 2]);
datasource.setRowIndex(rowIndex);
Object data = datasource.getRowData();
datasource.setRowIndex(-1);
dndEvent = new DragDropEvent(this,
behaviorEvent.getBehavior(), dragId, dropId, data);
} else {
dndEvent = new DragDropEvent(this,
behaviorEvent.getBehavior(), dragId, dropId);
}
super.queueEvent(dndEvent);
}
} else {
super.queueEvent(event);
}
}
@Override
public Collection<String> getEventNames() {
return EVENT_NAMES;
}
@Override
public String getDefaultEventName() {
return DEFAULT_EVENT;
}
@Override
public void decode(FacesContext context) {
if (context == null ) {
throw new NullPointerException();
}
String clientId = getClientId(context);
Map<String, String> requestParameterMap = context.getExternalContext().getRequestParameterMap();
String value = (String) requestParameterMap.get(clientId);
if (value == null || value.equals("") || !clientId.equals(value))
return;
ActionEvent actionEvent = new ActionEvent(this);
queueEvent(actionEvent);
}
@Override
public void encodeEnd(FacesContext context) throws IOException {
ClientBehaviorContext behaviorContext =
ClientBehaviorContext.createClientBehaviorContext(context,this, DEFAULT_EVENT, getClientId(context), null);
ResponseWriter writer = context.getResponseWriter();
String clientId = getClientId(context);
UIComponent targetComponent = findComponent(getFor());
if(targetComponent == null)
throw new FacesException("Cannot find component \"" + getFor());
String target = targetComponent.getClientId();
writer.startElement("script", null);
writer.writeAttribute("id", clientId + "_s", null);
writer.writeAttribute("type", "text/javascript", null);
writer.write("$(function() {");
writer.write("$( '#" + target.replace(":", "\\\\:") + "').droppable({");
if (getActiveClass() != null) writer.write(" activeClass: '" + getActiveClass() + "',");
if (getHoverClass() != null) writer.write(" hoverClass: '" + getHoverClass() + "',");
if (getAccept() != null) writer.write(" accept: '" + getAccept() + "',");
if (getTolerance() != null) writer.write(" tolerance: '" + getTolerance() + "',");
Map<String,List<ClientBehavior>> behaviors = getClientBehaviors();
if (behaviors.containsKey(DEFAULT_EVENT) ) {
String drop = behaviors.get(DEFAULT_EVENT).get(0).getScript(behaviorContext);
writer.writeAttribute("drop:", drop, null);
}
writer.write("});");
writer.write("});");
writer.endElement("script");
}
// Private
private boolean isRequestSource(FacesContext context) {
return this.getClientId(context).equals(context.getExternalContext().getRequestParameterMap() .get("javax.faces.source"));
}
}
这个用法就像......
<h:form id="frm">
<div id="container" class="container">
<ui:repeat var="row" value="#{homeBean.data}" id="dnd" >
<h:panelGroup layout="block" id="draggable" styleClass="draggable">
<h:outputText value="#{row}" />
</h:panelGroup>
<et:draggable for="draggable" draggableSelector=".draggable" containTo="parent" revert="invalid" />
</ui:repeat>
<h:panelGroup layout="block" id="droppable" styleClass="droppable">
<p>Drop Here!</p>
</h:panelGroup>
</div>
<h:dataTable id="selectedItems" var="data" value="#{homeBean.selectedRows}">
<h:column>
<h:outputText value="#{data.name}" />
</h:column>
</h:dataTable>
<et:droppable for="droppable" droppableSelector=".droppable" hoverClass="ui-state-hover" activeClass="ui-state-active" >
<f:ajax listener="#{homeBean.objectDropped}" render="@form" event="drop" />
</et:droppable>
</h:form>
HomeBean.java
@ManagedBean
public class HomeBean {
private List<String> data = new ArrayList<String>();
private List<String> selectedRows = new ArrayList<String>();
@PostConstruct
public void init() {
data.add("Value 1");
data.add("Value 2");
}
public void objectDropped(DragDropEvent event) {
selectedRows.add(event.getSourceId());
}
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
public List<String> getSelectedRows() {
return selectedRows;
}
public void setSelectedRows(List<String> selectedRows) {
this.selectedRows = selectedRows;
}
}
答案 0 :(得分:0)
在您的示例中,这是将数据从jquery事件通过JSF传递到服务器(其自解释的INMO)的一种方法
$( ".selector" ).bind( "drop", function(event, ui) {
$("#myInputHiddenID").val("someJsonStringCanBePlacedHereForExample");
$("#myButtonID").click();
});
<h:commandButton id="myButtonID" action="#{myBean.myAction()}" style="display:none" >
<f:ajax></f:ajax>
<h:inputHidden id="myInputHiddenID" value="#{myBean.myStringData}" />
</h:commandButton>
public void myAction() {
System.out.println(myStringData);
}
答案 1 :(得分:0)
当它结束时,我缺少的是在jQuery drop事件上添加一个Ajax Call,它引发了Droppable.java中定义的“drop”事件....
writer.write(" jsf.ajax.request(this,event,{execute: '");
writer.write(getClientId() +"', sourceId: ui.draggable.attr('id') , targetId: $(this).attr('id')}); ");
我仍然遇到生成事件的问题(它不会生成javax.faces.behavior.event的实例),但我想我应该为此打开一个新问题......