How to use a button's "data-" attribute to call a selected JavaScript function

81,622

Solution 1

Use the following code to get the values in your HTML:

$('button').click(function(){
  var data = $.parseJSON($(this).attr('data-button'));
  alert(data.option1)
});

This code is specifically for your requirement. By this way, you can store data in HTML and retrieve in JavaScript code.

Updated the JSFiddle code, working code is available at: http://jsfiddle.net/NDaEh/51/

EDIT:

Solution to call a function dynamically: http://jsfiddle.net/NDaEh/70/ HTML:

<button type='button' data-button='{"func": "func1"}'>click1</button>
<button type='button' data-button='{"func": "func2"}'>click2</button>

JS:

var myFuncs = {
  func1: function () { alert('Function 1'); },
  func2: function () { alert('Function 2'); },
};

$('button').click(function(){
  var data = $.parseJSON($(this).attr('data-button'));

  myFuncs[data.func]();
});

Solution 2

Dont save objects as JSON strings in the html tag property value. Use the data() method instead.

$('input[type="button"]').data({ option1: 'o1', option2: 'o2' });

Also, when youre writing this:

$(this).data('button').option1(data);

option1 would need to be a plugin in order to be chained on to the data method (or any jquery method for that matter). You would need tomething like this:

jQuery.fn.option1 = function () {

   alert($(this).data('option1'));

   return this;
}

Fiddle

Solution 3

Use the jQuery data as shown below:

$('input[type=button]').data('button-data', { option1: 'option1', option2: 'option2});

Use:

$('input[type=button]').data('button-data');  //{ option1: 'option1', option2: 'option2}

In order to get the data from the element

Share:
81,622
tim peterson
Author by

tim peterson

web programming-javascript, php, mysql, css, html-is my thang

Updated on July 05, 2022

Comments

  • tim peterson
    tim peterson almost 2 years

    I'm trying to set some data on my buttons such that it can be accessed onclick. I'm having no problem using JSON in a button's data attribute where the key value is a string. However, I can't figure out how to set the values to be a function.

    What I'd like to happen upon clicking the button in this demo code is for the click event to call the function option1() which will alert the string "hello outside".

    The error I'm getting is this:

    Uncaught TypeError: Property 'option1' of object #<Object> is not a function
    

    HTML (JSFiddle is here: http://jsfiddle.net/NDaEh/32/):

    <button type='button' data-button='{"option1": "option1", "option2": 
    "option2"}'>click1</button>
    

    JS:

    var data='hello outside';
    var option1=function(data){
        alert(data)
    }  
    
    $('button').click(function(){
      //var data='hello inside';
      $(this).data('button').option1(data); // should alert 'hello outside'
    });
    

    Thoughts?

  • tim peterson
    tim peterson over 11 years
    why can't i save objects as JSON strings? also i don't want to generate this data using JS b/c it will be highly variable across my app and i've already spent the time to generate it with server side code (logic is wired in my mysql database)
  • Johan
    Johan over 11 years
    @timpeterson Well, html tags property values should be wrapped with double quotes. JSON strings should be as well. So I wouldnt recommend it. You would end up with either invalid html or json.
  • Johan
    Johan over 11 years
    @timpeterson How are you fetching the data from the server? By ajax? Or are you just printing it directly in to the html? And what serverside language are you using?
  • tim peterson
    tim peterson over 11 years
    I'm just printing the HTML. I don't want to do that and then write all these $('button').data() assignments across my entire app since there are many different buttons and many different assignments.
  • Johan
    Johan over 11 years
    @timpeterson Ok, if you insist on sticking with inline string objects, you could use the code that i posted and format then using var myObject = $.parseJSON($(this).attr('data-button'))
  • tim peterson
    tim peterson over 11 years
    ok thanks yes i see $.parseJSON but using myObject.option1(data) still isn't alerting "hello outside". would you mind adding what you think works to this jsfiddle: jsfiddle.net/NDaEh/32 ?
  • tim peterson
    tim peterson over 11 years
    thanks @IvenMS but the key thing I want is that data.option1 is itself a function and not just a string. So writing data.option1(data) calls the alert function and not vice versa.
  • IvenMS
    IvenMS over 11 years
    Try this: var alert_data='hello outside'; function option1 (data){ alert(data) } $('button').click(function(){ var data = $.parseJSON($(this).attr('data-button')); window[data.option1](alert_data); });
  • IvenMS
    IvenMS over 11 years
    The idea is to run the function declared in your document with window["function_name"](arguments);. Please check....
  • tim peterson
    tim peterson over 11 years
    I understand the concept but your code is not working, its giving same error of option1 not being a function as I was first getting
  • Johan
    Johan over 11 years
    @timpeterson Sorry about the delay, i went for lunch. Check out the fiddle that i posted. Is this what you need?
  • tim peterson
    tim peterson over 11 years
    yes that' s on the right track, I don't need to extend the jquery object, it could extend some smaller object using a similar syntax right?
  • Johan
    Johan over 11 years
    @timpeterson If you want to write a custom jquery method (aka plugin), thats how its done (In other words, as long as you want to use your method directly on the jquery object). If you dont want to do that you could extract the data object and pass it to your regular function and handle it there.
  • IvenMS
    IvenMS over 11 years
    Try this link: jsfiddle.net/NDaEh/66 It is working. The concept is little different, but the same logic.
  • tim peterson
    tim peterson over 11 years
    that is exactly what I was looking for, can you put this jsfiddle in your answer, I'll accept it, thanks for pursuing this, really appreciate it!