views:

37

answers:

2

With jQuery, jQuery-ui and one of the ui themes (I quite like lightness) included

(bear with me, there is a question at the bottom which you can skip to if you like, just wanted to show how I got to where I am)

(sorry if there are any mistakes or bits I have missed out in the code, it does work, but was cutting up the code for ease of reading)

I started out with the standard draggable + Sortable provide by the jQuery-UI project:

// HTML
<div id="leftColumn">
<ul id="pageElements">
<li class="ui-state-default ui-corner-all" id="html">Html</li>
<li class="ui-state-default ui-corner-all" id="paragraph">Paragraph</li>
<li class="ui-state-default ui-corner-all" id="image">Image</li>
<li class="ui-state-default ui-corner-all" id="faq">FAQ</li>
</ul>
</div>

<div id="rightColumn">
    <ul id="pageItems"></ul>
</div>

// JavaScript Code
$("#pageItems").sortable({
    revert: true,
    placeholder: 'ui-state-highlight',
    tolerance: 'pointer'
});
$("#pageElements li").draggable({
    connectToSortable: '#pageItems',
    helper: 'clone',
    revert: 'invalid'
 });

Then I started to think well it would be useful to add a dblclick function to allow items to be shifted from one list to another without needing to drag, so I added this:

    $("#pageElements li").dblclick(function () {
        copythis(this);
    });

function copythis(elem) {
    var selected = $(elem).closest("li").clone();     
    $("#pageItems").append(selected).html();
}

Then I thought ok, now I want to dblclick on the pageItem and show a dialog for edit

so I added:

<div id="itemDialog"></div> 


$("#itemDialog").dialog({ autoOpen: false, modal:true });
$("#pageItems li").live("dblclick", function () {
    openDialog(this);
});

function openDialog(elem) {
    $("#itemDialog").dialog('open');
}

Then I thought I want a button when I hover over an element, to allow me to delete, and I might as well have an edit route in there too:

var removeButton = '<span class="buttons"><span class="ui-edit ui-state-default ui-corner-all ui-icon ui-icon-pencil" title="edit">Edit</span><span class="ui-remove ui-state-default ui-corner-all ui-icon ui-icon-closethick" title="remove">Remove</span></span>';

$("#pageItems li").live("mouseenter", function () { $(this).append(addButton); }).live("mouseleave", function () { $(this).find(".buttons").remove(); });

    $(".ui-remove").live("click", function () { $(this).closest("li").remove(); });

    $(".ui-edit").live("click", function () {
        openDialog(this);
    });

So now it was quite functional, I wanted to then add an "add" button to the pageElement, so I would then have 3 options of drag, dblclick and a button click, so adding the code:

    var addButton = '<span class="buttons"><span class="ui-add ui-state-default ui-corner-all ui-icon ui-icon-triangle-1-e" title="Add">Add</span></span>';

used code from the pageItem li "live hover" again:

$("#pageElements li").live("mouseenter", function () { $(this).append(addButton); }).live("mouseleave", function () { $(this).find(".buttons").remove(); });

$(".ui-add").live("click", function () {
    copythis(this);
});

I amended the copythis function to allow for the inclusion of buttons:

function copythis(elem) {
    var selected = $(elem).closest("li").clone();
    selected.find(".buttons").remove();
    $("#pageItems").append(selected).html();
}

And this is where I am now and the problem I am currently working on.

If you dblclick the pageElement, that will copy the element (as expected).

If you click on the add button that will also copy a new element (as expected).

because the pageElement dblclick event is attached to the pageElement li tag and the add button click event is on a span tag nested inside that, if I click on the add button quickly sometimes I will get the dblclick event firing so adding more than one element to the pageItem list.

What I am looking to do is create a deadzone for the dblclick event which surrounds the add button item.

I am open to any ideas.

Cheers

Luke

A: 

I know it's far from helpful, but I'd advise against listening to dblclick - it is a) works differently in different clients - and jquery doesn't mask all of it, b) you don't want your user to double click, it's complicated.

tjp
A: 

OK, so I found an answer, probably not the best, but it works.

It involves defining a global variable:

var clicked = 0;

Then on the live event of the ui-add set the value to 1 and then set a timeout to delay the reset of the value back to 0:

    $(".ui-add").live("click", function () {
        clicked = 1;
        copythis(this);
        setTimeout(function () { clicked = 0;}, 100);
    });

So then on my pageElement dblclick function:

    $("#pageElements li").dblclick(function () {
        if (clicked == 0) {
            copythis(this);
        }
    });

Not ideal, but it works.

Luke Duddridge