首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

HTML5 复合组件,第 2 部分 实现拖放-6

HTML5 复合组件,第 2 部分 实现拖放-6

有条件拖拉在  中,我将 Feeds 应用程序中的保存链接列表作为一个链表实现了,这意味着,用户可以添加同一文章的副本。我想要禁止这一行为,如图 7 所示。注意所托拉标题上的光标没有变成一个加号,就像  中的成功放置一样。
图 7. 禁用一个放置(光标不表示复制)为了禁用副本放置,我修改了 <h5:drop> 组件的 drag-enter 和 drag-over 事件处理程序来接受有条件放置,如清单 11 所示:
清单 11. <h5:drop> 组件的 JavaScript,Take III
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
if (!html5)
   var html5 = {}
if (!html5.jsf) {
   html5.jsf = {
      init : function(ccid, payloadType, renderIds) {
         var dropzone = $(ccid);


         if (dropzone.serverPayload) // already initialized
            return;
         
         dropzone.payloadInput = $(ccid + ":form:payload");
         dropzone.acceptDrop = false;
         dropzone.serverPayload = function() {
            return dropzone.payloadInput.value;
         };

         dropzone.addEventListener("drop", function(event) {
            if (payloadType == "")
               payloadType = "text";

            if (renderIds == "" || renderIds == "@this")
               renderIds = ccid;

            dropzone.payloadInput.value = event.dataTransfer
                  .getData(payloadType);
            
            jsf.ajax.request(dropzone.payloadInput, event, {
               render: renderIds
               onevent : function(data) {
                   if (data.status == "success")
                      html5.jsf.init(ccid, payloadType, renderIds);
                }
            });            
         }, false);

         dropzone.addEventListener("dragenter", function(event) {
            if (dropzone.acceptDrop)
               event.preventDefault();
         }, false);

         dropzone.addEventListener("dragover", function(event) {
            if (dropzone.acceptDrop)
               event.preventDefault();
         }, false);
      }
   };
   }




@Inject注意  中的 @Inject 注释。它提供对 rssFeed 托管的 bean 的访问。JSF 应用程序通常需要在 Java 代码中访问这些托管的 bean。您可以使用 JSF 和 JSP Expression Language API 来访问那些托管的 bean,或者仅使用 @Inject 注释。

在  小节,我主要关注将拖放负载从客户端传递到服务器端。为了接受有条件放置,我必须背道而驰:将信息从服务器端发送回客户端。在这种情况下,我需要访问保存链接列表,以便于我可以确定链接是否是一个副本。因此,为了将必要数据从服务器端传送回客户端,我添加了一个 serverPayload 变量到 dropzone。
为了将保存链接列表发送回服务器,我将一个含有保存链接标题的字符串存储在放置目标的不可见文本输入中,通过 DragDrop.getPayload() 实现,如清单 12 所示:
清单 12.  payload 属性的 getter 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.clarity;

// imports omitted. See <a href="#listing10">清单 10</a>.

@Named
@SessionScoped
public class DragDrop implements Serializable {
   @Inject private RSSFeed rssFeed;

   public DragDrop() {
   }
   
   public String getPayload() {
      // sends a string that is a concatenation of the saved
      // item's titles, back to the client
      LinkedList<RSSItem> savedItems = rssFeed.getSavedItems();
      Iterator<RSSItem> it = savedItems.iterator();
      String s = "";
      
      while (it.hasNext()) {
         RSSItem item = it.next();
         s += item.getTitle() + " | ";
      }
      return s;
   }
   
   public void setPayload(String payload) {
      // creates a new saved item, based on the payload. Payload
      // was set in the drop event listener for the h5:drop component
      // in /sections/feeds/menuLeft.xhtml
      StringTokenizer st = new StringTokenizer(payload);
      RSSItem item = new RSSItem();
      
      item.setTitle(st.nextToken("|"));
      st.nextToken(" ");
      item.setLink(st.nextToken(" "));
      
      rssFeed.getSavedItems().add(item);
   }
}




下一次初始化一个拖拉时,应用程序的拖拉源从服务器端检查负载(当然,这是不可见文本输入值),确任拖拉链接是否是一个副本,如清单 13 所示:
清单 13. 拖拉源,Take II
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:h5="http://java.sun.com/jsf/composite/html5"
   xmlns:places="http://java.sun.com/jsf/composite/places">

   <script>
      // event.target is one of the h5:drag elements generated by ui:repeat below
       function dragStart(event) {
          var linkref = event.target.firstElementChild.firstElementChild; // anchor
          var link = linkref.href;
          var title = linkref.textContent;

          var dropzone = $("dropzone"); // h5:drop in dropZone.xhtml
          dropzone.acceptDrop = true;         
                     
          var serverPayload = dropzone.serverPayload();
          if (serverPayload.indexOf(title) != -1)
           dropzone.acceptDrop = false; // link already present
                        
          event.dataTransfer.setData('text', title + " | " + link + " ");
      }
    </script>

   <h:panelGrid columns="1" id="items">
     <ui:repeat value="#{rssFeed.items}" var="item">

       <h5:drag ondragstart="dragStart(event)">
        <p>
          <a href="#{item.link}">#{item.title}</a> <br />
        </p>
      </h5:drag>

      </ui:repeat>
   </h:panelGrid>

</ui:composition>




如果拖拉的链接是一个副本,拖拉源的 JavaScript 将放置目标的 acceptDrop 属性设置为 false。放置随后被放置源取消。
返回列表