Docassemble 'autoterms' picking up whole `field' text? - docassemble

I'm rendering a list of choices using this formula:
generic object: DADict
question: |
(!!!) What is your desired outcome for your property?
fields:
- "Destroy current property": x.assets['destroy_current_property']
datatype: radio
code: property_choices
help: (!!!) To do
default: x.assets.destroy_current_property
- "Donate future property": x.assets['donate_future_property']
datatype: radio
code: property_choices
help: (!!!) To do
default: x.assets.donate_future_property
The choices from the code seem to be working fine, so I'm not going to get into that. The issue I'm having is that I also have a set of autoterms like this:
auto terms:
...
- property: |
prŏp′ər-tē
<br><br>
/ˈaset/
<br><br>
noun
<br><br>
plural noun: properties
<br><br>
1. Something owned; a possession.
<br><br>
2. A piece of real estate.
<br><br>
3. Something tangible or intangible to which its owner has legal title.
The auto terms work fine in most places. What's happening here, though, is that the entire "Donate current property" and "donate future property" are being assigned the class daterm. So the relevant part of the HTML looks like this:
<a tabindex="0" class="daterm" data-container="body" data-toggle="popover" data-placement="bottom" data-content="(!!!) To do" data-original-title="" title="">
Destroy current property
...
</a>
And I think it should (or at least I'd like it to) look more like this:
<a tabindex="0" data-container="body" data-toggle="popover" data-placement="bottom" data-content="(!!!) To do" data-original-title="" title="">
Destroy current <span class="daterm">property</span>
...
</a>
Is there something I can do so that the entire option / choice text is not selected as an autoterm, and only the one auto-text word is selected (i.e. perhaps this is user error)?

I tried to reproduce the issue with this interview:
mandatory: True
question: |
(!!!) What is your desired outcome for your property?
fields:
- "Destroy current property": bar
datatype: radio
code: property_choices
help: (!!!) To do
- "Donate future property": foo
datatype: radio
code: property_choices
help: (!!!) To do
---
auto terms:
property: |
prŏp′ər-tē
<br><br>
/ˈaset/
<br><br>
noun
<br><br>
plural noun: properties
<br><br>
1. Something owned; a possession.
<br><br>
2. A piece of real estate.
<br><br>
3. Something tangible or intangible to which its owner has legal title.
---
code: |
property_choices = ['Car', 'House', 'Plane']
In the resulting HTML, however, only the word "property" has the class daterm.
So I am not sure why the daterm encompasses the whole label, unless maybe you are using an old version of docassemble from a time when the help associated with a field would highlight the whole field label as a popover with green text. If that is the case, the help feature and the auto terms will be incompatible.
In general I don't recommend using auto terms; using terms and explicitly indicating where you want the terms to be highlighted avoids the problems that can happen when terms overlap.
In any case, the way that terms and auto terms work, the popover link is only going to encompass the term itself, not text around it.

Related

lxml.html XPATH expression for element when the test has to be applied to the text_content not the text

I have the following html
<html>
<body>
<p style="text-align:center;margin-bottom:0pt;margin-top:0pt;text-indent:0%;font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">
<a name="_marker_1"></a>
<a name="bananabread"></a>
<font style="font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">
<a name="bananabread"></a>Ban</font> <font style="font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">ana Bread</font>
</p>
<p style="text-align:center;margin-top:10pt;margin-bottom:0pt;text-indent:0%;font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">The Best You Ever Tasted</p>
<p style="margin-top:24pt;margin-bottom:0pt;text-indent:7.69%;font-style:italic;font-family:Times New Roman;font-size:10pt;font-weight:normal;text-transform:none;font-variant: normal;">If you don't agree that this is the best banana bread you have ever eaten well I would suggest you see your doctor</p>
<p style="margin-top:10pt;margin-bottom:0pt;text-indent:7.69%;font-family:Times New Roman;font-size:10pt;font-weight:normal;font-style:normal;text-transform:none;font-variant: normal;">Lots of text here describing what I am trying to capture</p>
<p style="text-align:center;margin-bottom:0pt;margin-top:0pt;text-indent:0%;font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">
<a name="_marker_2"></a>
<a name="bananapudding"></a>
<font style="font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">
<a name="bananapudding"></a>Banana</font>
<font style="font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">Pudding</font>
</p>
<p style="text-align:center;margin-top:10pt;margin-bottom:0pt;text-indent:0%;font-weight:bold;font-family:Times New Roman;font-size:10pt;font-style:normal;text-transform:none;font-variant: normal;">Creamy and Satisfying</p>
<p style="margin-top:24pt;margin-bottom:0pt;text-indent:7.69%;font-style:italic;font-family:Times New Roman;font-size:10pt;font-weight:normal;text-transform:none;font-variant: normal;">This is the same recipe your mother used when you were ten!</p>
<p style="margin-top:10pt;margin-bottom:0pt;text-indent:7.69%;font-family:Times New Roman;font-size:10pt;font-weight:normal;font-style:normal;text-transform:none;font-variant: normal;">Lots of text here describing what I am trying to capture</p>
</body>
</html>
I am trying to write an xpath expression to identify Banana Bread - my initial efforts were successful -
b_tree.xpath('.//*[starts-with(text(),"Banana Bread")]')
but I notice the error cases and upon investigation they are like the html above - another element is added inside the content I am searching for. Sometimes it is like above, a possibly unneeded font element, sometimes it is an anchor.
I worked with this answer (Related) but have not been successful
I can check for elements that have text_content() - clean up the text_content and then string match to my ultimate goal but I am hoping to learn to better apply xpath to these types of problems.
To be absolutely clear I need the text_content of the p element. But sometimes I just need the text of a font element. My existing XPATH expression works fine on the cases where there is not an intervening element. I do not know when I open the page the structure that was imposed on the document.
When the text() expression is applied to an element whose text content is interrupted by other elements, it returns a nodeset consisting of multiple text nodes, of which starts-with considers only the first. If you replace text() by ., you get the text value of the element, which is the concatenation of all text nodes, and that's what you want.
But there is still a problem with the spaces in an element like (attributes omitted, spaces are dots):
<p>
..<a></a>
..<a></a>
..<font>
....<a></a>Banana</font>
..<font>Pudding</font>
</p>
The text value of this element is _.._.._.._....Banana_..Pudding_ (underscores represent line feeds), therefore you must apply normalize-space, which normalizes this to Banana.Pudding, so that
.//*[starts-with(normalize-space(.),"Banana Pudding")]
finds this occurrence.
However, Banana Bread cannot be found, because it does not exist on the page. The element
<font>
..<a></a>Ban</font>.....<font>ana.Bread</font>
has a normalized text value of Ban.ana.Bread and you don't expect the space inside the word Banana. normalize-space removes spaces and line feeds that are invisible on the rendered page, but the two spaces in Ban.ana.Bread are both visible.
If there was no space between the two <font> elements,
.//*[starts-with(normalize-space(.),"Banana Bread")]
would detect 3 elements: the <html>, the <body> and the <p>, because "Banana Bread" are the first words in each of them. So you might better use
.//p[starts-with(normalize-space(.),"Banana Bread")]
instead.

How to click on Web check box using Excel VBA?

How do I check the table checkbox?
I tried clicking.
ie.Document.getElementsByClassName("x-grid3-hd-checker").Checked = True
<div class="x-grid3-hd-inner x-grid3-hd-checker x-grid3-hd-checker-on" unselectable="on" style="">
<a class="x-grid3-hd-btn" href="#"></a>
<div class="x-grid3-hd-checker"> </div>
<img class="x-grid3-sort-icon" src="/javascript/extjs/resources/images/default/s.gif">
</div>
I can't see a checkbox in the HTML code. But you use getElementsByClassName() in a wrong way for your case. getElementsByClassName() generates a node collection. If you need a specific node, you must get it by it's index in the node collection. First element has index 0.
Please note that the div tag with the CSS class class="x-grid3-hd-inner x-grid3-hd-checker x-grid3-hd-checker-on " is also included in the Node Collection, because a part of the class identifier is identical to "x-grid3-hd-checker ". [Edit: I'm not realy sure if the part must maybe stand at the begin of the identifier]
If you want to check this:
<div class="x-grid3-hd-checker"> </div>
Your code needs the second index of the node collection:
ie.Document.getElementsByClassName("x-grid3-hd-checker")(1).Checked = True
But if there are more tags with the class name "x-grid3-hd-checker" the above line don't work. I can't say anymore until you don't post more HTML and VBA code. The best would be a link to the site.

working with .Document.getElementById() and variables in vba

I am trying to select the value from a dropdown box using vba, the code block for the dropdown box is as follows
<input type="text" id="form_autocomplete_input-1542902425322" list="form_autocomplete_suggestions-1542902425322" placeholder="Search keyword or select filter" role="combobox" aria-expanded="false" autocomplete="off" autocorrect="off" autocapitalize="off" aria-autocomplete="list" aria-owns="form_autocomplete_suggestions-1542902425322 form_autocomplete_selection-1542902425322">
If the value of form_autocomplete_suggestions-1542902425322 was static I would use .Document.getElementById("form_autocomplete_suggestions-1542902425322").Value = "Role: Student" however this seems to be a randomly generated numerical value.
I have had a look and it seems I cannot simply add a wildcard in such as .Document.getElementById("form_autocomplete_suggestions-*").Value = "Role: Student"
And as its randomly generated and such a long number it cannot loop through an array of values. so I am unsure on how to solve this issue.
You can use css attribute equals value selector syntax with the ^ operator to say starts with a certain substring. You could also use * instead, which means contains.
[id^='form_autocomplete_input-']
VBA:
ie.document.querySelector("[id^='form_autocomplete_input-']")
You might also use:
[placeholder='Search keyword or select filter']
Which would be:
ie.document.querySelector("[placeholder='Search keyword or select filter']")
As you indicate this needs to be selected you may need:
ie.document.querySelector("[id^='form_autocomplete_input-']").Selected = True
Reference:
CSS attribute selectors

Material Design: how to disconnect float label for select?

I need to create select field without float label but I want to have placeholder and default value.
I read docs https://material.angular.io/components/form-field/overview#floating-label and tried to do it by myself.
<mat-form-field [floatLabel]="never">
<mat-select placeholder="All categories" [formControl]="catForm" multiple> //First opportunity for use placeholder
<mat-option *ngFor="let category of categories" [value]="category.name">
{{ category.name }}
</mat-option>
</mat-select>
<!-- <mat-placeholder>All categories</mat-placeholder> -->//Second opportunity for use placeholder
</mat-form-field>
And anyway I get float label. That am I doing wrong?
The correct way is that:
<mat-form-field floatLabel="never">
Square brackets for variables.
Sergei R has the correct usage for basic inputs (input type=text) but for the dropdown (select), it simply doesn't work. Even the Angular Material docs (https://material.angular.io/components/form-field/overview#floating-label) have sample code that (when augmented for this specific scenario, floatLabel="never"), indicate that it doesn't work: https://angular-vij8al.stackblitz.io
I added the fourth example of how to get the placeholder effect without the label (but you lose the ability to use more complex text).
You can remove float label even on mat-select by putting the following into your global styles.scss:
.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,
.mat-form-field-can-float .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label{
display: none !important;
}
If you want to apply this to only one mat-select, you can just specify it further in the above code.
I had given up when I saw the previous answers that said it simply can't be done, until I saw this answer for a different question about floatLabel: https://stackoverflow.com/a/66531080/14100714
Just Use this in scss:-
::ng-deep .mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,
.mat-form-field-can-float .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label{
display: none !important;
}

rich:toolTip not handling String values that contain quotes

I have ran into a particularly strange problem when implementing a RichFaces tool tip component. In my project I have a table that displays a list of Strings that are entered by the user, and I want there to be a pop-up of additional information when a user mouses over the strings in the list.
One of the requirements is that any string that is more than one word must contain double quotes "" when input by the user--e.g. a single word would be input as Java vs. a phrase "Java is cool".
So, I added a <rich:toolTip> to render additional info if it exists--and it works, except for strings that contain double-quotes. For example (as it's displayed in the table) "sample string" will not show additional information on mouseover.
My JSF code is simply:
<h:outputText id="keywordText" value="#{keywordData.keyword}"/>
<rich:toolTip for="keywordText" rendered="#{keywordData.comments != null}" value="#{keywordData.comments}"/>
Like I said, this works for words/strings that do not contain quotes. I am wondering if there is a workaround within JSF/RichFaces I can use in order to get this to work properly with a string that contains quotes. Or perhaps some assistance in writing a custom JavaScript function that forces or "tricks" RichFaces into handling quotation marks in a string correctly?
Thanks for any help in advance!
Edit: I am using RichFaces 3.3.3
In the page source, for the string "Testing Quotes" (does not work) I found this:
<span id="j_id138:j_id144:keywordTable:"Testing Quotes":keywordText">"Testing Quotes"</span>
<span id="j_id138:j_id144:keywordTable:"Testing Quotes":j_id159" class="rich-tool-tip " style="z-index:99; ">
<span id="j_id138:j_id144:keywordTable:"Testing Quotes":j_id159content">
<p>This comment should display</p>
</span>
<span id="j_id138:j_id144:keywordTable:"Testing Quotes":j_id159script" style="display:none">
<script id="scriptj_id138:j_id144:keywordTable:" quotes":j_id159"="" testing="" type="text/javascript">
new ToolTip("j_id138:j_id144:keywordTable:"Testing Quotes":j_id159","j_id138:j_id144:keywordTable:"Testing Quotes":keywordText",{'showEvent':'mouseover'} );
</script>
</span>
You can see that the quotations in the string itself (which appears to supposed to be part of the id attribute) are being misinterpreted in the new ToolTip parameters. And for a string testkeywordawesome without quotes you can see it works (because it does not contain quotes):
<span id="j_id138:j_id144:keywordTable:testkeywordawesome:keywordText">testkeywordawesome</span>
<span id="j_id138:j_id144:keywordTable:testkeywordawesome:j_id159" class="rich-tool-tip " style="z-index: 99; visibility: hidden; display: none; left: 63.7833px; top: 210.75px;">
<span id="j_id138:j_id144:keywordTable:testkeywordawesome:j_id159content">
<p>the best comment in the world</p>
</span>
<span id="j_id138:j_id144:keywordTable:testkeywordawesome:j_id159script" style="display:none">
<script id="scriptj_id138:j_id144:keywordTable:testkeywordawesome:j_id159" type="text/javascript">
new ToolTip("j_id138:j_id144:keywordTable:testkeywordawesome:j_id159","j_id138:j_id144:keywordTable:testkeywordawesome:keywordText",{'showEvent':'mouseover'} );
</script>
</span>
Edit2: The tool tips exists in a rich:column, of which exists in a rich:extendedDataTable. Below are their code:
<rich:extendedDataTable value="#{keywordEntry.globalKeywordsDataModel}"
rendered="#{fn:length(keywordEntry.globalKeywords) gt 0}"
styleClass="removeEDTSortIcon removeEDTContextMenu"
id="keywordTable" rowClasses="row1, row2"
var="keywordData" rows="0" noDataLabel=" "
headerClass="#{displayHeader == null or displayHeader ? 'rich-table-header' : 'hide'}"
rowKeyVar="keywordRowIdx" enableContextMenu="false"
sortMode="#{globalKeywordListSort.multiSortEnabled ? 'multi' : 'single'}"
sortPriority="#{globalKeywordListSort.sortOrderList}"
width="#{eStaffUser.userKeywordAdmin ? '750px' : '750px'}"
height="#{((fn:length(keywordEntry.globalKeywords)*30 + 50) lt 480) ? (fn:length(keywordEntry.globalKeywords)*30 + 50) : 480}px"
>
and
<rich:column id="#{globalKeywordSortFieldEnumBean.KEYWORD}" selfSorted="false" width="#{eStaffUser.userKeywordAdmin ? '48%' : '52%'}" sortBy="#{keywordData.keyword}"
sortOrder="#{globalKeywordListSort.dataTableColumnSortClass[globalKeywordSortFieldEnumBean.KEYWORD].sortOrder}">
id="j_id138:j_id144:keywordTable:"Testing Quotes":keywordText"
This means that one of the parents of <h:outputText id="keywordText"> has its id defined by something that evaluates to "Testing Quotes", that's obviously bad.
OK, so the root of the issue was that the rich:extendedDataTable uses an ID supplied by each entry to generate a unique ID for each table row. So the problem ended up being in the underlying "Model Managed-Bean" that implemented a generic data entity interface, this interface defines a getEntityId() method and in this case, the "ID" returned was the keyword value itself, since there was no true (i.e., database) entity ID such as a primary key:
public class KeywordDataBean implements SummaryDataEntityIF<String>
The problem was resolved by changing the interface's implementation to Integer and returning the hash as the unique ID for each keyword object:
public class KeywordDataBean implements SummaryDataEntityIF<Integer>
This forced the html id generated by the rich:extendedDataTable to be a simple integer number instead of a (keyword) string containing quotes, allowing the rich:toolTip to work properly.

Resources