1

So, I'll admit to being a bit of a JS noob, but as far as I can tell, this should be working and it is not.

Background:

I have a form with 3 list boxes. The list boxes are named app1, db1, and db2. I'm using javascript to allow the user to add additional list boxes, increasing the name tag for each additional select box.

When I add additional app named boxes, the value increments properly for each additional field. If I try to add addtional db named selects, it fails to recognize the 2nd tag on the first loop through the array. This causes me to end up with 2 elements named db2. On each subsequent tag, it is recognized properly and is properly incremented.

Here is the HTML for the db1 tag:

<select name="db1">
  *options*
</select>

And db2:

<select name="db2">
  *options*
</select>

The tags are identical. Here is the function that I am using to figure out the next number in the sequence (note: tag is either app or db, tags is an array of all select tag names in the DOM, if I inspect tags, it gives me ['app1', 'db1', 'db2', '']):

function return_select_name(tag, tags) {
  matches = new Array();
  var re = new RegExp(tag + "\\d+", "g");
  for (var i = 0; i < tags.length; i++) {
    var found = re.exec(tags[i]);
    if (found != null) {
      matches.push(found[0]);
    }
  }
  matches = matches.sort();
  index = parseInt(/\d+/.exec(matches.last())) + 1;
  index = tag + index;
  return index;
}

If I add an app tag, it will return 'app2'. If I search for a db tag, it will return 'db2' on the first time through, db3 on the 2nd, etc, etc.

So basically, I'm sure I'm doing something wrong here.

3
  • It's not really clear what you are trying to achieve here. Are you trying to generate sequential names that go like 'db1','db2','db3'... etc? And then if you pass 'app' in you want it to start at 'app1'? Commented Jun 4, 2012 at 13:19
  • Basically yeah. Only with app, it should return app2, which it does. Commented Jun 4, 2012 at 13:20
  • I added the prototypejs tag, as the code won't work at all without it. Commented Jun 4, 2012 at 13:54

3 Answers 3

2

I'd handle it by keeping a counter for db and a counter for app to use to generate the names.

var appCounter = 1;//set this manually or initialize to 0 and
var dbCounter = 2;//use your create function to add your elements on pageload

Then, when you go to create your next tag, just increment your counter and use that as the suffix for your name:

var newAppElement = document.createElement('select');
newAppElement.name = 'app' + (++appCounter);
..

//  --OR for the db element--

var newDbElement = document.createElement('select');
newDbElement.name = 'db' + (++dbCounter );
..
Sign up to request clarification or add additional context in comments.

1 Comment

I like this, I was making it way more complicated than it needed to be.
1

The problem you are getting is that regex objects are stateful. You can fix your program by putting the regex creation inside the loop.

function return_select_name(tag, tags) {
  matches = new Array();
  // <-- regex was here
  for (var i = 0; i < tags.length; i++) {
    var re = new RegExp(tag + "\\d+", "g"); //<--- now is here
    var found = re.exec(tags[i]);
    if (found != null) {
      matches.push(found[0]);
    }
  }
  matches = matches.sort();
  index = parseInt(/\d+/.exec(matches[matches.length-1])) + 1; //<--- I dont think matches.last is portable, btw
  index = tag + index;
  return index;
}

In any case, if I were to do this myself, I would probably prefer to avoid the cmplicated text matching and just store the next tag indices in a variable or hash map.


Another suggestion: if you put parenthesis in your regex:

// /tag(\d+)/
var re = new RegExp(tag + "(\\d+)", "g");

Then you can use found[1] to get your number directly, without the extra step afterwards.

Comments

0

I know this has already been answered, but I put this together as a proof of concept.

http://jsfiddle.net/zero21xxx/LzyTf/

It's an object so you could probably reuse it in different scenarios. Obviously there are ways it could be improved, but I thought it was cool so I thought I would share.

The console.debug only works in Chrome and maybe FF.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.