0

I have a table with cells. I want to click a cell only once in order to mark it. After I have marked it and saved it, I want to click a clear_Button that would unmark the cells and let me mark them again.

$("td").one('click', function (evt) {
        $(this).css("border", "3px solid yellow");
});

$("#clear_Button").click(function () {
        $("#table td").css("border", "1px solid black");
    });

But since .one() function allows an object to be executed only once, I can not click the cell again. Is it possible to tell the jQuery to refresh .one() function? Thanks.

Shukhrat Raimov
  • 2,137
  • 4
  • 21
  • 27

5 Answers5

2

You can do following way

function tdClick (evt) {
        $(this).css("border", "3px solid yellow");
}   
 $("td").one('click', tdClick );

$("#clear_Button").click(function () {
        $("#table td").css("border", "1px solid black");
      $("td").one('click', tdClick );
    });

OR You can use on and off to assign and remove event.

function tdClick (evt) {
    $("td").off('click' );
        $(this).css("border", "3px solid yellow");
}

$("td").on('click', tdClick );

$("#clear_Button").click(function () {
        $("#table td").css("border", "1px solid black");
        $("td").on('click', tdClick );
    });
punitdam
  • 66
  • 3
1

You can re-attach the events after clear button is clicked.

var attachEvents = function () {
    $("div").one('click', function (evt) {
        $(this).css("border", "3px solid yellow");
    });
}

$("#clear_Button").click(function () {
    $("div").css("border", "1px solid black");
    attachEvents();
});

attachEvents();

demo: http://jsfiddle.net/82vr7/2/

Fabricator
  • 12,722
  • 2
  • 27
  • 40
  • I want to click a cell only once.Hmm in another words in "one session" of choosing the cells. After I click it I do not want to make it clickable again, until the clear button is clicked (that would clear all the cells and starts a new session of clicking:) ). I hope you understand what I am saying. – Shukhrat Raimov Jun 05 '14 at 22:46
1

You can go for a more general purpose solutionand make your self a little disable flag so you can essentially turn the event handler on/off at will without having to deinstall/reinstall it:

jQuery.fn.suspend = function(val) {
    return this.data("suspended", !!val);
}

jQuery.fn.isSuspended = function() {
    return this.data("suspended");
}

$("td").on('click', function (evt) {
     if (!$(this).isSuspended()) {
        $(this).css("border", "3px solid yellow");
     }
});

Then, you can disable the event handler at any time for a particular cell with this:

$("#aParticularCell").suspend(true);

or for all cells with:

$("td").suspend(true);

Or enable it with:

$("#aParticularCell").suspend(false);

or for all cells with:

$("td").suspend(false);

The point is that you can just set up a flag that controls whether the event handler is enabled or disabled and all you have to do is toggle that flag to change the behavior and you can use this flag on a single cell or any group of cells.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Is it possible to tell the jQuery to refresh .one() function? Thanks.

Yes. Do that from the clear-button handler.

In fact, you can make two functions that mutally call each other asynchronously:

function cellSelecter() {
    $("td").one('click', function (evt) {
        $(this).css("border", "3px solid yellow");
        cellClearer();
    });
}
function cellClearer() {
    $("#clear_Button").one('click', function () {
        $("#table td").css("border", "1px solid black");
        cellSelecter();
    });
}

You might even be able to incorporate the Promise pattern (like this), and get very composable behaviours.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • That is very interesting approach!:) – Shukhrat Raimov Jun 05 '14 at 22:59
  • This approach is actually a little ripped off from the paper [Directing JavaScript with Arrows](http://www.cs.umd.edu/~jfoster/papers/dls09-arrows.pdf), if you're interested in a more theoretical view on this :-) – Bergi Jun 05 '14 at 23:06
0

A different approach here (whithout .one())

//--- this is your clickable thing
$("#clickme").on("click", function(){
    if(!$(this).hasClass("alreadyclicked")){
        //--- the first time the thing is clicked
        $(this).css({background: "yellow"}).addClass("alreadyclicked");
    }else{
        alert("already clicked.. reset!");   
    }    
});

//--- and this is the reset button
$("#reset").on("click", function(){
    $("#clickme").css({background: "red"}).removeClass("alreadyclicked"); 
})

fiddle http://jsfiddle.net/KSV6n/1/

BeNdErR
  • 17,471
  • 21
  • 72
  • 103
  • I think I need to use .one() function, because I add the value of the cells to the array. If I would use .on(), that would let me add the same cells over and over again. Is it possible to just tell jQuery-forget about previous .one() function and start it again? – Shukhrat Raimov Jun 05 '14 at 22:50
  • suppose jquery forgets about previous .one() click: what happens to the value of the cells? do you need to re-add them to the array? – BeNdErR Jun 05 '14 at 22:53
  • No I just clear the previous array and start a new one. – Shukhrat Raimov Jun 05 '14 at 22:54
  • so you can add the array clear in the refresh button callback (where you set the bg back to red) and add the value of cells to the array where you click the first time button (where you set the bg to yellow) – BeNdErR Jun 05 '14 at 23:00