views:

125

answers:

1

Hi Folks,

I'd like to know if someone has a better way to access the elements #type and #type_new based on my html:

<tr>
  <th>Type of Organization</th>
  <td id="toggle">
    <select name="type" id="type">
      <option>Church</option>
      <option>College</option>
      <option>Theatre</option>
    </select> 
    <input name="type_new" id="type_new" type="text" />                        
  </td>
</tr>
<tr>
  <th>&nbsp;</th>
  <td><a class="toggle" id="type"><small>Add New Type</small></a></td>
</tr>

Here is my javascript:

$("a.toggle").unbind('click').click(function(){
  $.prev = $(this).parents().parent().prev().find("td#toggle");
  $.select = $.prev.find("#type");
  $.textbox = $.prev.find("#type_new");

  if($.textbox.is(':visible')==true)
    $(this).find("small").html("Add New Type");
  else
    $(this).find("small").html("Choose From Exisiting Types");
  $.select.toggle();
  $.textbox.toggle().val("");
});

I know there are other ways to lay out the html to make the javascript easier but surely someone has a good way based on my current html.

It's probably worth noting that the reason I'm not just referencing by ID or CLASS is I'm also generating more of these on the fly with an an ajax .load and all elements will have the same id's and classes. Why not use indexes you might ask? Well I've been there and done that. I'd have to actually use more code to re-bind the click events to include all new elements. I'm going for the simplest way possible here.

Thanks!

UPDATE: I want to stress the fact that I'm adding identical elements further down the page with an ajax .load. They'll have different element names for $_POST reasons but I want my javascript function to handle every instance as they appear. If I reference only by ID it will update all of the elements all the way down the page.

+4  A: 

IDs are supposed to be unique. If that is so in the case of your markup, then there is no need for complex traversing as you can directly select them, so your first three lines of code can be omitted, or instead simply be:

$.prev = $("td#toggle");
$.select = $("#type");
$.textbox = $("#type_new");

or the entire content of your click handler can be replaced with:

if($("#type_new").is(':visible')) {
    $(this).find("small")
           .html("Add New Type"); 
} else  {
    $(this).find("small").html("Choose From Exisiting Types");
    $("#type").toggle();
    $("#type_new").toggle().val("");
}
karim79
Your code totally makes sense. I guess I'm wrong in that when my ajax request adds another section to my table the elements are identical with the same IDs. They have different names for post reasons. I've given them the same IDs so my one piece of javascript will handle it each time there's a new request. Am I making sense?
jeerose
If you're appending stuff to your page and *duplicating* ids that exist on the page, you'll need to rework the way your markup is generated on the server. Use classes instead, for example <select class="type"> or <input class="type_new"/> and *then* select them based on the clicked anchor.
karim79
As in your previous code makes more sense if you're *not* selecting by IDs.
karim79
You're totally right. Classes. Thanks for your help.
jeerose