1

我正在設計一個表單構建界面。所有可用的字段將位於界面左側的無序列表中,右側有一個大的空白無序列表,它將成爲我的Web窗體。使這個接口工作的「訣竅」是讓左邊的列表項被轉換成有效的html元素,方法是在將html添加到右側的可排序列表中之前,將html附加到可放置的ui元素中。jQuery可拖拽排序,在丟棄元素上更改html

我有它的工作......主要是...使用draggable()和sortable()。目前,我使用可排序的接收事件從可拖動元素中獲取id,並將其放入data()塊以傳遞給更新事件。從那裏,我做了一個與id元素的ajax調用,確定它是什麼類型的字段,以及應該從後端添加什麼選項,構建元素,然後使用ui.item.html,它是一個元素傳遞的接口更新功能。

我的方法存在的問題是,當元素被拖拽時,它也會觸發,導致選擇元素在無意中追加到可排序列表時導致屏幕亂丟垃圾。顯然,接收事件是僅當排序從連接列表中獲取項目時觸發的事件。但是,如果我嘗試在內部HTML元素ui.item中更改源列表,而不是所需的目標。當項目已經在右側的webform列表中時,我絕對不希望修改它們,只要它們正在排序。

有什麼方法可以訪問和更改連接的sortable()列表接收事件中的目標html嗎?有沒有其他策略可以解決我的挑戰?

驗證碼:

<div class="grid_3 mainwindow formfields"> 

    <h3>Available Fields</h3> 
    <div id="accordion"> 
     <ul> 
      <li>First Name</li> 
      <li>Last Name</li> 
      <li>Company</li>    
     </ul> 
    </div> 

    </div> 
    </div> 

    <div class="grid_12 formcontainer formfields"> 
    <h3>Webform</h3> 
    <form id="form" action="http://responses.smarttracks.com" method="post"> 
     <input type="hidden" name="webform_id" id="webform_id" value="<?php echo $webform_id ?>"></input> 

     <ul id="webform_list"></ul> 
    </form> 
    </div> 

而jQuery的

/***** Make webform fields draggable *****/ 
    $(".master_list li").draggable({ 
     connectToSortable: "#webform_list", 
     helper: "clone", 
     revert: "invalid" 
    }); 

/***** Make form elements sortable *****/ 
    $("#webform_list").sortable({ 
     revert: true, 
     cursor: 'pointer', 
     placeholder: "placeholderdiv", 
     receive: function(event, ui) { 
      $(this).data('id', ui.item[0].id); 
      var element = event.target 


     }, 

     update: function(event, ui) { 
      var fieldname = ui.item.text(); 
      if ($(this).data('id')) { 

       $.ajax({ 
        url: "/webform/getFieldAttributes",     
        timeout: 30000, 
        type: "POST", 
        data: 'id='+$(this).data('id'), 
        dataType: 'json', 
        error: function(XMLHttpRequest, textStatus, errorThrown) { 
         alert("An error has occurred making the request: " + errorThrown) 
        }, 
        success: function(data){ 
         switch (data.control_type) { 
          case 'text': 
           var inputfield = $('<input type="text">').attr('id', 'fieldname'); 

           var field = (ui.item).text(); 

           switch (field) { 
            case 'Email Address': 
             inputfield.addClass('validate[optional,custom[email]]'); 
             break; 
            default: 
             inputfield.addClass('validate[required]'); 
             break; 
           } 

           break; 
          case 'textarea': 
           var inputfield = $('<textarea>'); 
           break; 
          case 'Dropdown Menu (Single Select)': 
           var inputfield = $('<select>'); 

           $.each(data.field_options, function(name, value) { 
            inputfield.append($("<option></option>").attr("value",name).text(value)) 
           }); 

           inputfield.addClass('validate[required]'); 
           break; 
          case 'Radio Buttons (Single Select)': 

           var inputfield = $('<div class="webform_radiogroup">'); 

           $.each(data.field_options, function(name, value) { 
            var container = $('<div class="webform_radio_option">'); 
            var radio = $('<input type="radio">').attr({ name: name,value: value,id: name }); 
            radio.appendTo(container); 
            $('<label for="'+name+'">'+name+'</label>').appendTo(container); 
            $('<div class="clear">').appendTo(container); 

            container.appendTo(inputfield); 
           }); 
           break; 
         } 

         if (data.control_type == 'Radio Buttons (Single Select)') { 
          ui.item.html('<div class="webform_radiogroup_label">'+fieldname+'</div>').append(inputfield).append('<div class="clear">').wrapInner('<div class="webform_questiongroup">').wrapInner('<div class="hoverdiv" />'); 
         } else { 
          ui.item.html('').append('<label for="'+fieldname+'">'+fieldname+'</label>').append(inputfield).wrapInner('<div class="hoverdiv" />'); 
         } 

        } 
       }); 
      } 
     } 
    }); 
+0

你可以加入你在JsFiddle中工作的東西,這樣我就能更好地理解它。 – Thaiscorpion

回答

6

而是使用可放開就這樣

$(".master_list li").draggable({ 
     connectToSortable: "#webform_list", 
     helper: "clone", 
     revert: "invalid" 
    }); 
    $("#webform_list").droppable({ 
     drop: function(event, ui) { 
      // your ajax code 
     } 
    }).sortable({ 
     handle : 'p', 
     cursor : 'crosshair' 
    }); 

我還沒有發佈完整的代碼,只給你粗略的想法工作。

2

您不需要使用接收方法都沒有。您可以從更新方法使用$(ui.item)

簡單地改變你的代碼訪問對象:

placeholder: "placeholderdiv", 
    // removed receive method 

    update: function(event, ui) { 

     var draggingElement = $(ui.item); 
     var fieldname = draggingElement.text(); 
     var fieldId = draggingElement.attr('id'); // or whatever you require. 

     if (fieldId) { 
      // etc... 

至於你的問題,事件觸發兩次,我都試圖複製這是JsFiddle,但我無法你能把你的代碼添加到小提琴嗎?

謝謝。