2

In traditional code I will pass arguments to link button like this:

<a href="javascript:call_hello(1, 2, 3)" role="button">Hello</a>

How can I do it in unobtrusive JavaScript style with JQuery or similar library.

<a href="#" class="hello" arg1="1" arg2="2" arg3="3" role="button">Hello</a>

Do not focus that code is longer since it is only example. I want attach Javascript code in such way.

$(".hello").on('click', call_hello2);

Can you suggest the best solution in your opinion for unobtrusive JavaScript style (attaching Javascript by matching elements not by html code).

Chameleon
  • 9,722
  • 16
  • 65
  • 127
  • possible duplicate of [pass more parameters into callback](http://stackoverflow.com/q/939032/1048572) – Bergi Sep 02 '15 at 15:05
  • What are those args? Where are they coming from, should they really go into the HTML markup? – Bergi Sep 02 '15 at 15:07

4 Answers4

2

You should use data-* prefixed custom attributes which can be stored and fetched using $.fn.data()

Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.

Alternatively HTMLElement.dataset can also be used.

The HTMLElement.dataset read-only property allows access, both in reading and writing mode, to all the custom data attributes (data-*) set on the element. It is a map of DOMString, one entry for each custom data attribute.

$(function() {
  $('a').on('click', function(event) {
    event.preventDefault();
    var arg1 = $(this).data('arg1');
    
    alert(arg1)
    
    //Using native JS
    console.log(this.dataset.arg1)
  })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" class="hello" data-arg1="1" data-arg2="2" data-arg3="3" role="button">Hello</a>
Satpal
  • 132,252
  • 13
  • 159
  • 168
1

The common approach for arguments passing to a jQuery plugin/helper in an unobtrusive way is to use the data-* attributes:

<a href="#" class="hello" data-arg1="1" data-arg2="2" data-arg3="3" role="button">Hello</a>

Then in your code:

$('.hello').on('click', function(e) {
    var options = $(this).data();

    if (options.arg1 == 1)
        ...
});

You can also set your default options and only override the passed arguments:

$('.hello').on('click', function(e) {
    var defaultOptions = {
         arg1: "something",
         arg2: "something2",
         arg3: "something3"
    },
    passedOptions = $(this).data(),
    options = $.extend(defaultOptions, passedOptions);
});
haim770
  • 48,394
  • 7
  • 105
  • 133
1

You could try this:

<a id="hello-button" href="#" class="hello" data-args="1,2,3" role="button">Hello</a>

with the following JavaScript:

function call_hello2() {
    var args = $("#hello-button").data('args').split(',');
    call_hello.apply(this, args);
}

This way you could have a variable number of arguments.

Finally, just use the code you posted:

$(".hello").on('click', call_hello2);
LostMyGlasses
  • 3,074
  • 20
  • 28
  • You are probably going to want to do `call_hello.apply(this, args)` which will call the method like `(1,2,3)` vs `call_hello(args)` which is like `([1,2,3])` – pllee Sep 02 '15 at 15:17
  • @pllee nice point, would be more elegant. I'll edit the answer. – LostMyGlasses Sep 02 '15 at 15:21
1

Should be:

<a id="hello-button" href="#" class="hello" data-args="1,2,3" role="button">Hello</a>

$(".hello").on('click', function (e) {
    var el = $(e.target);
    var args = el.data('args').split(',');
    call_hello(args);
});

This is the most unobtrusive way of doing it. You don't clobber the DOM with lots of attributes nor create arbitrary JavaScript functions.

beautifulcoder
  • 10,832
  • 3
  • 19
  • 29