Search code examples
jqueryjquery-uiuser-interfacedroppable

jQuery droppable cannot be disabled


I have a strange problem with droppable. http://jsfiddle.net/samanth/dykcV/16/ This example works very well. Once I drop a div on the droppable, it does not allow me to drop anything else on that. I have the same piece of code in my application, but the droppable accepts drops.

I have an AJAX call before making a drop. Could this be a problem?

Here is my actual code.

$(".dropItem").droppable({
    accept:'.dragItem',
    hoverClass: 'hovered',

    drop:function (event, ui) {
        var answerNumber = $(this).attr( 'id' );
        var questionNumber = ui.draggable.attr( 'id' );

        $(this).append($(ui.draggable));

        //Send ajax query and get the response here..
        // generating form data

        send('matchAnswer?gameId=' + gameId + '&answerId=' + answerNumber + '&questionId=' + questionNumber, function (e) {
            if (this.status == 200) {
                var resp = this.responseText;
                if ( resp == "true" ) {
                    $(ui.draggable).css ({ position:"relative", top:"0px", left:"0px" }).draggable ("disable").css ({ opacity : 1 });
                    $(this).droppable('option', 'disabled', true);
                } else {
                    // do something here
                }
            }
        }, formData);
    }
});

Solution

  • The Ajax call is the problem. Let's break down what is happening:

    1. Draggable item gets dropped into a droppable item
    2. Your drop method appends the draggable item into the droppable item
    3. Your drop method then executes an ajax call
    4. When the ajax call completes and the status code is a 200 you do some minor css tweaks and then disable the ability of the droppable from receiving any more draggable items.

    The problem you outlined is that the droppable is allowing more than 1 draggable item to be placed inside of it. Therefore, the problem occurs with the Ajax call. Without being able to test it myself, I would say you are experiencing one of the following problems:


    Your AJAX call is never succeeding

    To check: Open firebug and check the response for your AJAX call


    Your AJAX call is returning with a status code that is NOT 200

    To check: Use firebug to debug the function that gets executed when the AJAX call returns. Is your status code 200?


    this keyword is not referencing the element you think it is

    To check: Use firebug to debug the function that gets executed when the AJAX call returns. What is the value of $(this)?

    If $(this) is not what you think it is, then I believe this javascript code will work for you:

    send('matchAnswer?gameId=' + gameId + '&answerId=' + answerNumber + '&questionId=' + questionNumber,
        $.proxy( function (e) {
        if (this.status == 200) {
            var resp = this.responseText;
            if ( resp == "true" ) {
                $(ui.draggable).css ({ position:"relative", top:"0px", left:"0px" }).draggable ("disable").css ({ opacity : 1 });
                $(this).droppable('option', 'disabled', true);
            } else {
                // do something here
            }
        }
    }, this), formData);
    

    The key in the code above is that I am using $.proxy to ensure that the function that gets executed will keep the correct scope. More information: http://api.jquery.com/jQuery.proxy/