This can be easily done by setting the selected
property of each option element to true
.
CasperJS by values
casper.selectOptionsByValues = function(selectCssSelector, values){
this.evaluate(function(selector, values){
[].forEach.call(document.querySelector(selector).options, function(opt){
if (values.indexOf(opt.value) !== -1) {
opt.selected = true;
}
});
}, selectCssSelector, values);
};
Values must be strings. You can use it like this:
casper.selectOptionsByValues("#xxx", [ "124", "125" ]);
CasperJS by text
A similar function can be achieved when selecting by text:
casper.selectOptionsByTexts = function(selectCssSelector, texts){
texts = texts.map(function(t){ return t.trim() });
this.evaluate(function(selector, texts){
[].forEach.call(document.querySelector(selector).options, function(opt){
if (texts.indexOf(opt.text.trim()) !== -1) {
opt.selected = true;
}
});
}, selectCssSelector, texts);
};
And use it like this:
casper.selectOptionsByTexts ("#xxx", [ "zazaza", "ajajaj" ]);
PhantomJS by values
The same thing can be done for PhantomJS directly:
function selectOptionsByValues(page, selectCssSelector, values){
page.evaluate(function(selector, values){
[].forEach.call(document.querySelector(selector).options, function(opt){
if (values.indexOf(opt.value) !== -1) {
opt.selected = true;
}
});
}, selectCssSelector, values);
};
and use it like this:
selectOptionsByValues(page, "#xxx", [ "124", "125" ]);
Triggering a change
It may be necessary to trigger a change event in case another element on the page depends on the
this.evaluate(function(selector, values){
[].forEach.call(...);
var evt = document.createEvent("UIEvents"); // or "HTMLEvents"
evt.initUIEvent("change", true, true);
document.querySelector(selector).dispatchEvent(evt);
}, selectCssSelector, values);
Change event trigger was taken from here.