0

jquery ui のドラッグ アンド ドロップを使用したコード例を次に示します: http://jsfiddle.net/kwMpH/7/

「承認レベルの表示」ボタンは、どのユーザー バブルがどのボックスに該当するかを表示しようとします。うまくいくようですが、それを壊すことができるシナリオがあります:

  1. 1 つの要素を最初の承認レベルにドラッグします。
  2. 「承認レベルの追加」をクリックします
  3. 別の要素を取り、新しく作成された承認レベルに追加します
  4. バブルをレベル 2 からレベル 1 に移動し、[承認レベルの表示] をすばやくクリックします。

私が detach と appendTo を使用している理由は、この古い投稿と同じ「フォーム送信」要件であることは注目に値します。

コードは次のとおりです。

    <div class="container">
    <div class="topInstructions">Drag and Drop a one or more categories of users to one or more approval levels.</div>
    <div class="workFlowNameArea">
        <div class="workFlowNameSubArea">
            <div style="font-weight:bold;">Work Flow Name</div>
            <div>
                <input type="text" name="workFlowName" id="workFlowName" maxlength="100" width="50" />
            </div>
        </div>
        <div class="workFlowNameSubArea" style="margin-left: 20px; margin-top: 17px;">
            <input id="saveButton" type="button" value="Save" />
        </div>
        <div class="workFlowNameSubArea" style="margin-left: 20px; margin-top: 17px;">
            <input id="addApprovalLevel" type="button" value="Add Approval Level" />
        </div>
        <div class="workFlowNameSubArea" style="margin-left: 20px; margin-top: 17px;">
            <input id="showState" type="button" value="Show State" />
        </div>
        <div class="workFlowNameSubArea" style="margin-left: 20px; margin-top: 17px;">
            <input id="appLevel" type="button" value="Show approval Levels" />
        </div>
    </div>
    <div class="dropGroup">
        <div id="approval1" class="approvalText">Approval Level 1
            <div id="deleteApproval1" class="deleteApproval" style="visibility: hidden;">
                <img src="/images/redX.gif" />
            </div>
            <div id="droppable1" class="droppable"></div>
        </div>
        <div id="arrow1" class="arrow">
            <img src="/images/arrow_in_circle_down.png" />
        </div>
        <div id="ellipsis1" class="ellipsis">
            <img src="/images/ellipsis.png" />
        </div>
    </div>
    <div class="choices">
        <div class="approvalText">Categories</div>
        <div class="draggable" title="click and drag to an approval level" style="background: #CC0000; color: #fff;">System Administrators</div>
        <div class="draggable" title="click and drag to an approval level" style="background: #FF9933; color: #000;">Administrators</div>
        <div class="draggable" title="click and drag to an approval level" style="background: #FFFF00; color: #000;">Managers</div>
        <div class="draggable" title="click and drag to an approval level" style="background: #99FF66; color: #000;">Instructors</div>
        <div class="draggable" title="click and drag to an approval level" style="background: #66CCFF; color: #000;">School Administrators</div>
        <div class="draggable" title="click and drag to an approval level" style="background: #6600FF; color: #fff;">Users</div>
        <div class="clonable" title="click to create a custom group" style="background: #999; color: #fff;">Custom</div>
    </div>
</div>
.draggable {
    width: 100px;
    height: 35px;
    display: inline-block;
    margin-top: 10px;
    margin-bottom: 10px;
    border: 2px solid #000;
    border-radius: 15px;
    -webkit-border-radius: 15px;
    -khtml-border-radius: 15px;
    -moz-border-radius: 15px;
    text-align: center;
    line-height: normal;
    vertical-align: middle;
    font-weight: bold;
    font-family: arial;
    font-size: 12px;
    cursor: pointer;
}
.clonable {
    width: 100px;
    height: 35px;
    display: inline-block;
    margin-top: 10px;
    margin-bottom: 10px;
    border: 2px solid #000;
    border-radius: 15px;
    -webkit-border-radius: 15px;
    -khtml-border-radius: 15px;
    -moz-border-radius: 15px;
    text-align: center;
    line-height: normal;
    vertical-align: middle;
    font-weight: bold;
    font-family: arial;
    font-size: 12px;
    cursor: pointer;
}
.droppable {
    width: 150px;
    height: 75px;
    margin: 10px;
    border-color: #999;
    color: #999;
    border-style: dashed;
    margin-left: auto;
    margin-right: auto;
}
.topInstructions {
    position: relative;
    float: top;
    margin-top: 5px;
    margin-bottom: 10px;
    text-align: center;
    font-family: arial;
    font-size: 16px;
}
.dropGroup {
    position: relative;
    float: right;
    margin-right: 100px;
    color: #999;
    text-align: center;
    width: 300px;
    height: 450px;
    margin-top: 5px;
}
.choices {
    position: relative;
    text-align: center;
    float: left;
    width: 150px;
    height: 430px;
    margin-left: 75px;
    margin-top: 5px;
}
.approvalText {
    color: #999;
    font-family: arial;
    font-size: 12px;
}
.deleteApproval {
    color: red;
    display: inline-block;
    cursor: hand;
    cursor: pointer;
}
.workFlowNameArea {
    position: relative;
    float: top;
    width: 680px;
    margin-left: 75px;
    margin-bottom: 15px;
}
.workFlowNameSubArea {
    display: inline-block;
    float: left;
}
.container {
    width: 680px;
    position: relative;
}
var globalElement;

$(document).ready(function () {

    $(".draggable").draggable({
        helper: "clone",
        revert: true,
        containment: "document",
        start: function (event, ui) {
            globalElement = $(this);
        },
        stop: function (event, ui) {
            globalElement = null;
        }
    });

    $(".droppable").droppable({
        accepts: ".draggable",
        tolerance: "intersect",
        drop: function (event, ui) {
            dropFunction($(this), event, ui);
        }
    }).hover(function () {
        if ($(this).find(".draggable").length < 1) {

        }
    });

    $(".choices").droppable({
        accepts: ".draggable",
        tolerance: "intersect",
        drop: function (event, ui) {
            dropFunction($(this), event, ui);
        }
    });

    $(".clonable").click(function () {
        //TODO pop up for user list
    });
    $(".startOverButton").click(function () {
        // is this possible?
    });
    $("#addApprovalLevel").click(function () {
        addNextApprovalLevel();
    });
    $("#saveButton").click(function () {
        saveWorkflow();
        console.log("approval levels\n");
        $(".droppable").each(function (index) {
            console.log((index + 1) + ":" + $(this).find(".draggable").length + ":" + $(this).find(".draggable").text());
        });
    });
    $("#showState").click(function () {
        alert(state);
    });
    $("#appLevel").click(function () {
        // this does not work in drop function but does work here... maybe because drop is not completely done?
        //console.log("approval levels");
        for (i = 0; i < 1000; i++){}
        var str = "approval levels";
        $(".droppable").each(function (index) {
            str += "" + (index + 1) + ":" + $(this).find(".draggable").length + ":" + $(this).find(".draggable").text() + "\n";
        });
        alert(str);

    });

});

var state = new Array();


function dropFunction(jObj, event, ui) {

    if (globalElement != null) {
        ui.helper.fadeOut();
        globalElement.detach().appendTo(jObj);
        $(jObj).css("border-color", "#999");

        drpGroup = $(".dropGroup").height();
        net = 0;
        $.each($(".droppable"), function (i, drp) {
            oldHeight = $(drp).height();
            newHeight = ($(drp).find(".draggable").length * 45) + 75;
            $(drp).css("height", newHeight);
            net += newHeight - oldHeight;
            //console.log("old = " + oldHeight + ", new = " + newHeight + ", net = " + net);
        });
        drpGroup += net;
        $(".dropGroup").css("height", drpGroup);
        //console.log("new drop group height = " + $(".dropGroup").height());
    } else {
        //console.log("too fast!");
    }
}

function addNextApprovalLevel() {
    var curHighest = $(".droppable").length;
    $("#ellipsis" + curHighest).remove();
    var nextLevelNum = curHighest + 1;
    var newApprovalText = "<div id='approval" + nextLevelNum + "'>Approval Level " + nextLevelNum + "&nbsp;&nbsp;<div id='deleteApproval" + nextLevelNum + "' class='deleteApproval'><img src='/images/redX.gif' /></div>" + "</div>";

    var newApprovalBox = $("<div id='droppable" + nextLevelNum + "' class='droppable'>" + "</div>");
    //$("#droppable" + curHighest).clone().attr("id", "droppable" + nextLevelNum);


    $(newApprovalBox).droppable({
        accepts: ".draggable",
        tolerance: "intersect",
        drop: function (event, ui) {
            dropFunction($(this), event, ui);
            //$("#droppable1").css("height", $("#droppable1").find(".draggable").length * 75);
            //console.log($("#droppable1").find(".draggable").length + "\n" +
            //      $("#droppable1").find(".draggable").text() );
        }
    });
    $("#arrow" + curHighest).css("margin-bottom", "5px");
    $(".dropGroup").append(newApprovalText);
    $(".dropGroup").append(newApprovalBox);
    var newArrow = "<div id='arrow" + nextLevelNum + "' class='arrow'><img src='/images/arrow_in_circle_down.png' /></div>";
    var newEllipsis = "<div id='ellipsis" + nextLevelNum + "' class='ellipsis'><img src='/images/ellipsis.png' /></div>";
    $(".dropGroup").append(newArrow);
    $(".dropGroup").append(newEllipsis);
    $(".dropGroup").css("height", $(".dropGroup").height() + 170);

    $("#deleteApproval" + nextLevelNum).click(function () {
        if ($("#droppable" + nextLevelNum).parent().find(".draggable").length >= 1) {
            alert("A user category must first be removed before an approval level can be deleted.");
        } else {
            deleteApprovalBox($(this));
        }
    });
}

function deleteApprovalBox(jqAppBox) {
    level = parseInt($(jqAppBox).attr("id").substring("deleteApproval".length));
    $("#approval" + level).remove();
    $("#droppable" + level).remove();
    $("#arrow" + level).remove();
    level++;
    while ($("#approval" + level).length) {
        $("#approval" + level).html("Approval Level " + (level - 1) + "&nbsp;&nbsp;<div id='deleteApproval" + (level - 1) + "' class='deleteApproval'><img src='/images/redX.gif' /></div>");
        $("#approval" + level).attr("id", "approval" + (level - 1));
        $("#droppable" + level).attr("id", "droppable" + (level - 1));
        $("#arrow" + level).attr("id", "arrow" + (level - 1));

        $("#deleteApproval" + (level - 1)).click(function () {
            if ($("#droppable" + (level - 1)).parent().find(".draggable").length >= 1) {
                alert("A user category must first be removed before an approval level can be deleted.");
            } else {
                deleteApprovalBox($(this));
            }
        });
        level++;
    }
    level--;
    if ($("#ellipsis" + level).length == 1) {
        $("#ellipsis" + level).attr("id", "ellipsis" + (level - 1));
    }
}

function saveWorkflow() {


    // validate the name    
    var alphaNum = new RegExp(/^([\sa-zA-Z0-9_-]+)$/);
    if ($("#workFlowName").val().length < 1) {
        alert("Work flow name must be between 1 and 100 characters.");
        return false;
    }
    if (!alphaNum.test($("#workFlowName").val())) {
        alert("Invalid Work flow name.  Must have numbers or letters.");
        return false;
    }

    // check if there are no empty

    // check if any approval levels are empty
    if ($(".droppable").length > 1) {
        $.each($(".droppable"), function (i, drp) {
            //console.log(i + ":" + $(drp).find(".draggable").length);
            if ($(drp).find(".draggable").length < 1) {
                $(drp).css("border-color", "red");
                alert("Approval Level " + (i + 1) + " is empty.  Delete?");
                // TODO, implement an approval level delete method hooked into the NO of the YES/NO             
                return;
            }
        });
    }

    //var findResult = $("#droppable1").find(".draggable");

    // remove ellipis... do we need to do this?
    //var curHighest = $(".droppable").length;
    //$("#ellipsis" + curHighest).remove();
}
4

1 に答える 1