How to select an option with CasperJS

本秂侑毒 提交于 2019-12-08 22:31:07

问题


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:


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+"]".



来源:https://stackoverflow.com/questions/30136361/how-to-select-an-option-with-casperjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!