Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
470 views
in Technique[技术] by (71.8m points)

javascript - How to select an option with CasperJS

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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...