How to select an option with CasperJS

2019-01-29 02:18发布

I try to set select option attribute to selected. But I try to avoid using nth-child in CasperJS because there are bugs in PhantomJS's nth-child. So I try to use this as the subtitution of jQuery(css_path).

function setSelectedCountry(i){
    window.__utils__.echo("i :"+i);
    var query = "//*[@id='cboCountry']/optgroup[2]/option["+i+"]";
    __utils__.getElementByXPath(query).setAttribute("selected","selected");
}

But, when I evaluate that code by this way

this.evaluate(setSelectedCountry, 5);

The select option is not changed.

Moreover, when I try to trigger onblur() using

document.getElementById("cboCountry").onblur();

inside setSelectedCountry() funtion, there were nothing happened.

Why this happened?

Also, when I try to call the function with XPath expression, and the other one is using CSS selector, I got undefined error returned from CasperJS.

I use this function :

function getCityName(i){
    var query = "//*[@id='cboCity']/option["+i+"]";
    return __utils__.getElementByXPath(query).innerText;
}

then I got the other one:

function setSelectedCountry(i){
    var query = "#cboCountry > optgroup:nth-child(3) > option:nth-child("+i+")";
    jQuery(query).attr("selected", "selected").blur();
}

When I try to run both of them, then this is what I've got

PAGE.ERROR: TypeError: 'undefined' is not an object (evaluating
'__utils__.getElementByXPath(query).innerText')

Can you give me suggestions?

[EDITED]

Here is my markup : This one for cboCountry select option :

<select name="cboCountry" id="cboCountry" onkeypress="return selectItem();" onkeyup="event.cancelbubble=true;return false;" onkeydown="return handleKey();" onfocus="activeList=this;this.enteredText='';" onchange="//hs.DropCity();" onblur="hs.DropCity();"
class="txtBox">
  <option value="">-- --Select-- --</option>
  <optgroup label="Popular Destinations">
    <option value="MA05110065">Indonesia</option>
    <option value="MA05110067">Malaysia</option>
    <option value="MA05110069">Singapore</option>
    <option value="MA05110001">Thailand</option>
  </optgroup>
  <optgroup label="Other Destinations">
    <option value="MA05110083">Afghanistan</option>
    <option value="MA05110124">Albania</option>
    <option value="MA05110133">Algeria</option>
    <option value="MA05110186">American Samoa</option>
    <option value="MA05110103">Andorra</option>
    <option value="MA05110014">Angola</option>
    <option value="MA05110135">Anguilla (UK)</option>
    <option value="MA05110136">Antigua and Barbuda</option>
    <option value="MA05110171">Argentina</option>
    <option value="MA05110206">Armenia</option>
    <option value="MA05110183">Venezuela</option>
    <option value="MA05110070">Vietnam</option>
    <option value="MA05110013">Western Sahara</option>
    <option value="MA05110082">Yemen</option>
    <option value="MA05110027">Zambia</option>
    <option value="MA05110028">Zimbabwe</option>
  </optgroup>
</select>

And this one for cboCity select option :

<select name="cboCity" id="cboCity" onkeypress="return selectItem();" onkeyup="event.cancelbubble=true;return false;" onkeydown="return handleKey();" onfocus="activeList=this;this.enteredText='';" onchange="//hs.DropLocation();" onblur="hs.DropLocation();"
class="txtBox">
  <option value="">-- --Select-- --</option>
  <option value="">-- Select --</option>
  <option value="MA02022810">Ambarawa</option>
  <option value="MA09090008">Ambon</option>
  <option value="MA08090042">Anyer</option>
  <option value="MA02022861">Wonosobo</option>
  <option value="MA06060051">Yogyakarta</option>
</select>

1条回答
SAY GOODBYE
2楼-- · 2019-01-29 02:48

The problem is the distinction between property and attribute. Browsers usually don't re-evaluate attributes when you change them in the DOM. In those cases, you would need to change the property behind that attribute on the DOM element.

In this case, you need to change the selected index. The select element has the selectedIndex property that you can change to the intended option which you can get through option.index:

function setSelectedCountry(i){
    __utils__.echo("i :"+i);
    var opt = "//*[@id='cboCountry']/optgroup[2]/option["+i+"]";
    var select = document.getElementById('cboCountry');
    select.selectedIndex = __utils__.getElementByXPath(opt).index;
    select.onblur(); // or `onchange()`
}

See this answer for more information on the option index.


"//*[@id='cboCity']/option["+i+"]" cannot work, because this expression will match options that are direct children of a #cboCity element, but you have an optgroup inbetween. Either use "//*[@id='cboCity']//option["+i+"]" or "//*[@id='cboCity']/optgroup/option["+i+"]".

查看更多
登录 后发表回答