0

I have some parts of a page which I am locking using a padlock icon in the top right. This updates the database and the icon changes from an open lock to a closed lock. I want the same icon to now be used to unlock the same data. What i am trying to do is change the onclick function from lockRun() to unlockRun() each time it is clicked. What is happening though is that is not only setting the onclick but executing the click aswell so it just goes from locked to unlocked constantly which isnt what I want! The code that is doing this loop is below.

function lockRun(runNum) {
  var lockID = 'Lock' + runNum;
  var runID = 'Run' + runNum;
  var runIDCode = document.getElementById(lockID).dataset.runid;
  console.log(runIDCode);
  $.ajax({
    url: '/runs/lock',
    type: 'POST',
    data: {
      runCode: runIDCode
    }
  }).done(function (response) {
    //console.log(siblings[1].dataset.contno);
    var dbResponse = JSON.parse(response);
    document.getElementById(lockID).classList.remove("fa-lock-open");
    document.getElementById(lockID).classList.add("fa-lock");
    document.getElementById(runID).classList.add('locked');
    document.getElementById(lockID).onclick = unlockRun(runNum);
  });
}

function unlockRun(runNum) {
  var lockID = 'Lock' + runNum;
  var runID = 'Run' + runNum;
  var runIDCode = document.getElementById(lockID).dataset.runid;
  console.log(runIDCode);
  $.ajax({
    url: '/runs/unlock',
    type: 'POST',
    data: {
      runCode: runIDCode
    }
  }).done(function (response) {
    //console.log(siblings[1].dataset.contno);
    var dbResponse = JSON.parse(response);
    document.getElementById(lockID).classList.remove("fa-lock");
    document.getElementById(lockID).classList.add("fa-lock-open");
    document.getElementById(runID).classList.remove('locked');
    document.getElementById(lockID).onclick = lockRun(runNum);
  });
}

So once the padlock icon is clicked, it is immediatley executing the unlock function then the lock function on repeat.

Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
AKAust
  • 103
  • 9
  • 1
    I recommend having two different bindings based on the class for 'locked' vs 'unlocked'. This way you don't have to rebind things. – nurdyguy Sep 25 '18 at 17:07

1 Answers1

4

Your problem is in this line here -

document.getElementById(lockID).onclick = unlockRun(runNum);

You are setting onclick to whatever that function returns not the function itself. By having the function with (argument) you are calling it immediately, not passing it to be called later on.

Here's one way to fix that - using a closure:

document.getElementById(lockID).onclick = function () { unlockRun(runNum) };

See Passing a function with parameters as a parameter? for more on this stuff.

Edit:

As noted by @get-off-my-lawn in a comment this same strategy needs to be applied to both places where onclick is being set.

Rose Robertson
  • 1,236
  • 7
  • 14
  • 2
    I think it is because both functions are calling each other. so you need to do this to both functions – Get Off My Lawn Sep 25 '18 at 17:07
  • 1
    Hello Rose, thank you for your answer it solved the issue. I appreciate your help! Will accept answer as soon as it allows me to. – AKAust Sep 25 '18 at 17:13
  • Thanks @GetOffMyLawn I've just updated my answer with a bit on that so that it's super clear for anyone reading in the future :) – Rose Robertson Sep 25 '18 at 17:28