capitombolare
capitombolare

Reputation: 25

jQuery: Counter for draggables (again!)

This is a follow up of the post:

JQuery Drag and Drop Count Content of Drop Area?

I'm rather new to programming so, apologies for a dull question. I am trying to count the number of draggable elements dropped in a a droppable. Rather than initialising a count variable at 0 and the increase/decrease the count each time a draggable drops in the droppable area, I am trying the (potentially) less troublesome strategy of try counting the total number of pills in the droppable. I've tried with ".count()", ".length" but no success... Here is the code. Any suggestions?

<!DOCTYPE html>
<html>
<head>
    <title>My Page</title>

    <meta charset="utf-8"> 

    <script type="text/javascript" src="js/jquery-1.11.2.js"></script>
    <script src="js/jquery-ui.js"></script>
    <script src="js/jquery.ui.touch-punch.js"></script>

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
    <script src="bootstrap/js/bootstrap.min.js"></script>


    <style>


        .fish  {

            margin:.5em;
            font-size:1.2em;
            position:relative;
            display:inline-block;
            -webkit-box-sizing:border-box;
            -moz-box-sizing:border-box;
            box-sizing:border-box;
            border-radius: 50%;

            width: 40px;
            height: 40px; 
            background: #BAB6B2;
            float: left;
            border:.3em  solid #4B027C ;
        }

        .cloth {
            width: 100%;
            height: 210px; 
            border-radius: 15px;
            border: 5% solid rgba(200,0,0,.5);

            background-color:white;
            background-image: linear-gradient(90deg, rgba(200,0,0,.5) 50%, transparent 50%),
            linear-gradient(rgba(200,0,0,.5) 50%, transparent 50%);
            background-size:20px 20px;
        }



    </style>

    <script type="text/javascript">
    $(init);


        function init() {
            var j = 0;
            $("#counter").find("h1").html("You keep: " + j);

            $(".fish").draggable({
                addClasses: true,
            });

            $(".cloth").droppable({
                accept: ".fish",
                tolerance: "fit",
                drop: function( event, ui ) {

                    j = $(".cloth  .fish").length;
                    $("#counter").find("h1").html("You keep: " + j);

                }, 
                out: function(){

                    j = $(" .cloth .fish ").length;
                    $("#counter").find("h1").html("You keep: " + j);

                }

            });



        }
    </script>


</head>
<body>


    <div class="container">


        <div  id= "counter"><h1>You keep: 0</h1></div>


        <div class="cloth" ></div>


        <div class = "row ">
            <div class="fish" ></div>
            <div class="fish" ></div>
            <div class="fish" ></div>
            <div class="fish" ></div>
            <div class="fish" ></div>

        </div>
        <div class ="row ">
        <div class="fish" ></div>
        <div class="fish" ></div>
        <div class="fish" ></div>
        <div class="fish" ></div>
        <div class="fish" ></div>
        </div>



    </div>

 <button type="button" class="btn btn-primary footpage" >Send!</button>

</body>
</html>

Upvotes: 2

Views: 1598

Answers (2)

Julien Gr&#233;goire
Julien Gr&#233;goire

Reputation: 17144

Your logic works, but there's one thing missing: you're never actually adding the .fish to the .cloth div. Dropping doesn't mean it's added to the droppable, it means that you can drop on that element and get the events related. If you want to add them you have to append them. This will mean modifying a bit your css and adding some behavior to deal with relative positioning vs absolute. And also out doesn't mean you remove the elements, it means they go out of the droppable region. So you can replace this part also. It could look like this:

function init() {
    var j = 0;
    $("#counter").find("h1").html("You keep: " + j);

    $(".fish").draggable({
        addClasses: true,
        refreshPositions: true,
        //When you start dragging you append to body mainly to remove
        // from cloth div
        start: function (e, ui) {
            ui.helper.appendTo('body');
        },
        //You move your out logic to stop. So if the element hasn't been added
        // to cloth, it won't be counter
        stop: function (e, ui) {
            j = $(".cloth  .fish").length;
            $("#counter").find("h1").html("You keep: " + j);
        }

    });

    $(".cloth").droppable({
        accept: ".fish",
        tolerance: "fit",
        drop: function (event, ui) {
            //On drop you append fish to the cloth div so it's counted
            $('.cloth').append(ui.helper.css({
                position: 'absolute',
                top: ui.helper.offset().top,
                left: ui.helper.offset().left
            }));
            j = $(".cloth  .fish").length;
            $("#counter").find("h1").html("You keep: " + j);

        },


    });



}

And the css:

.ui-draggable-dragging {
    position: absolute;
}

fiddle: https://jsfiddle.net/nL3axfd2/8/

That said, I'd look into previous answer, working with classes might simplify a lot this whole thing.

Upvotes: 1

omikes
omikes

Reputation: 8533

May not be of much help, but here's an example of how to add a class to objects which have been dropped on droppables. You may then count them based on that class with a jQuery selector:

    $("#draggable").draggable();
    $("#droppable").droppable({
        drop: function (event, ui) {
            $(event.toElement).addClass("ui-state-highlight")
                              .find("p")
                              .html("Dropped!"); 
        }
    });
<meta charset="utf-8">
<title>jQuery UI Droppable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
    #draggable {
        width: 100px;
        height: 100px;
        padding: 0.5em;
        float: left;
        margin: 10px 10px 10px 0;
    }
    #droppable {
        width: 150px;
        height: 150px;
        padding: 0.5em;
        float: left;
        margin: 10px;
    }
</style>
<body>
    <div id="draggable" class="ui-widget-content">
        <p>Drag me to my target</p>
    </div>
    <div id="droppable" class="ui-widget-header">
        <p>Drop here</p>
    </div>

Upvotes: 0

Related Questions