PDA

View Full Version : Resolved dynamic DOM jQuery find element



ggalan
11-25-2011, 07:37 PM
i have some dynamic elements created from javascript looks like this from firebug
http://www.2020proj.com//media/images/computer/dynamicDOM.JPG
there are several of these fileuploaddiv_0, fileuploaddiv_1, fileuploaddiv_2
etc

from the img, how can i find which div id this element resides in?

I am interested in finding the "i".
the number after #fileuploaddiv_?


for(var i=0;i<=total;i++){
$('#container #fileuploaddiv_'+i).fileupload({
change: function (e, data) {
$.each(data.files, function (index, file) {
alert($(this).parent().parent().parent().parent().parent().parent().parent().parent().find('div[type=id]').attr());
});
}
});
}//loop

jscheuer1
11-26-2011, 07:39 AM
jQuery has its own iterative functions, .each(function(index, Element){}) for a jQuery Object, and jQuery.each(collection, function(indexInArray, valueOfElement){}) for non-jQuery collections (objects and arrays).

But with jQuery we often need not iterate over items simply to capture events upon them.

And an image has no change event. What does the user do to the image that you want captured? Do they click on it? Do they mouse over it?

And your loop suggests that you may be trying to capture the change or some other event of an input tag of the type file, so is it, and if so what event? Or is it really the img tag we're concerned with?

And all those .parent().parent() . . . things in a row can probably be replaced by a single .parents('div[id^="fileuploaddiv_"]') or a single .parents('div[class="fileuploadclass"]')

And .attr() requires an attribute to find or change. Which attribute(s) are you interested in and what to you want to do with them? From your post it appears to be the number part of the id attribute you want.

So, let's assume that and for instance that clicking on the image is what you want to capture. To get back to the div and get its number we could do:


$('.preview a img').live('click', function(){
alert($(this).parents('div[class="fileuploadclass"]').attr('id').replace(/\D/g, ''));
});

Note: I used the .live() method because you said these were dynamically generated. If that happens after we assign the click to these image elements, then live is required. If it happens before, live is OK but overkill. Using .bind('click', function(){}) or .click(function(){}) would be more direct and efficient.

If you want more help, please be more specific about what it is you're trying to do (answer the above questions) and please provide a link to a demo of the problem.

ggalan
11-26-2011, 05:09 PM
thank you for the help. i am using a uploader found here
https://github.com/blueimp/jQuery-File-Upload/wiki/API

and there is a callback area that i am trying to get some info.
i have too much code to post the entire thing so i just wanted to have a conversation about this.
currently using this alert i get a "undefined". i am trying to find the iteration's number (does that make sense?)
there is no click or button, the image comes from an upload and i am trying to find which item uploaded the image



for(var i=0;i<=total;i++){
$('#container #fileuploaddiv_'+i).fileupload({
change: function (e, data) {
$.each(data.files, function (index, file) {
//callback
alert($(this).parents('div[class="fileuploadclass"]').attr('id'));
});
}
});
}//loop

jscheuer1
11-26-2011, 07:18 PM
Then you want either the change event of the file input (which is not shown in your post but is implied to be in the form with the enctype attribute), or the submit event of the form with the file input in it (again, presumably that form), or you want to act within the function that generates the preview image, or you want to act upon the DOM as a whole after the preview image is present.

From what little you show, I can't tell for sure which if any of these can or should be done. In the javascript you do have what's data.files? I think it's an array or object containing a list of the images uploaded as paths and filenames. You need a list of the preview images as img tags, or a different approach.

If you want more help:

Please post a link to a page on the web that contains the problematic code so we can check it out.

It doesn't have to be a full blown web site. Just enough stuff to show the problem.

ggalan
11-26-2011, 08:35 PM
i made a truncated version of what im doing here. files:
http://bit.ly/tuMjao

jscheuer1
11-27-2011, 04:02 AM
There's a wealth of information available there if you want it. But if all you want is the number of the division, replace all this:


<script>
var total = <?php echo $i; ?>;
$(function () {
'use strict';

for(var i=0;i<=total;i++){
// Initialize the jQuery File Upload widget:
//$('#container #fileuploaddiv_'+i).fileupload();
$('#container #fileuploaddiv_'+i).fileupload({
//var num = i;
change: function (e, data) {
$.each(data.files, function (index, file) {
//alert('Selected file: ' + file.name);
//alert(file.name);

//alert($(this).parents('div[class="fileuploadclass"]').attr('id'));
//alert($(this).parent().parent().parent().parent().parent().parent().parent().parent().find('div[type=id]').attr());
//$('div.fileupload-content').find('tr[class=template-download]').remove();
//$('#container #fileuploaddiv_' + e).find('tr[class=template-download]').remove();
});
}
});

}//loop

});
</script>

with:


<script>
$(function () {
$('.fileuploadclass').fileupload({
change: function () {
alert(this.id.replace(/\D/g, ''));
}
});
});
</script>

ggalan
11-27-2011, 02:34 PM
awesome! how can i find out the list of information available in there?
also, what does this regex do?


replace(/\D/g, '');

jscheuer1
11-27-2011, 04:32 PM
Your best source as to what information can be gotten with the .fileupload() plugin would be from its documentation. Looks like that's:

https://github.com/blueimp/jQuery-File-Upload/wiki

But just playing around with it I found an api callback that wasn't listed in the api section of the documentation, namely 'success'. However, this is a generic callback for many plugins so perhaps they just left it to the the generic plugin docs to explain that one.

To explore for yourself what is available, you can do things like:


<script>
$(function () {
$('.fileuploadclass').fileupload({
change: function (e, data) {
var r = '', p;
for(p in e){
r += 'e[' + p + ']: ' + e[p] + '\n';
}
r += '\n';
for(p in data){
r += 'data[' + p + ']: ' + data[p] + '\n';
}
alert(r);
}
});
});
</script>

If any of those come back as objects (and some will), they can similarly be iterated over. You can also use $.each() to iterate over objects.

I still don't know how many parameters the success callback takes but I was doing something similar to the above with it and found it had at least three, all of which were objects, some of which had nested objects. I wasn't finding anything useful, so I stopped exploring. That's why an api doc can be handy. They usually tend to point out the most useful stuff. But the real goodies can sometimes be between the lines.

I found this.id for the change callback just by guessing. It's common in a lot of jQuery. But in the success callback it doesn't point to the same thing.


To answer your other question, that .replace(/\D/g, ''); is regular javascript. The replace() method uses a regular expression /\D/g to globally (that's the g part) identify all non-numeric characters (\D is shorthand for those, the two / things are delimiters, like quotes for strings) and replaces them all with '' (the empty string). So all you're left with is the number.

It's not a true number by the way (it's a string) but will be automatically type converted to one in most cases if math is performed on it or it's compared (without type specific syntax) to a true number. In some cases you may have to type convert it manually. Like if you want to add another number to it or add it to another number. The easiest way to do that is to put a + sign in front of it, example:


var divnum = +(this.id.replace(/\D/g, ''));

Now it's a true number. And if that's what you need, best to do that right off when you create/obtain it because those automatic type conversions are often only temporary (for the duration of that operation).

ggalan
11-27-2011, 05:03 PM
when you do this, are you adding anything?

var divnum = +(this.id.replace(/\D/g, ''));

can you do this?

var divnum = (this.id.replace(/\D/g, ''))*1;

jscheuer1
11-27-2011, 05:30 PM
You're not adding anything. You're signing it, declaring it as a positive version. Now that might seem strange, even ill advised. But positive signing a positive number gives a positive result and positive signing a negative number is a negative result. The opposite is true if you sign it with a minus - sign (negative). Then a positive becomes negative and a negative becomes positive.

You can multiply it by 1 like you suggest. I've been told that's slightly more computationally expensive that signing it. You could also subtract 0 from it - also more expensive I've been told. These are minor things for sure. There are other ways, parseFloat() - probably the most expensive, and parseInt() - the next most costly. However, if it is a Float, I think any of those 'cheaper' methods (except paresInt) will use parseFloat(). The benefit of using one of the parse methods is you can optionally specify the base (like base 10, hex, binary, ocatal, etc.). In some cases it's important to test it after conversion to make sure it's not isNaN. But I don't think any of this bears on the use you will put this number to, does it?

ggalan
11-27-2011, 09:19 PM
But I don't think any of this bears on the use you will put this number to, does it?
no
but thank you for the lesson on numbers