Reputation: 9784
Note: If you're 'just' a jQuery developer some things in this post may look a tad complex (Base62 encoding etc.) - it's really not. Although the more technical details are relevant to the question, the core is that jQuery won't select stuff with capitals. Thanks!
Hi folks!
So I have a list generated by Ajax. When you click the list's title, it's ID is sent and the list item appears alongside it. Standard stuff.
Since we're using an auto_increment ID, we don't want the users knowing how many submissions there are in the database. So, I'm encoding it into Base62, then decoding back again. [Note that this is - or, should be, irrelevant to the problem].
So as my list is generated, this code is output. We're using CodeIgniter PHP alongside the jQuery - this is in a loop of database results. $this->basecrypt->encode()
is a simple CI library to convert an integer (the ID) to Base62:
$('#title-<?php echo $this->basecrypt->encode($row->codeid); ?>').click(function() {
alert("clicked");
[...]
And then, further down the page:
<div id="title-<?php echo $this->basecrypt->encode($row->codeid);?>" class="title">
As you can see, this is all generated in the same loop - and viewing the outputted source code shows, for example:
$('#title-1T').click[...]
and then <div id="title-1T" [...]
So, jQuery shouldn't have any trouble, right? It was all working fine until we started Base62-ing the IDs. I believe that jQuery can't/won't select our IDs when they contain capital letters.
Now forgive me if I'm wrong - I am, relatively speaking, fairly new to jQuery - but to test my point I changed my $this->basecrypt->encode()
into Base36.
Before, it was using 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
After, it was using 0123456789abcdefghijklmnopqrstuvwxyz
With no capital letters, jQuery could select (and show the alert for testing purposes) just fine.
So what can I do? Is it safe for me to continue just using numbers and lowcase letters, in Base36 - and if so, what's the maximum integer size this can go up to? If not, what can I do about jQuery's problematic selection process?
Thanks!
Jack
EDIT: Included below is some example code from the page.
This is a part of the script returned in the file ajaxlist.php - it's called from Ajax and appears a couple of seconds after the page loads. I added in alert("clicked");
right near the beginning to see if that would appear - sadly, it doesn't...
$(document).ready(function() {
$('#title-<?php echo $this->basecrypt->encode($row->codeid); ?>').click(function() {
alert("clicked");
var form_data = {
id: <?php echo $this->basecrypt->encode($row->codeid); ?>
};
$('.resultselected').removeClass('resultselected');
$(this).parent().parent().addClass('resultselected');
$('#col3').fadeOut('slow', function() {
$.ajax({
url: "<?php echo site_url('code/viewajax');?>",
type: 'POST',
data: form_data,
success: function(msg) {
$('#col3').html(msg);
$('#col3').fadeIn('fast');
}
});
});
});
});
</script>
Also returned from the same file, at the same time as the code above (just beneath it) is this:
<div class="result">
<div class="resulttext">
<div id="title-<?php echo $this->basecrypt->encode($row->codeid);?>" class="title">
<?php echo anchor('#',$row->codetitle); ?>
</div> [.......]
If this helps anymore, let me know!
EDIT 2: ACTUAL OUTPUT RETURNED TO THE BROWSER.
This was taken from Firebug, and is the returned data (Ajax) to the browser:
<script type="text/javascript">
$(document).ready(function() {
$('#title-1T').click(function() {
alert("clicked");
var form_data = {
id: 1T };
$('.resultselected').removeClass('resultselected');
$(this).parent().parent().addClass('resultselected');
$('#col3').fadeOut('slow', function() {
$.ajax({
url: "http://localhost:8888/code/viewajax",
type: 'POST',
data: form_data,
success: function(msg) {
$('#col3').html(msg);
$('#col3').fadeIn('fast');
}
});
});
});
});
</script>
<div class="result">
<div class="resulttext">
<div id="title-1T" class="title">
<a href="http://localhost:8888/#"><p>This is an example </p></a> </div>`
<div class="summary">
gibberish summary text </div>
<div class="bottom">
<div class="author">
by <a href="http://localhost:8888/user/7/author">author</a> </div>
<div class="tagbuttoncontainer">
<div class="tagbutton listv">
<span>tag1</span>
</div>
</div>
<!-- Now insert the rating system -->
<div class="ratingswrapper">
<p>4.0</p>
</div>
</div>
</div>
</div>
Come on - you cannot say that shouldn't work... can you?!
Upvotes: 0
Views: 169
Reputation: 86453
Ok I found your problem... you need to put quotes around the variable in the form_data definition (demo):
var form_data = {
id: "<?php echo $this->basecrypt->encode($row->codeid); ?>"
};
I also had to add a return false;
so the demo doesn't try to follow the link
Upvotes: 5
Reputation: 15601
This doesn't solve your specific issue, but would couldn't you just do something like this:
$('#container-of-the-divs div[id^=title-]').click(function(e) {
alert('Clicked div with ID: ' + e.target.id);
});
You could also just add a class to these elements and select that instead. If you're looking for performance with a ton of items, you could also add the click event onto a parent item, and then do an if statement inside which would create only one event listener, instead of N event listeners. Example:
$('#container-of-the-divs').click(function(e) {
if (e.target.id.substring(0, 6) == 'title-') {
alert('Clicked div with ID: ' + e.target.id);
}
});
Or you could just check if $(e.target).hasClass() like mentioned before.
Updated: Here is a working example based off the code you gave:
<div class="result">
<div class="resulttext">
<div id="title-A0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" class="title">
<a href="#">A0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ</a>
</div>
<div id="title-B0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" class="title">
<a href="#">B0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ</a>
</div>
<div id="title-C0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" class="title">
<a href="#">C0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ</a>
</div>
<div id="title-D0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" class="title">
<a href="#">D0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ</a>
</div>
</div>
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$('div.resulttext div.title').click(function() {
$i = $(this);
alert('Clicked div with ID: ' + $i.attr('id'));
});
</script>
Upvotes: 1
Reputation: 338336
I don't think that jQuery is the problem.
Please double-check that the IDs you generate are unique to the page and conform to the definition of ID tokens:
ID
andNAME
tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
Also do a validity test of your output HTML to make sure your HTML is not broken in places where you did not look.
Upvotes: 2