-1

I need to solve a little problem of simulation of user's actions on site: select certain <option> tag in <select> and then imitate pressing the button "OK". There are several rows with <select> tags so I decided do it in a for loop with jQuery. But this code works only in the first iteration (but works pretty well - numbers changing and then alert('gooood-goood') shows).

Interestingly, the loop continues and vars 'option' and 'select' assigned just as they should, even alert() of the second button shows, indicating that event onclick worked, but <select> tags in second row remained at zero, and there was no simulate of onclick event actually. This code seemed to refuse to work in all loops of the cycle, but the first.

The ultimate goal - to simulate the user and solve exactly on JavaScript is not required. I have a dynamically changing parameters in the loop, I think that Selenium IDE may be the answer for me but I need it work with some logic and changed parameters in the loop.

Here two lists: script and html where script should be executed.

<input type="button" id="done" value="C'mon" />

<table>
  <tr>
    <td id="c10">
      <select name="c0">
        <option value="0" selected>0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9">9</option>
      </select>
    </td>
    <td id="c11">
      <select name="c1">
        <option value="0" selected>0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9">9</option>
      </select>
    </td>
    <td id="c12">
      <input value="OK" type="button" onclick="alert('gooood-goood')" />
    </td>
  </tr>
  <tr>
    <td id="c20">
      <select name="c0">
        <option value="0" selected>0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9">9</option>
      </select>
    </td>
    <td id="c21">
      <select name="c1">
        <option value="0" selected>0</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</optiaon>
        <option value="8">8</option>
        <option value="9">9</option>
      </select>
    </td>
    <td id="c22">
      <input value="OK" type="button" onclick="alert('gooood-goood')" />
    </td>
  </tr>
</table>

And script then:

function foo() {
  alert('inside');
  
  var comb = rand(10, 99) + '', row = 1, col = 0;

  for (; row <= 2; row++) {
    for (; col <= 1; col++) {
      var select = '#c' + row + col + ' select[name=c' + col + ']';
      var option = "#c" + row + col + " select option[value=" + comb[col] + "]";

      $(select).change(function () {
        $(option).prop('selected', true);
      });

      $(select).change();

      if (col == 1) {
        var i = col + 1;
        $('#c' + row + i + ' input').click();
      }
    }
    
    col = 0;
    comb = rand(10, 99);
  }
}

$(function () {
  document.getElementById('done').onclick = foo;
});


function rand(min, max) { // Generate a random integer
  if (max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  } else {
    return Math.floor(Math.random() * (min + 1));
  }
}

UPDATE

I don't know what I've done, but it's working now. Same code :/

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
vudex
  • 13
  • 5
  • It's your typical JavaScript "function-in-a-loop" problem. – Matt Ball Aug 31 '12 at 01:51
  • possible duplicate of [Javascript function is using the last known parameters in loop?](http://stackoverflow.com/questions/9439700/javascript-function-is-using-the-last-known-parameters-in-loop) – Matt Ball Aug 31 '12 at 01:59
  • I misunderstanding something general in javascript scopes. Can't get it, if vars 'select' and 'option' change, why $(select).change() doesn't work with new var 'select' for example in second iteration? – vudex Aug 31 '12 at 06:12

2 Answers2

0

In your code:

>  var option = "#c"+ row + col + " select option[value=" + comb[col] + "]";
> 
>  $(select).change(function(){
> 
>    $(option).prop('selected', true);
>  });

The variable option in the change function has a closure to the outer option variable, so the value will be whatever option was when the loop ended, which is (where comb[col] is set to 6):

 "#c21 select option[value=6]";

BTW, the way you are selecting a digit from comb will fail in browsers that don't allow access to string characters by index (some versions of IE at least) and means the rand function may as well just return a number from 0 to 9 inclusive.

You can solve the first issue using something like:

comb.substring(1,2)

or

 comb.charAt(1)

which makes what you are doing a lot more obvious.

Have you considered instead just getting the form controls and iterating over those, independently of the table structure? It would be very much simpler.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • _Have you considered instead just getting the form controls and iterating over those, independently of the table structure? It would be very much simpler._ Can you be more specific? I've lost you here:( – vudex Aug 31 '12 at 07:00
  • Did you mean get all neccesary DOM elements and give them event handlers on change and click? – vudex Aug 31 '12 at 07:04
  • The [form.elements](http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-76728479) collection gives you all the form controls regardless of the page structure. All tests can then be based on the control name independently of the document layout. – RobG Sep 01 '12 at 03:46
0

Okay, i just realized. comb = rand(10, 99); after first iteration became not a string.

Just need to fix that comb = rand(10, 99) + '';

Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134