2012-07-16 111 views
1

我正在学习构建JSF自定义组件,我想我可以尝试和构建一个实现的jQuery的拖动&拖..所以我读了大部分的东西,可以真正建立一个基本上产生jQuery的JS适量足够简单的可拖动和投掷的组件,支持将&下降,直到我可以在“拖动”对象和“投掷的”容器和几乎拖关联/左右下降东西..JSF自定义组件jQueryUI拖放

这很简单,我的问题是如何获得丢弃内容的“数据”,或者如何绑定到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

你的意思是排序?像这样? http://jqueryui.com/demos/sortable/ – Daniel 2012-07-16 09:10:50

+0

@Daniel,我实际上需要一步之前,我需要绑定jQuery下降事件'$(“.selector”).bind(“drop”,function(event, ui){ ... });'所以我可以创建我的自定义(好吧..它实际上结束了就像PrimeFaces ....)DragDropEvent并调用DE BB做一些与丢弃的项目.. – FMQ 2012-07-16 14:49:53

+0

嗨@FMQ,我对JSF中的自定义拖放组件也很感兴趣。您能否与我分享一些如何做的经验,或者一些教程或文档会非常感谢。先进的谢谢! – Sonn 2017-11-19 16:52:57

回答

0

为了您的例子,这是通过JSF传递从jQuery的事件数据到服务器的一种方式(其言自明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); 
} 
+0

@丹尼尔..是的...这应该工作,但我实际上正在尝试在我创建的自定义组件中实现此目的..例如PrimeFaces为“drop”事件生成此代码$(function() {PrimeFaces.cw( '可投放', 'widget_carForm_j_idt35',{ID: 'carForm:j_idt35',目标: 'carForm:selectedCars',activeClass: 'UI状态高亮',onDrop:handleDrop,公差: '触摸',行为:{drop:function(event){PrimeFaces。ab({source:'carForm:j_idt35',event:'drop',process:'carForm:j_idt35',update:'carForm:dropArea carForm:availableCars'},arguments [1]);}}});}) ;'这会生成一个DragDropEvent ... – FMQ 2012-07-16 16:40:26

+0

这部分是我无法理解的,它与我的组件有什么关系......我对问题的解释可能不清楚..如果是这样的话......请让我知道所以我可以尝试澄清我的问题......谢谢! – FMQ 2012-07-16 16:43:28

+0

dunno,看起来像一些构造函数('cw'),尝试调试js,然后...将断点放入'cw'中(或将'debugger;'放在函数内部)并调试代码以了解更多... – Daniel 2012-07-17 05:52:26

0

因为它turn's出来,有什么我失踪是jQuery的添加AJAX调用掉落事件引发中Droppable.java定义的“滴”事件....

writer.write(" jsf.ajax.request(this,event,{execute: '"); 
writer.write(getClientId() +"', sourceId: ui.draggable.attr('id') , targetId: $(this).attr('id')}); "); 

我仍然有生成的事件的问题(它不会生成的javax的实例.faces.behavior.event),但我猜我应该为此打开一个新的问题...