dijit.InlineEditBox with highlighted html - dojo

I have some dijit.InlineEditBox widgets and now I need to add some search highlighting over them, so I return the results with a span with class="highlight" over the matched words. The resulting code looks like this :
<div id="title_514141" data-dojo-type="dijit.InlineEditBox"
data-dojo-props="editor:\'dijit.form.TextBox\', onFocus:titles.save_old_value,
onChange:titles.save_inline, renderAsHtml:true">Twenty Thousand Leagues <span
class="highlight">Under</span> the Sea</div>
This looks as expected, however, when I start editing the title the added span shows up. How can I make the editor remove the span added so only the text remains ?
In this particular case the titles of the books have no html in them, so some kind of full tag stripping should work, but it would be nice to find a solution (in case of short description field with a dijit.Editor widget perhaps) where the existing html is left in place and only the highlighting span is removed.
Also, if you can suggest a better way to do this (inline editing and word highlighting) please let me know.
Thank you !

How will this affect your displayed content in the editor? It rather depends on the contents you allow into the field - you will need a rich-text editor (huge footprint) to handle html correctly.
These RegExp's will trim away XML tags
this.value = this.displayNode.innerHTML.replace(/<[^>]*>/, " ").replace(/<\/[^>]*>/, '');
Here's a running example of the below code: fiddle
<div id="title_514141" data-dojo-type="dijit.InlineEditBox"
data-dojo-props="editor:\'dijit.form.TextBox\', onFocus:titles.save_old_value,
onChange:titles.save_inline, renderAsHtml:true">Twenty Thousand Leagues <span
class="highlight">Under</span> the Sea
<script type="dojo/method" event="onFocus">
this.value = this.displayNode.innerHTML.
replace(/<[^>]*>/, " ").
replace(/<\/[^>]*>/, '');
this.inherited(arguments);
</script>
</div>
The renderAsHtml attribute only trims 'off one layer', so embedded HTML will still be html afaik. With the above you should be able to 1) override the onFocus handling, 2) set the editable value yourself and 3) call 'old' onFocus method.
Alternatively (as seeing you have allready set 'titles.save_*' in props, use dojo/connect instead of dojo/method - but you need to get there first, sort of say.

Related

Selenium XPath find element where second text child element contains certain text (use contains on array item)

The page contains a multi-select dropdown (similar to the one below)
The html code looks like the below:
<div class="button-and-dropdown-div>
<button class="Multi-Select-Button">multi-select button</button>
<div class="dropdown-containing-options>
<label class="dropdown-item">
<input class="checkbox">
"
Name
"
</label>
<label class="dropdown-item">
<input class="checkbox">
"
Address
"
</label>
</div>
After testing in firefox developer tools, I was finally able to figure out the xPath needed in order to get the text for a certain label ...
The below XPath statement will return the the text "Phone"
$x("(//label[#class='dropdown-item'])[4]/text()[2]")
The label contains multiple text items (although it looks like there is just one text object when looking at the UI) in the label element. There are actually two text elements within each label element. The first is always empty, the second contains the actual text (as shown in the below image when observing the element through the Firefox developer tool's console window):
Question:
How do I modify the XPath shown above in order to use in Selenium's FindElement?
Driver.FindElement(By.XPath("?"));
I know how to use the contains tool, but apparently not with more complex XPath statements. I was pretty sure one of the below would work but they did not (develop tool complain of a syntax error):
$x("(//label[#class='dropdown-item' and text()[2][contains(., 'Name')]]")
$x("(//label[#class='dropdown-item' and contains(text()[2], 'Name')]")
I am using the 'contains' in order to avoid white-space conflicts.
Additional for learning purposes (good for XPath debugging):
just in case anyone comes across this who is new to XPath, I wanted to show what the data structure of these label objects looked like. You can explore the data structure of objects within your webpage by using the Firefox Console window within the developer tools (F12). As you can see, the label element contains three sub-items; text which is empty, then the inpput checkbox, then some more text which has the actual text in it (not ideal). In the picture below, you can see the part of the webpage that corresponds to the label data structure.
If you are looking to find the element that contains "Name" given the HTML above, you can use
//label[#class='dropdown-item'][contains(.,'Name')]
So finally got it to work. The Firefox developer environment was correct when it stated there was a syntax problem with the XPath strings.
The following XPath string finally returned the desired result:
$x("//label[#class='dropdown-item' and contains(text()[2], 'Name')]")

Selenium - Search for an element within element

Hi I want to hold element references in files somewhere. and then in run time search for elements withing referenced elements in Selenium how to do that.
For example- a Frame contains multiple text boxes -and multiple frames of similar properties exist where the textboxes are also duplicate. Something like I wanna reference the text box under a particular frame. But i wanna predefine the frame. and the specify that search under that frame[Something like Aliases in Testcomplete]
For Example - similar concept exist in Cheezy's Page-Objects. but not quite.
if you have a structure like this:
<div class='some class'>
<input class='input-button' value='submit'>Submit</input>
</div>
<div class='some class2'>
<input class='input-button' value='submit'>Submit</input>
</div>
and you want to find the first 'Submit' which is within the 'some class' div, you can do this:
parent_element = driver.find_element(:xpath, "//div[#class='some class']")
child_element = parent_element.find_element(:xpath, ".//input")
p.s. this is ruby code.

How to verify text across HTML elements in Selenium

Given the following code, how would I verify the text within using Selenium?
<div class='my-text-block>
<p>My first paragraph of text</p>
<p>My second paragraph of text</p>
</div>
I am wanting to, in one verifyText statement to capture all the text:
My first paragraph of text
My second paragraph of text
Is it possible?
Since you've tagged this with selenium-webdriver, I'm assuming you want a code example but because you've not stated what language you're using, I'll give you a python example. It should be easy to translate that to a different language if needed.
ok(driver.find_element("class", "my-text-block").text == "What I expect it to be")
The text attribute on a WebElement object simply contains all visible text within that element and all children elements.
And some lovely docs, of course.

Overwrite data-dojo-props for title attribute in dijit/TitlePane

I have created a TitlePane and wish to load data dynamically from a get method into the Title property. As of the current this all works. However, now when the data is loaded (4 separate types), its all getting mushed together. I wish to divide this received data evenly (25%) across the title.
For example:
<div id="tp2" data-dojo-type="dijit/TitlePane" data-dojo-props="title: 'I'm a TitlePane
Too'">
Click arrow to close me.
</div>
In this example the title is set to "I'm a TitlePane Too".
I wish to change the title so that each of the four words is evenly distributed across the title section of the pane. However there are no extra properties for doing this sort of thing.
Use the "set" method to set the new title.
E.g:-
<div id="tp2" data-dojo-type="dijit/TitlePane" data-dojo-props="title: 'I'm a TitlePane
Too'">
Click arrow to close me.
</div>
//For this above example, title is replaced as follows in JS
dijit.byId('tp2').set('title','New title');
Update: If this title pane is created dynamically without an ID, then get the widget object using the css query.
dijit.getEnclosingWidget(dojo.query(".dijitTitlePane")[0]).set('title','New title');
dojo.query(".dijitTitlePane") => will give array of all titlepane domNodes. From this chose the one you need. I chose at "0"th index i.e. 1st title pane node in the page.
Then I get the widget object of that domNode and then set the title.

dijit.form.Select won't set value programmatically

I have a dynamic dojo form in which I have a dijit.form.Select whose selected value I have tried to set dynamically through various ways. I get the select widget to load and show the data, but it always ignores my every attempt. I am using dojo 1.7.
var bcntryval = <?= $this->billingContact->countryId;?>;
var countryStore;
function onBillingShow() {
if (countryStore) countryStore.close();
countryStore = new dojo.data.ItemFileReadStore({url: 'CartUtilities.php?action=getcountries'});
dijit.byId("bcntry").setStore(countryStore, bcntryval); // does not set value! but does set the store
dijit.byId("bcntry").attr('value', String(bcntryval)); // doesn't set the value either
dijit.byId("bcntry").set('value', bcntryval)); // nor does this!
}
My markup for the bcntry widget is as follows:
<td><input data-dojo-type="dijit.form.Select" style="width: 10em;" data-dojo-props="sortByLabel:false, maxHeight:'-1'" data-dojo-id="bcntry" id="bcntry" name="bcntry" />
I've invested a fair amount of time on learning dojo. When it works its nice, but the docs leave a lot to be desired!
I am also seeing a similar problem with the dijit.form.FilteringSelect. That also ignores setting the value via javaScript.
I've also tried completely programmatic versions of this code. I have come to the conclusion that setting the value just doesn't work when you're selecting from a store.
This DID work, but its not dynamic.
<div name="scntry" data-dojo-type="dijit.form.Select" data-dojo-props="maxHeight:'-1',sortByLabel:false" value="<?= $this->shippingContact->countryId;?>" >
<?php foreach($this->countryList as $c):?>
<span value="<?= $c->id;?>"><?= $c->name;?></span>
<?php endforeach;?>
</div>
The reason most likely is, that youre trying to set the value of the 'searchAttr'. Instead you would want to set value to the 'identifier'.
Answer is here, check the timeout function on bottom shelf: http://jsfiddle.net/TTkQV/4/
The trick is to set the value as you would set option.value (not option.innerHTML).
normalSelect.set("value", "CA");
filteringSelect.set("value", "AK");
Take a look here, I believe this does what you want in the Dojo way:
Setting the value (selected option) of a dijit.form.Select widget
If not, you can always just use the actual dom selection object and use straight Javascript:
How do I programatically set the value of a select box element using javascript?