Question

To be specific, I'm talking about avoiding this type of code:

<input type='text' id='title_33' class='title'
  onfocus='updateCharsLeft(33);' 
  onkeypress='updateCharsLeft(33);' />

Here I would like to put the onfocus and onkeypress event handles separately, i.e in a .js file. Like this:

$(document).ready(function()
  {
    $(".title").focus(updateCharsLeft);
    $(".title").keypress(updateCharsLeft);
);

However here the problem is that the ID of the textbox needs to be passed onto the function updateCharsLeft(). It would suck to have to extract out the id from the ID of the textbox in that function, so it would actually be cleaner to just put in the event handlers within the HTML code.

Thoughts?

Was it helpful?

Solution

I've had to do something similar before and also wasn't happy with parsing the value out the ID attribute. The best thing I can suggest is that you use another attribute for the value you need, like the rel attribute:

<input type='text' id='title_33' class='title' rel='33' />

Or depending on how religious you are about validation, just use a custom attribute:

<input type='text' id='title_33' class='title' myval='33' />

OTHER TIPS

Can't you do this:

$(document).ready(function()
  {
    $(".title").focus(function() {
        updateCharsLeft(this.id);
    });
    $(".title").keypress(function() {
        updateCharsLeft(this.id);
    });
);

or more neatly:

$(document).ready(function()
  {
    $(".title .another .someother .andAnother").focus(function() {
        updateCharsLeft(this.id);
    }).keypress(function() {
        updateCharsLeft(this.id);
    });
);

I definitely think you should separate your JavaScript and HTML. It will be easier to find/maintain, and you can edit one place rather than 10. Don't repeat yourself.

I would look into using jQuery's live functionality. If you have 10 text input's, your adding 20 event handlers this way as opposed to 2 (one for EVERY focus handler on the page and one for EVERY keypress handler on the page).

Also re your comment to karim, I don't see why you would be duplicating yourself. It should be trivial to pass the id or transform it with a regular expression if necessary as long as your consistent in your naming convention For example, this.id.replace(/.*(\d+)$/,''). However, it would probably even be better to pass the direct DOM element reference instead, and work with that in your function.

Lastly, you seem to think that some aspect of this will suck. Maybe I'm missing the point, but can you clarify what's so difficult about mainupaliting the id or the DOM reference or whatever else that you need to do? Maybe post a longer code sample of what you're doing next.

If you really don’t want to pass this.Id then you could add a custom attribute to the input tag...

<input type='text' id='title_33' idSuffix='33' class='title'/>

You then set the event handlers like this...

$(document).ready(function()
{
    $(".title").focus(function() {
        updateCharsLeft(this.idSuffix);
    });
    $(".title").keypress(function() {
        updateCharsLeft(this.idSuffix);
    });
);

I personally like custom attributes. They provide a way to give Html tags custom metadata and keep it all in the markup. Html validators don’t like them though :-(

I would try to manage the all events from a single JavaScript block. As long as you are able to reference elements on the page, this should be possible.

You could always use the string functions to parse out the value and pass it along, e.g.

$(".title").focus(function() {
   var thisid = this.id;
   updateCharsLeft(thisid.substring(thisid.indexOf("_") + 1));
});

I'm not sure what the performance implications would be if you had to do this for a lot of elements though.

$(document).ready(function(){
    var update = function(){ updateCharsLeft(this.id.split("_")[1]); };
    $("input.title")
        .focus(update)
        .keypress(update);
});

This is exactly what Unobtrusive Javascript technique focuses on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top