-1
<div id='example' data-fn='functiona'>OK</div>

$('#button').click function(){
    $('#example').attr('data-fn', functionb');
});

function functiona(){
    console.log('functiona');
}

function functionb(){
    console.log('functionb');
}

$('#example').click(function(){
    // execute function currently stored inside data-fn attribute
});

Probably everything is clear.
I need dinamically change the function which will be executed by clicking on example. The current function should be stored inside data-fn.

Any help?

Alec
  • 8,529
  • 8
  • 37
  • 63
  • 2
    Dynamically change it based on what? – Scott Hunter Jun 18 '18 at 18:50
  • do really need to store the function in the element? why you don't store just the function name, then when on click get that name and run the respective function. no need to store it on the element – Calvin Nunes Jun 18 '18 at 18:51
  • I highly doubt storing the function as a data attribute will be necessary. What are you trying to accomplish here. – Damon Jun 18 '18 at 18:51
  • @Damon, I want to avoid multiple dialogs for multiple tasks, because the dialogs are the same , just executed function on `OK` button is different. –  Jun 18 '18 at 18:54
  • 3
    I don't know what "multiple dialogs for multiple tasks" means, but it sounds to me like you just need to write a higher order function (factory) to create similar on click functions based on whatever parameters. If you _explicitly define what you are trying to do_, it will help you get a higher quality answer – Damon Jun 18 '18 at 18:57
  • @ScottHunter, based on free choice. I need to assaign any function to `example` and store its name inside `data-fn`. The question is - how to call that function? –  Jun 18 '18 at 19:01
  • 1
    Possible duplicate of [Can you set a javascript function name as an html attribute?](https://stackoverflow.com/questions/27447755/can-you-set-a-javascript-function-name-as-an-html-attribute) – t.niese Jun 18 '18 at 19:01
  • You really should think about the factory method solution. It is way cleaner then storing the name in the in the attribute. – t.niese Jun 18 '18 at 19:02
  • @puerto: I have no idea what "based on free choice" means. If you want this to change dynamically, you have to spell out under what conditions it needs to change. – Scott Hunter Jun 18 '18 at 19:48

2 Answers2

2

What you want to do is described in Can you set a javascript function name as an html attribute?

But I suggest that you solve it that way:

$('#button').click(function() {
  $('#example').off('click.myNamespace') // remove the previously assigned callback
               .on('click.myNamespace', creatClickCallback(functionb)); // register the new callback
});

function functiona() {
  console.log('functiona');
}

function functionb() {
  console.log('functionb');
}

function creatClickCallback(functionToCall) {
  return function(evt) {
    functionToCall()
  }
}

$('#example').on('click.myNamespace', creatClickCallback(functiona));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='example'>OK</div>
<div id='button'>button</div>

This way you ensure that you do not accitantily name a function the wrong way, because you pass it as an actual reference to that function instead of a string.

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • Thanks but this is not my question. Please read it again. Click on an element should store choosen function name inside data attr of another element, and click on that another el. should execute that function. –  Jun 18 '18 at 19:11
  • This isn't exactly what I had in mind. In this case, you could just pass `functiona` or `functionb` directly a la `$('#example').on('click.myNamespace', functiona);`. It seems like OP wants to change some minor behavior of the function for different use cases. But at this point, your guess is as good as mine since the question is completely unclear. – Damon Jun 18 '18 at 19:12
  • @puerto yes an that's what this code does, but a more save way. With the click on `#button` the callback for the click on `#element` is changed so that the `functionb` is called when `#element` is clicked. – t.niese Jun 18 '18 at 19:16
-1

Couldn't you just store the function name, then when you click you check which function is then call it and update the function to which one you want?

Something like this:

function functiona(){
    console.log('called functiona');
    document.body.style.background = '#aaa';
}

function functionb(){
    console.log('called functionb');
    document.body.style.background = '#fff';
}

$('#example').on("click", function(ev){
  var func = $(ev.target).attr('data-fn');
  console.log(func);
  window[func]();
});

$('#changer').on("click", function(ev){
    //HERE you can change the function will be called based on what you want 
    //Here I just changed it with a simple if...
    var fn = $("#example").attr("data-fn");
    if (fn == 'functiona'){
      $("#example").attr("data-fn", "functionb");
    }else {
      $("#example").attr("data-fn", "functiona");
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='example' data-fn='functiona'>Click Me to call function</div>
<button id='changer'>Change Function</button>

Here, the global variable window have your functions stored, so going through it by it's name and calling it, should work, if this name exist as a function window[stringOfFuncionName]();

This is not the best way of doing what you need (actually you didn't let completely clear your final objective), but this maybe can help.

Calvin Nunes
  • 6,376
  • 4
  • 20
  • 48
  • There is no just two functions. I need to assign any function, based on free choice. –  Jun 18 '18 at 19:04
  • free choice of what? Please, consider editting your question to let it more clear and help us to help you – Calvin Nunes Jun 18 '18 at 19:05
  • The question is perfectly clear. Once more - click on an element should store choosen function name inside data attr of another element, and click on that another el. should execute that function. What is unclear here? –  Jun 18 '18 at 19:08
  • 1
    What is unclear is what everyone is asking you in comments, something like: "Based on free choice" Which free choice? choice of what? "multiple dialogs for multiple tasks" Which dialogs? which tasks? But anyway, i made an edit to my Answer, check it to see if it helps. If not, sorry. – Calvin Nunes Jun 18 '18 at 19:11
  • 1
    @puerto you are shooting yourself in the foot if you go with this. People are trying to lead you to a less brittle solution which is why they are asking you to provide more context. For example, this will immediately break if you put the code in a private scope. – Damon Jun 18 '18 at 19:19
  • 2
    @puerto this will work, but you really should avoid that. In gerenal you do not want to pollute the global scope, because this could result in naming conflicts, and hard to debug problems. And if you decide to not pollute the global namespace aynmore then `window[func]();` won't work. – t.niese Jun 18 '18 at 19:20
  • This answer is just a copy of this, [https://stackoverflow.com/questions/27447755/can-you-set-a-javascript-function-name-as-an-html-attribute](https://stackoverflow.com/questions/27447755/can-you-set-a-javascript-function-name-as-an-html-attribute), which is a duplicate. – Asons Jun 18 '18 at 19:35