Hey everyone, take a look at the code below and appreciate how messy the id attributes are
View File
<?php foreach($array_project as $prj) : ?>
<div id="prj-p<?=$item['project_id'] ?>">
<?php foreach($arr_skill as $skill) : ?>
<h2><?=$skill['name'] ?></h2>
<a class="view" id="skill-p<?=$prj['project_id'] ?>-s<?=skill['skill_id'] ?>">view</a>
<a class="edit" id="edit-p<?=$prj['project_id'] ?>-s<?=skill['skill_id'] ?>">edit</a>
<a class="delete" id="delete-p<?=$prj['project_id'] ?>-s<?=skill['skill_id'] ?>">delete</a>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
Javascript File (using Jquery)
$('.view').live('click', onClick);
$('.edit').live('click', onClick);
$('.delete').live('click', onClick);
function onClick()
{
// prjId and skillId are effectively arguments that are
// traditionally passed via onClick(prjId, skillId), but here
// we've attached them to element ids
prjId = this.id.replace(/(skill\-p)|(\-s\d+)/g, '')
skillId = this.id.replace(/(skill\-p\d+)|(\-s)/,'');
// do stuff with the prjId and skillId
}
So my issue with the above code is that doing something like this in the view file
<a class="view" id="skill-p<?=$prj['project_id'] ?>-s<?=skill['skill_id'] ?>">view</a>
is effectively the same as
<a onclick="onClick(<?=$prj['project_id'] ?>,<?=skill['skill_id'] ?>)">view</a>
With the latter actually being more readable to the programmer. In the former, I don’t like how I have to derive my own id naming convention to keep track of database entity ids: for example, -p prefix denotes project id, and -s prefix denotes skill_id. And then I have to use regular expression to parse it. I don’t liek the latter of inline js event handlers, because that’s intrusive javascript.
I thought about simplifying the code like this:
View File
<?php foreach($array_project as $prj) : ?>
<div id="prj-p<?=$item['project_id'] ?>">
<?php foreach($arr_skill as $skill) : ?>
<h2><?=$skill['name'] ?></h2>
<input type="hidden" class="project_id" value="<?=$prj['project_id'] ?>" />
<input type="hidden" class="skill_id" value="<?=$prj['skill_id'] ?>" />
<a class="view">view</a>
<a class="edit">edit</a>
<a class="delete">delete</a>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
Javascript File (using Jquery)
$('.view').live('click', onClick);
$('.edit').live('click', onClick);
$('.delete').live('click', onClick);
function onClick()
{
prjId = this.parentNode.childNodes[1].value;
skillId = this.parentNode.childNodes[2].value;
// do stuff with the prjId and skillId
}
This is much easier less coding when I have A LOT of db entity ids to reference between the js and view files (eg. i only have to print the project_id and skill_id ONCE). But the problem with this solution is that as soon as my designer changes the xhtml schema, I have to update my javascript file to re-reference the hidden input fields.
Is there an easier and less code-redundant way for html elements to pass data to javascript functions?
You could use data attributes, like this:
Then access them in jQuery:
This work in HTML4 and is a part of the HTML5 standard, so no conflicts now, completely compliant HTML later. with this approach you may not even needs the
idon the<div>, if that’s the case you can remove the attribute, since it’s not needed, only thedata-ones are used in theonClick()function above. You may also want to give that container<div>a class, likeclass="project"and change the call to find it to.closest(".project")to make it a bit more resilient.