1

フォーム構築インターフェースを設計しています。使用可能なすべてのフィールドは、インターフェイスの左側の順序付けられていないリストにあり、右側には大きな空の順序付けられていないリストがあり、これが Web フォームになります。このインターフェイスを機能させるための「トリック」は、右側の並べ替え可能なリストに追加される直前に、ドロップ可能な ui 要素に html を追加することにより、左側のリスト項目を有効な html 要素に変換することです。

私はそれを機能させています...ほとんど... draggable()とsortable()を使用しています。現在、sortable の receive イベントを使用してドラッグ可能な要素から ID を取得し、それを data() ブロックに入れて update イベントに渡します。そこから、id 要素を使用して ajax 呼び出しを行い、フィールドのタイプとバックエンドから追加する必要があるオプションを決定し、要素を構築してから、 を使用してインターフェイスに配置しますui.item.html。更新機能。

私の方法の問題は、要素がドラッグされたときにも起動することです。これにより、select 要素が意図せずに並べ替え可能なリストに追加されたときに画面が散らかります。明らかに、受信イベントは、並べ替えが接続されたリストからアイテムを取得したときにのみ発生するイベントです。ただし、ui.item要素を HTML 内に挿入しようとすると、目的のターゲットではなく、ソース リストが変更されます。項目が既に右側の Web フォーム リストにある場合、それらが並べ替えられているだけであれば、それらを変更したくはありません。

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" />');
                        }

                    }
                });
            }
        }   
    });
4

2 に答える 2

6

代わりに、このように droppable を使用します

    $( ".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'
   });

コード全体を投稿したわけではありません。大まかなアイデアを提供しただけです。

于 2012-11-10T06:07:21.743 に答える
3

receive メソッドを使用する必要はまったくありません。を使用して update メソッドからオブジェクトにアクセスできます。$(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...

イベントが 2 回発生するという問題については、これをJsFiddleで複製しようとしましたが、コードをフィドルに追加できませんか?

ありがとう。

于 2012-11-08T00:57:29.127 に答える