m0onio
m0onio

Reputation: 213

making draggable snap left when dropped

**EDIT**

I am currently creating a drag and drop spelling game where the user drags letters onto the highlighted word in order to spell it and reveal the image behind.

When a word is highlighted by the style ".spellword", it indicates to the user to spell that word. When the user goes to drag a letter into that area he/she can drag the letter anywhere in the 3 letter space, but I need them to be dropped from "left" to "right" to ensure the word is spelt in the correct order.

Basically when a letter is dropped onto the word I need it to snap to the left (first letter of the word) and then the next letter dropped snaps onto the next letter of the word etc...so it is spelt in the correct order

What can I do to ensure this?

The script for the draggable and droppable is...

$('.drag').draggable({
helper: 'clone',
snap: '.drop',
grid: [62, 62],
revert: 'invalid',
snapMode: 'corner',
start: function(){
    var validDrop = $('.drop-box.spellword');
    validDrop.addClass('drop');
    makeDroppables();
}
});


function makeDroppables(){   
$('.drop').droppable({
drop: function(event, ui) {
    word = $(this).data('word');
    guesses[word].push($(ui.draggable).attr('data-letter'));

    if ($(this).text() == $(ui.draggable).text().trim()) {

        $(this).addClass('wordglow3');
    } else {
        $(this).addClass('wordglow');
    }


    if (guesses[word].length == 3) {
        if (guesses[word].join('') == word) {
            $('td[data-word=' + word + ']').addClass('wordglow2');

        } else {
            $('td[data-word=' + word + ']').addClass("wordglow4");
            guesses[word].splice(0, guesses[word].length);
        }
    }
},


activate: function(event, ui) {
    word = $(this).data('word');

    // try to remove the class
    $('td[data-word=' + word + ']').removeClass('wordglow').removeClass('wordglow4').removeClass('wordglow3');
}

});

}

HTML for draggables is....

<div class="squares">

        <div id="drag1" class="drag ui-widget-content box-style2" tabindex="0" data-letter="a">
        <p>a</p>
        </div>

        <div id="drag2" class="drag ui-widget-content box-style" tabindex="0" data-letter="b">
        <p>b</p>
        </div>

        <div id="drag3" class="drag ui-widget-content box-style" tabindex="0" data-letter="c">
        <p>c</p>
        </div>

        <div id="drag4" class="drag ui-widget-content box-style" tabindex="0" data-letter="d">
        <p>d</p>
        </div>

        <div id="drag5" class="drag ui-widget-content box-style2" tabindex="0" data-letter="e">
        <p>e</p>
        </div>

        <div id="drag6" class="drag ui-widget-content box-style" tabindex="0" data-letter="f">
        <p>f</p>
        </div>

        <div id="drag7" class="drag ui-widget-content box-style" tabindex="0" data-letter="g">
        <p>g</p>
        </div>

        <div id="drag8" class="drag ui-widget-content box-style" tabindex="0" data-letter="h">
        <p>h</p>
        </div>

        <div id="drag9" class="drag ui-widget-content box-style2" tabindex="0" data-letter="i">
        <p>i</p>
        </div>

         <div id="drag10" class="drag ui-widget-content box-style" tabindex="0" data-letter="j">
        <p>j</p>
        </div>

        <div id="drag11" class="drag ui-widget-content box-style" tabindex="0" data-letter="k">
        <p>k</p>
        </div>

        <div id="drag12" class="drag ui-widget-content box-style" tabindex="0" data-letter="l">
        <p>l</p>
        </div>

        <div id="drag13" class="drag ui-widget-content box-style" tabindex="0" data-letter="m">
        <p>m</p>
        </div>

        <div id="drag14" class="drag ui-widget-content box-style" tabindex="0" data-letter="n">
        <p>n</p>
        </div>

        <div id="drag15" class="drag ui-widget-content box-style2" tabindex="0" data-letter="o">
        <p>o</p>
        </div>

        <div id="drag16" class="drag ui-widget-content box-style" tabindex="0" data-letter="p">
        <p>p</p>
        </div>

        <div id="drag17" class="drag ui-widget-content box-style" tabindex="0" data-letter="r">
        <p>r</p>
        </div>

        <div id="drag18" class="drag ui-widget-content box-style" tabindex="0" data-letter="s">
        <p>s</p>
        </div>

        <div id="drag19" class="drag ui-widget-content box-style" tabindex="0" data-letter="t">
        <p>t</p>
        </div>

        <div id="drag20" class="drag ui-widget-content box-style2" tabindex="0" data-letter="u">
        <p>u</p>
        </div>


     </div>

Upvotes: 8

Views: 798

Answers (6)

nickaknudson
nickaknudson

Reputation: 4807

Personally, I don't like the idea of using CSS for this effect. Why not make it as though the letter was actually dropped on the first open space of the word? This seems to achieve the desired effect:

http://jsfiddle.net/nickaknudson/sYJwm/

$('.drop').droppable({
...
drop: function(event, ui) {
    word = $(this).data('word');
    //change context from this to that
    that = $('.spellword')[guesses[word].length];
    guesses[word].push($(ui.draggable).attr('data-letter'));

    if ($(that).text() == $(ui.draggable).text().trim()) {

        $(that).addClass('wordglow3');
    } else {
        $(that).addClass('wordglow');
    }


    if (guesses[word].length == 3) {
        if (guesses[word].join('') == word) {
            $('td[data-word=' + word + ']').addClass('wordglow2');

        } else {
            $('td[data-word=' + word + ']').addClass("wordglow4");
            guesses[word].splice(0, guesses[word].length);
        }
    }
},
...

Upvotes: 1

miracules
miracules

Reputation: 696

The answers from Anz & malificent are both good, however making sure that the letters that are sorted as "last one in - place as last" and setting position to relative would be a better solution as it would avoid a few fall pits in CSS should you want to apply further styling.

#mainlist {
    width: 20%;
    position: relative;
    padding: 2px;
    max-height: 65px;
}

Upvotes: 2

Anz
Anz

Reputation: 594

You could try using CSS float for the snapping effect on the DIV. Something like below perhaps.

#mainlist {
    width: 20%;
    float: left;
    padding: 2px;
}

Upvotes: 1

malificent
malificent

Reputation: 1441

you can use the sortable ui in conjunction with draggable. then float:left as user1555320 suggested...something like this:

$('.drop').sortable({revert:true, axis:'x'});

$('.drag').draggable({
connectToSortable:'.drop',
helper: 'clone',
snap: '.drop',
grid: [60, 60],
revert: function(droppable) {
    if (droppable === false) {
        return true;
    }

    else {

        return false;
    }
}
});

then your css

.drop div {
   float:left;           
}

Upvotes: 2

user1555320
user1555320

Reputation: 495

I think that you just need a float:left property in your css so that divs are pòaced in the right order in the container

Upvotes: 0

ricardoespsanto
ricardoespsanto

Reputation: 1110

I did not understand your problem fully but just looking at your code this seems like something I would change:

revert: function(droppable) {
    return !droppable;
});

If you mean you need to access the first element then the second then the third, etc in order you can do this with pseudo selectors

Upvotes: -1

Related Questions