1

私はJSFカスタムコンポーネントを構築することを学んでおり、jQueryのドラッグ&ドロップの実装を試して構築できると思っていました. 「ドラッグ可能な」オブジェクトと「ドロップ可能な」コンテナを関連付けて、ほとんどのものをドラッグ/ドロップできるようになるまで、ドラッグアンドドロップをサポートするjQuery jsの量..

これはかなり単純でした。私の問題は、ドロップされているものの「データ」を取得する方法、またはjQueryが生成するドロップイベントにバインドする方法です...十分に簡単であることはわかっています。正しい方向(ドキュメント/コードサンプル)私はそれを非常に感謝しています...

私がしなければならないと思うだけのコードを貼り付けます..あなたが私がしたことを見ることができるように..私は多くを共有することができます(実際に貼り付けられたもの以上のものではありません..)誰かがそれを必要とする場合...

(ご覧のとおり、ajaxイベントをバインドできます..それを呼び出す方法がわかりません..)。

ティア..

コンポーネント...

@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;
    }


}
4

2 に答える 2

0

結局のところ、私が見逃していたのは、Droppable.java...で定義された「drop」イベントを発生させるjQuerydropイベントでのAjax呼び出しを追加することです。

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

生成されたイベントにまだ問題があります(javax.faces.behavior.eventのインスタンスは生成されません)が、これについて新しい質問を開く必要があると思います...

于 2012-07-17T16:41:17.433 に答える
0

あなたの例では、これはJSFを介してjqueryイベントからサーバーにデータを渡す1つの方法です(自明の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);
}
于 2012-07-16T15:04:20.447 に答える