[jQuery] Re: Very confused!
Weel, it's simple (easy to say after a couple of tries, I must admit). The real reason is in the REGEXP, which does not work at all for numbers, but only on empty []. So, the FIRST run of the script works in both cases, since the [] are empty. But then, on the second run, the REGEXP is failing miserably... only on the broken code (the div productOption AFTER the #newProductOption div). Why ? Because starting at the 2nd run, the var tpl = JQ('.productOption:first') line is now retrieving, in this broken situation, the FIRST created .productOption div, with a name of [1000]. Since the REGEXP is failing, it does not match anything, so it does not CHANGE anything... your cloned node remains the same, cloning after cloning. On the working solution, of course, you always select the always-first div that does not contain an number in its name, so the REGEXP still matches. Try to put [2000], you'll see it's failing. But, overall, I think your code is complex: why take :first, if your template div is the last ? Putting a more logical (to me) last would work like a charm. It took me a bit of time because initially, I thought that you would extract the number from the name, increment it, and write it to the new node. But with the way your algorithm works (much simpler than my first though), why not simply create a node on the fly, with JQ('my html code [' + OINDEX + '] blabla') ? Best, Order of divs make the jQuery selector retrieve different On Aug 25, 4:36 pm, Stephan Beal [EMAIL PROTECTED] wrote: On Aug 24, 3:10 pm, Scott Sauyet [EMAIL PROTECTED] wrote: var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); For your code you don't need the \d?, because your template doesn't have a number in it. That said, your template code is incorrect: JQ(tpl).find('[EMAIL PROTECTED]').each(function(){ Carefully count the [ and ] characters in that string and you'll find that they're mismatched and cannot match your regex: var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); Also, it wouldn't surprise me if you need to escape the [ and ] inside the find() command, as detailed in the FAQ: http://docs.jquery.com/Frequently_Asked_Questions#How_do_I_select_an_... But apparently your working example demonstrates that that's not necessary. THAT i can't explain, though. :)
[jQuery] Re: Very confused!
Scott, Thanks for that replace tip. I've stopped using replace and am now getting what I want. Weird! Matt
[jQuery] Re: Very confused!
On Aug 24, 3:10 pm, Scott Sauyet [EMAIL PROTECTED] wrote: var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); For your code you don't need the \d?, because your template doesn't have a number in it. That said, your template code is incorrect: JQ(tpl).find('[EMAIL PROTECTED]').each(function(){ Carefully count the [ and ] characters in that string and you'll find that they're mismatched and cannot match your regex: var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); Also, it wouldn't surprise me if you need to escape the [ and ] inside the find() command, as detailed in the FAQ: http://docs.jquery.com/Frequently_Asked_Questions#How_do_I_select_an_element_that_has_weird_characters_in_its_ID.3F But apparently your working example demonstrates that that's not necessary. THAT i can't explain, though. :)
[jQuery] Re: Very confused!
OK I've got the same problem happening again in a different page. I'd love to know why this is happening before I start re-arranging all of my html. Anyone know what could be causing this? matt On Aug 23, 10:23 pm, goodieboy [EMAIL PROTECTED] wrote: OK, turns out I am crazy, but thanks to html and javascript. So, depending on the arrangement of the default .productOption div, I either get the behavior you all have described, or the behavior I have described. Below, if '.productOption' is after the '#newProductOptions' div, the number doesn't increment. If it's before '#newProductOptions', wallah!. Wow, a whole 2 days of me rubbing my forehead raw, and a room booming full of, wtf f?!? :-) I'm happy now. Try it and see what happens: %= javascript_include_tag('jquery') % script JQ = $; var OINDEX=1000; JQ(function(){ JQ('#addProductOption a').click(function(){ addProductOption(); return false; }); function addProductOption(){ var tpl = JQ('.productOption:first').clone(true); JQ(tpl).find('[EMAIL PROTECTED]').each(function(){ var n = JQ(this).attr('name'); var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); JQ(this).attr('value', new_name); JQ(this).attr('name', new_name); }); OINDEX++; JQ('#newProductOptions').append(tpl); tpl.show(); } }); /script div id=addProductOptiona href=#add/a/div div id=newProductOptions /div !-- down here, OINDEX doesn't increment inside of the each handler... move this div above newProductOptions to get the correct behavior -- div class=productOption input name=product_options[][name] type=text value= / /div
[jQuery] Re: Very confused!
goodieboy wrote: OK I've got the same problem happening again in a different page. I'd love to know why this is happening before I start re-arranging all of my html. Anyone know what could be causing this? No, I don't understand it. This is really odd. I did note that it's in the regex.replace that this is happening. If you replace this line var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); with this one var new_name = 'product_options[' + OINDEX + ']'; Everything works fine. But I'm assuming that in your real system, you actually need a replace. Bizarre. For anyone who wants to look at them live, I've posted it to http://scott.sauyet.com/Javascript/Demo/2007-08-24a/Broken/ http://scott.sauyet.com/Javascript/Demo/2007-08-24a/Working/ Any JQuery gurus have suggestions? Good luck, -- Scott On Aug 23, 10:23 pm, goodieboy [EMAIL PROTECTED] wrote: OK, turns out I am crazy, but thanks to html and javascript. So, depending on the arrangement of the default .productOption div, I either get the behavior you all have described, or the behavior I have described. Below, if '.productOption' is after the '#newProductOptions' div, the number doesn't increment. If it's before '#newProductOptions', wallah!. Wow, a whole 2 days of me rubbing my forehead raw, and a room booming full of, wtf f?!? :-) I'm happy now. Try it and see what happens: %= javascript_include_tag('jquery') % script JQ = $; var OINDEX=1000; JQ(function(){ JQ('#addProductOption a').click(function(){ addProductOption(); return false; }); function addProductOption(){ var tpl = JQ('.productOption:first').clone(true); JQ(tpl).find('[EMAIL PROTECTED]').each(function(){ var n = JQ(this).attr('name'); var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); JQ(this).attr('value', new_name); JQ(this).attr('name', new_name); }); OINDEX++; JQ('#newProductOptions').append(tpl); tpl.show(); } }); /script div id=addProductOptiona href=#add/a/div div id=newProductOptions /div !-- down here, OINDEX doesn't increment inside of the each handler... move this div above newProductOptions to get the correct behavior -- div class=productOption input name=product_options[][name] type=text value= / /div
[jQuery] Re: Very confused!
goodieboy wrote: What am I doing wrong? Here is an example: for(i=0; i10; i++){ $('input').each(function(){ $(this).attr('name', i); }); } John's response shows how to get this, if that index is really what you want. Why this goes wrong, though is a different matter. You have a nested loop. The .each loop is setting the name attribute to the current value of i for each input. The the outer loop runs again and resets each one to a new value. If this is just a simplification of what you're doing though, and you need something more than the index, you might also run into issues with closures. Google should help with that: http://www.google.com/search?q=javascript+closure Good luck, -- Scott
[jQuery] Re: Very confused!
Hi John, Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); How do you access i from within the inner loop? I'm guessing that the execution of the inner each loop doesn't really occur until the outer one has? I just can't seem to get dynamic values into each handlers like that. I know that with Prototype, there is a function(){}.bind feature, is that used on each also? Thanks, Matt On Aug 23, 12:16 am, John Resig [EMAIL PROTECTED] wrote: Like so: $('input').each(function(i){ $(this).attr('name', i); }); Nice and simple! --John On 8/23/07, goodieboy [EMAIL PROTECTED] wrote: OK, I thought I knew jQuery pretty well. But this is completely stumping me. What I want to do is iterate through a newly attached set of input elements, and set their names based on a dynamic (incrementing) number. But the only value that ever gets used is the initial value of the variable. I've tried everything, attaching the value to the dom object, and then in the loop trying to access it (still the same original value), using a global variable, a function to get the value, all return the original value that I set the variable to. What am I doing wrong? Here is an example: for(i=0; i10; i++){ $('input').each(function(){ $(this).attr('name', i); }); } Here, all of the inputs get the value 9. How can I make then all get the current incremented value of i? Thank you for any tips! Matt
[jQuery] Re: Very confused!
Your code looks like it'll work, it could even be reduced to: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').attr('name', 'option_num_' + i); }); --John On 8/23/07, goodieboy [EMAIL PROTECTED] wrote: Hi John, Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); How do you access i from within the inner loop? I'm guessing that the execution of the inner each loop doesn't really occur until the outer one has? I just can't seem to get dynamic values into each handlers like that. I know that with Prototype, there is a function(){}.bind feature, is that used on each also? Thanks, Matt On Aug 23, 12:16 am, John Resig [EMAIL PROTECTED] wrote: Like so: $('input').each(function(i){ $(this).attr('name', i); }); Nice and simple! --John On 8/23/07, goodieboy [EMAIL PROTECTED] wrote: OK, I thought I knew jQuery pretty well. But this is completely stumping me. What I want to do is iterate through a newly attached set of input elements, and set their names based on a dynamic (incrementing) number. But the only value that ever gets used is the initial value of the variable. I've tried everything, attaching the value to the dom object, and then in the loop trying to access it (still the same original value), using a global variable, a function to get the value, all return the original value that I set the variable to. What am I doing wrong? Here is an example: for(i=0; i10; i++){ $('input').each(function(){ $(this).attr('name', i); }); } Here, all of the inputs get the value 9. How can I make then all get the current incremented value of i? Thank you for any tips! Matt
[jQuery] Re: Very confused!
goodieboy wrote: Hi John, Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); Try this: $('form div.options').each(){function( i ){ var j = i; $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + j); }); }); If that works, then try looking up Javascript closures. If not, then I'm a little stumped. -- Scott
[jQuery] Re: Very confused!
Well the syntax in both examples are wrong! :) thanks to my original example. Fixing the syntax still gives the same results. The value set in the inner each is the last value set to i. Try this: $('div').each(function( i ){ $(this).find('input').attr('name', 'option_num_' + i); }); All elements will have the same name. the i appended to the name will have the last/greatest value of i. I realize that these are real/ realtime loops, their event handlers getting fired at different times, but I still can't find a solution?! Anymore ideas? Thanks, Matt On Aug 23, 12:03 pm, Scott Sauyet [EMAIL PROTECTED] wrote: goodieboy wrote: Hi John, Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); Try this: $('form div.options').each(){function( i ){ var j = i; $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + j); }); }); If that works, then try looking up Javascript closures. If not, then I'm a little stumped. -- Scott
[jQuery] Re: Very confused!
I meant NOT real/realtime loops like a for. -matt On Aug 23, 12:30 pm, goodieboy [EMAIL PROTECTED] wrote: Well the syntax in both examples are wrong! :) thanks to my original example. Fixing the syntax still gives the same results. The value set in the inner each is the last value set to i. Try this: $('div').each(function( i ){ $(this).find('input').attr('name', 'option_num_' + i); }); All elements will have the same name. the i appended to the name will have the last/greatest value of i. I realize that these are real/ realtime loops, their event handlers getting fired at different times, but I still can't find a solution?! Anymore ideas? Thanks, Matt On Aug 23, 12:03 pm, Scott Sauyet [EMAIL PROTECTED] wrote: goodieboy wrote: Hi John, Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); Try this: $('form div.options').each(){function( i ){ var j = i; $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + j); }); }); If that works, then try looking up Javascript closures. If not, then I'm a little stumped. -- Scott
[jQuery] Re: Very confused!
I don't know what you're doing, but it works great for me: http://dev.jquery.com/~john/test/each.html I'm using value so that it's easy to see the results. --John On 8/23/07, goodieboy [EMAIL PROTECTED] wrote: Well the syntax in both examples are wrong! :) thanks to my original example. Fixing the syntax still gives the same results. The value set in the inner each is the last value set to i. Try this: $('div').each(function( i ){ $(this).find('input').attr('name', 'option_num_' + i); }); All elements will have the same name. the i appended to the name will have the last/greatest value of i. I realize that these are real/ realtime loops, their event handlers getting fired at different times, but I still can't find a solution?! Anymore ideas? Thanks, Matt On Aug 23, 12:03 pm, Scott Sauyet [EMAIL PROTECTED] wrote: goodieboy wrote: Hi John, Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); Try this: $('form div.options').each(){function( i ){ var j = i; $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + j); }); }); If that works, then try looking up Javascript closures. If not, then I'm a little stumped. -- Scott
[jQuery] Re: Very confused!
From: goodieboy Actually that was a bad example sorry! What about something like this: $('form div.options').each(){function( i ){ $(this).children('[EMAIL PROTECTED]').each(function(){ $(this).attr('name', 'option_num_' + i); }); }); How do you access i from within the inner loop? I'm guessing that the execution of the inner each loop doesn't really occur until the outer one has? I just can't seem to get dynamic values into each handlers like that. I know that with Prototype, there is a function(){}.bind feature, is that used on each also? ... Well the syntax in both examples are wrong! :) thanks to my original example. Fixing the syntax still gives the same results. The value set in the inner each is the last value set to i. Try this: $('div').each(function( i ){ $(this).find('input').attr('name', 'option_num_' + i); }); All elements will have the same name. the i appended to the name will have the last/greatest value of i. I realize that these are real/ realtime loops, their event handlers getting fired at different times, but I still can't find a solution?! Anymore ideas? I meant NOT real/realtime loops like a for. -matt I think you must be seriously misunderstanding something, but I'm not quite sure what it is. There are no event handlers in either of the code snippets above, no events that get fired at different times, and nothing asynchronous. The each function is just as realtime as a for loop. If you trace into the code for each, you will see that it simply runs a for loop and calls your callback function each time through the loop. Try it: add a debugger; statement before your code, load it in Firebug or any JavaScript debugger, and trace into the each() function. It's a very simple bit of code. Maybe it would help to post a link to a test page that demonstrates whatever problem you're running into. Then we could see your code in context. -Mike
[jQuery] Re: Very confused!
John Resig wrote: I don't know what you're doing, but it works great for me: http://dev.jquery.com/~john/test/each.html I'm using value so that it's easy to see the results. And another version modeled on John's that uses the indices for both the inner and outer loops is at http://scott.sauyet.com/Javascript/Demo/2007-08-03a/ (My thoughts about closures seem to have been red herrings.) -- Scott
[jQuery] Re: Very confused!
Hi, I know there are no event handlers in the classic sense, I was referring to the function that handles the iteration passed to each. In a way, it is an event handler though. And by event I mean, a single iteration. I am however confused. :) because the last example posted (outer and inner loop) work, and the code that I've written doesn't. I found some of my code that actually does work. I'm going to try and extract the stuff that doesn't and post back here. Sorry for the confusion, but there is something strange happening. And thanks for all you chipping in and helping out. Matt
[jQuery] Re: Very confused!
OK, turns out I am crazy, but thanks to html and javascript. So, depending on the arrangement of the default .productOption div, I either get the behavior you all have described, or the behavior I have described. Below, if '.productOption' is after the '#newProductOptions' div, the number doesn't increment. If it's before '#newProductOptions', wallah!. Wow, a whole 2 days of me rubbing my forehead raw, and a room booming full of, wtf f?!? :-) I'm happy now. Try it and see what happens: %= javascript_include_tag('jquery') % script JQ = $; var OINDEX=1000; JQ(function(){ JQ('#addProductOption a').click(function(){ addProductOption(); return false; }); function addProductOption(){ var tpl = JQ('.productOption:first').clone(true); JQ(tpl).find('[EMAIL PROTECTED]').each(function(){ var n = JQ(this).attr('name'); var new_name = n.replace(/\[\d?\]/, '[' + OINDEX + ']'); JQ(this).attr('value', new_name); JQ(this).attr('name', new_name); }); OINDEX++; JQ('#newProductOptions').append(tpl); tpl.show(); } }); /script div id=addProductOptiona href=#add/a/div div id=newProductOptions /div !-- down here, OINDEX doesn't increment inside of the each handler... move this div above newProductOptions to get the correct behavior -- div class=productOption input name=product_options[][name] type=text value= / /div
[jQuery] Re: Very confused!
Like so: $('input').each(function(i){ $(this).attr('name', i); }); Nice and simple! --John On 8/23/07, goodieboy [EMAIL PROTECTED] wrote: OK, I thought I knew jQuery pretty well. But this is completely stumping me. What I want to do is iterate through a newly attached set of input elements, and set their names based on a dynamic (incrementing) number. But the only value that ever gets used is the initial value of the variable. I've tried everything, attaching the value to the dom object, and then in the loop trying to access it (still the same original value), using a global variable, a function to get the value, all return the original value that I set the variable to. What am I doing wrong? Here is an example: for(i=0; i10; i++){ $('input').each(function(){ $(this).attr('name', i); }); } Here, all of the inputs get the value 9. How can I make then all get the current incremented value of i? Thank you for any tips! Matt