views:

37

answers:

3

I'm calling a function in the element itself via an onclick attribute because I need php to dynamically give a value in one of the functions parameters. When I try to reference the calling element in the function via "$(this)", it ends up referencing the entire window and not the element. How do I fix this?

+1  A: 

Try to send your element as a parameter to your function like that :

<input type="text" onclick="myfunction(this);"></input>

your function should be :

<script>
  function myfunction(currentElement){
    // ...
  }
</script>
Canavar
+1  A: 

My general solution to problems like this never involves onclick handlers or other attribute-event-handlers of that sort.

Instead, I either store the dynamic value either in an inline javascript snippet that just sets a variable to be used later, or directly in the DOM by putting its contents in an attribute that might make sense ("rel" is frequently a good one -- or even just a made-up attribute sometimes).

For example, I might do this (this assumes PHP, but works the same way in any language):

<input type="text" id="some-input">
<script type="text/javascript">
  ThisAppConfig.some_dynamic_attribute = "<?php echo $something; ?>";
</script>

And n a javascript file (assuming it's loaded prior to the javascript snippet above), I would attach an event handler as normal, like so:

ThisAppConfig = {}

$(document).ready(function() {
  $('#some-input').click(function() {
    // $(this) -- is what you expect
    // ThisAppConfig.some_dynamic_attribute -- contains the dynamic data you need
  });
});

In the example above, I set the attribute on a custom config hash, but if you have custom other classes or hashes for your app, it often makes more sense to use them to store the value. You can even store it directly on the window if you want (i.e. window.some_dynamic_attribute = ...).

Anyway, that's one method. Alternatively, if you don't care about breaking some standards, you can invent an attribute and store the data there, like so:

<input type="text" id="some-input" some-dynamic-attribute="<?php echo $something; ?>">

Then retrieve in the javascript like so:

$(document).ready(function() {
  $('#some-input').click(function() {
    // $(this) -- is what you expect
    // $(this).attr('some-dynamic-attribute') -- contains the dynamic data you need
  });
});

I think both of these methods are superior to using attribute handlers like onclick="", simple because they are more solid from a design perspective; separation of concerns and all that.

A nice side-effect is that both of these methods also solve your problem.

Ben Lee
Thanks for the well thought out answer. Although not necessarily what I needed, a very interesting method.
Allen Gingrich
Allen -- this answer is the same as the one lonesomeday gave you along with an alternative.
Ben Lee
+1  A: 

I doubt you genuinely do need to use an inline onclick attribute. You can store data in an element in a variety of different ways. It's hard to say exactly how you would do it without knowing what the parameter you need to pass is, but I'll give some examples.

The most flexible would probably be in a data- attribute:

<a href="#" id="subject" data-type="fiction">Text</a>

You could then access the information in the following way:

$(document).ready(function(){
    $('#subject').click(function(){
        $type = $(this).data('type'); // this works as of jQuery 1.4.3, otherwise $(this).attr('data-type');

        // do your handling here, using $type
    });
});

You could also do this using classes, script tags that create global variables, all kinds of methods. These will almost certainly be better than putting jQuery handlers in onclick attributes.

lonesomeday