dijit/form/select to select search fields in Arc JS API - arcgis

I'm brand new to javascript, dojo and HTML and I've searched everywhere for examples of this and cannot find any.
I have a map with some feature points and a find task to highlight the feature points on the map, and display them in a grid with it's field attributes. This works great when I specify the search field as:
findParams.searchFields = ["LOCATION"];
But if I add:
findParams.searchFields = ["LOCATION", "MODEL_NUM"];
The grid displays results from multiple fields (ie. searching for attributes in LOCATION "A" would also find attributes in MODEL_NUM containing the letter "A"). So I decided to add a drop down menu select to specify which field to search in (one at a time) so the results are more precise.
So I added the following dijit:
<select id="fieldSelect" data-dojo-type="dijit/form/Select" name="fieldSelect">
<option value="" selected="selected">Select a field</option>
<option value="MODEL_NUM">Model Number</option>
<option value="LOCATION">Location</option>
<option value="NUM_DEFICIENCIES">Number of Deficiencies</option>
<option value="INSTALL_DATE">Install Date</option>
</select>
I then modified the search field statement to:
findParams.searchFields = "[" + "\"" + dom.byId("fieldSelect").value +
"\"" + "]";
When I click my search button I get an Uncaught TypeError: a.join is not a function (FindParameters.js:5)
I hope this is enough information. Does anyone have a solution or a recommendation?
UPDATE
After a suggestion to pass an array and not a string to the findParams.searchFields, I made the following changes:
findParams.searchFields = [];
findParmas.searchFields.push(dom.byId("fieldSelect").value);
This still gave me attribute results from multiple fields. After running a couple small tests:
var selectedField = document.getElementById('fieldSelect').value;
var index = selectedField.options[selectedField.selectedIndex].value;
And:
var selectedField = dom.byId('fieldSelect').value;
I'm finding that in the Chrome developer tools debugger, when I created a breakpoint at that line and executed the statement, both examples had the value of selectedField as 'undefined'.
Is this an issue of not getting the value from the drop down select dijit?
If no value is passed to findParams.searchFields, the API assumes all fields are valid, which is why I'm getting attribute results from multiple fields.
Thanks.

Use dijit.byId instead of dom.byId.
The following works for me:
var value = dijit.byId("fieldSelect").value;
if ("" != value) {
findParams.searchFields = [value];
} else {
findParams.searchFields = ["MODEL_NUM", "LOCATION", "NUM_DEFICIENCIES", "INSTALL_DATE"];
}

I found the problem.
Ultimately it was the registry.byId that led me to the answer, I had to rearrange some code after I realized the searchFields was in the wrong function and not in the function that is called when I click the search button.
But when accessing the dijit, the only thing that worked was registry.byId to access the dijit node and pass the value of the selected value into my searchFields.
Thanks.

Related

Unable to find web Element, Elements change based on field highlighting

Unable to find the Element, tried few ways but unable to get to the element
Picture 1:
id="1_s_1_l_MTO_Transaction_Type" and Class="" (is empty)
In the picture, the highlighted HTML (Document_For) is the next field and you can see Class being added as class="edit-cell ui-state-highlight
Picture 2:
The desired field is highlighted in this picture and id="1_s_1_l_MTO_Transaction_Type" and Class="edit-cell ui-state-highlight" and New HTML is added
<input id="1_MTO_Transaction_Type"...........
I tried the below:
driver.findElement(By.id("1_s_1_l_MTO_Transaction_Type")).click();
driver.findElement(By.xpath(("//tr[starts-with(#class,'ui-widget-content') and #role='row']//td[id='1_s_1_l_MTO_Transaction_Type']"))).click();
driver.findElement(By.xpath(("//tr[#id='1']/td[id='1_s_1_l_MTO_Transaction_Type']"))).click();
All the above gave me Unable to find element
Picture 3:
More HTML to figure out how to find element
It will be a great Help as I have a series of Elements to find in the same way.
Select the Transaction Type using the id and follow the code below.
// Select Transaction Type
String Transaction_Type = ExcelUtils.getCellData(8, 2);
driver.findElement(By.xpath(("//td[contains(#id,'Transaction_Type')]"))).click();
driver.findElement(By.id("s_1_2_47_0_icon")).click();
driver.findElement(By.xpath("//li[#class='ui-menu-item']/div[contains(text(), '" + Transaction_Type + "')]")).click();
Map the column and click on an index (as i'm seeing, when the column cell is clicked, the input field is created, so you have to click it first)
Try it like this (this is C#, java below):
List<IWebElement> TransactionTypeFields => driver.FindElements(By.CssSelector("td[id*='Transaction_type']"));
IWebElement TransactionTypeInput => driver.FindElement(By.CssSelector("td[id*='Transaction_type'] input"));
public void TypeInTransactionTypeCell(string value, int index)
{
TransactionTypeFields[index].Click();
TransactionTypeInput.SendKeys(value);
}
in java, using your logic, should be something like this (there may be some syntax errors as im using notepad++):
public void TypeInTransactionTypeCell(string value, int index)
{
driver.findElements(By.cssSelector("td[id*='Transaction_type']")).get(index).click();
driver.findElement(By.cssSelector("td[id*='Transaction_type'] input")).sendKeys(value);
}
Let me know if it works!

Select by attribute in Selenium

Is there a way to select by attribute? We have select drop down with incomplete visible text. We have to rely only on title. Is there a way to select by attribute?
My HTML looks something like
<select id="some ID" name="some Name" class="some class"
<option value="random number" title="testing pvt ltd">testing...</option>
<option value="random number" title="selenium HQ documentation">testing...
</option>
<option value="random number" title="selenium HQ API Request">selenium HQ...
</option>
Not natively, but nothing prevents you from implementing that method yourself, should you need it.
Something like this in C# should do the trick. Translation in your favourite language shouldn't be too hard.
public IWebElement GetWebElementByAttributeValue(string tagType, string attributeName, string attributeValue)
{
//finds all tags of a type, for example h1,a,etc...
//Here Driver is my instance of WebDriver
var allTags = Driver.FindElements(By.XPath("//" + tagType));
//iterate over all elements of that tag, and find the one whose attribute value you want
foreach (var v in allTags)
{
if ((v.GetAttribute.getText().equals(attributeName))
return v;
}
return null;
}
for you you would call it like that :
WebElement chosenOption = GetWebElementByAttributeValue("option","title","testing pvt ltd");
Hope this helps !
Naturally - the locators will go after the specific attribute and value.
Here are samples based on your source; xpath:
//select/option[#title="testing pvt ltd"]
If you're not familiar with xpath, it reads - select the option element that is a direct descendant (e.g. a child) of a select one, and has an attribute title (note the # char, which denotes thst an attribute name follows) with that value.
Absolutely the same with CSS:
select>option[title="testing pvt ltd"]
In general in CSS you can skip the double quotes around the value, if there's no whitespace in it - not like in your case, they are needed here.
el("input[value*='Edit'][type='submit']")
works without issue. I am using Fluentlenium and it makes thing a whole lot easier.
Use selectByValue method under Select class.

Google signup page: Selenium cannot find select listbox

I would like to use selenium to select a value in the Month list box for birthday on google page: https://accounts.google.com/SignUp
When I view page code, the code for the list box looks like:
<select id="BirthMonth" name="BirthMonth">
<option value="">Month</option>
<option value="01" >January</option>
<option value="02" >February</option>
......
<option value="12" >December</option>
</select>
However, when I use Selenium driver.findElements(), I cannot find this select and its option elements. It looks like every list box on this page (as well as gender one) cannot be accessed.
Can anyone give some suggestion how Selenium can access to these elements? Thanks
The code is as follows:
driver.get("https://accounts.google.com/SignUp");
List<WebElement> inputElements = driver.findElements(By.xpath("//select[#name]"));
for(WebElement input: inputElements){
if(input.getTagName().equals("select")){
Select selectinput = new Select(input);
List<WebElement> selects = selectinput.getOptions();
}
}
I did not get the select element I want.
EDIT:
I also try to use Select select1 = new Select(driver.findElement(By.tagName("select"))) but still cannot find this BirthMonth list box. It is wired. There is only one listbox which is inside Javascritpt that can be accessed.
Here's a suggestion for how access these elements in Selenium, with a Java example.
It gets a little messy with CSS Selectors (which I generally prefer) because this month field has some fancy widgets on it to help hide your choices for security reasons. So here we go with XPath as our selector mechanism.
Take notice I broke it down - 1st by selecting the month, and 2nd by selecting the month itself. Hope that helps.
public class Google Month Example {
public static void main(String[] args) throws Exception {
// Just picked Firefox for this example
FirefoxDriver driver;
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(7, TimeUnit.SECONDS);
// Head to URL
driver.get("https://accounts.google.com/SignUp");
// Get the first click on the month field to generate the listbox pop-up
driver.findElement(By.xpath(".//*[#id='BirthMonth']/div")).click();
// This is ":a" because each item in this month list is assigned a hex value starting at an index of zero
driver.findElement(By.xpath(".//*[#id=':a']/div")).click();
// Check to see if November got selected
if (!driver.findElement(By.xpath(".//*[#id='BirthMonth']/div[1]")).getText().equals("November")) {
driver.close();
throw new RuntimeException("assertText 'November' failed");
}
// Close browser window
driver.quit();
}
}
Update: I realized you wanted to pass in the Month as an argument.
So swap out from the example above:
driver.findElement(By.xpath(".//*[#id=':a']/div")).click();
for the below code:
String month = "November";
driver.findElement(By
.xpath("//div[#class='goog-menuitem']/div[.='" + month + "']")).click();
Second Update:
So at one point you saw the HTML as:
<select id="BirthMonth" name="BirthMonth">
<option value="">Month</option>
<option value="01" >January</option>
<option value="02" >February</option>
......
<option value="12" >December</option>
</select>
But as I look at it in Chrome Dev Tools right now (pressing F12) after clicking on the Month field I see multiple small structure changes (posted what I see in the of the Gist link).Examples include select now becoming span and value="01" now shown as id=":0" (Why the counting starts at zero and not 1). Hope that explains some of why my example is different.

selenium webdriver select element

I have a select control on my site. I am using page objects to interact with the page. If I do (with the first 2 lines under my class and the selectByValue in my method)
#FindBy(id="foo")
private Select foo;
foo.selectByValue("myValue");
It fails with a null pointer. I also tried without the #FindBy.
Now if I do this in my method it all works fine and selects the correct item
Select foo = new Select(sDriver.findElement(By.id("foo")));
foo.selectByValue("myValue");
Here is the actual web snippet for that control (edited to protect the innocent)
<select id="foo" name="service_name">
<option selected="selected" value="one">one</option>
<option value="two">two</option>
<option value="three">three</option>
</select>
Let me say that I have a work around for my issue but I don't get why the "normal" path is not working.
Thats because the Select class has this constructor:
Select(WebElement element)
See the Javadoc
So if you do something like this:
#FindBy(id="foo")
private WebElement wannabeSelect;
Select realSelect = new Select(wannabeSelect);
realSelect.selectByValue("myValue");
It should work.
BTW, I am using the same approach as you in the "workaround" because I dont wanna cast new WebElement object when I need Select object. But anyways, the
sDriver.findElement(By.id("foo"));
returns WebElement, so thats why its working. You can also do this:
WebElement wannabeSelect = sDriver.findElement(By.id("foo"));
Select foo = new Select(wannabeSelect);
There are two ways to select the option value:
One:
// Denotes option value - technical name
select.selectByValue(fieldValue);
Two:
// Denotes option text that is actually visible to be selected
select.selectByVisibleText(fieldValue);
Other way I achieved this is by using below method for all my onchange dropdownselection boxes. Pass id and selection and it works
public void onchangedropdownselection(String object, String value) {
WebElement obj = driver.findElement(By.id(object));
obj.sendKeys(value);
obj.sendKeys(Keys.UP);
obj.sendKeys(Keys.DOWN);
}
By doing up and down we are initialzing the script onchange.......

Matching Variables of Two Elements (binding cycle and ui-selectable)

I need help with condensing my script so that a #div_x is related to a separate element img_x.
My project uses ui-selectable to grab points on a map and return an image set in a separate div via jquery cycle (as in here http://bit.ly/gH7Lm3).
I have bound the 'selectablestop' event to two functions - .hasClass and .append - in order to 1) detect if a point has been selected and 2) append the containing cycle div with a corresponding image (also, incidentally, contained within its own div). As is, it looks something like this:
$("#selectable").selectable().bind("selectablestop", function(event, ui) {
if($('#point_a').hasClass('ui-selected')){
$('#cycle').append('<div id="pic"><img src="image_a.jpg" /></div>');}
if($('#point_b').hasClass('ui-selected')){
$('#cycle').append('<div id="pic"><img src="image_b.jpg" /></div>');}
if($('#point_c').hasClass('ui-selected')){
$('#cycle').append('<div id="pic"><img src="image_c.jpg" /></div>');}
, etc.
My question:
Can I accomplish this with one argument, using a variable x instead of writing out each line matching point_a to img_a, point_b to img_b, etc. That is,
if($('#point_(variable)').hasClass('ui-selected')){
$('#cycle').append('<div id="pic"><img src="image_(matching variable).jpg" /></div>');}
Thanks! I've spent some time looking for a good approach.
Thanks to rdworth via Jquery forum for this solution:
<li id="point_a" data-image="image_a.jpg">...</li>
<li id="point_b" data-image="image_b.jpg">...</li>
$( ".ui-selected" ).each(function() {
$( "#cycle" ).append( "<div id='pic'><img src='" + $( this ).data( "image" ) + "'></div>" );
});