Unique signature for a DOM element in absense of ID? - html

DOM Elements are identified by their "id" value when it is present. But in absence of it can we write a function that generates an "id" ? If called multiple times the function need to return the same ID for the same DOMElement.

Every element has its css selector that points to it uniquely, you can add id for example by jquery:
$(*unique selector*).attr('id', 'element_id');
and afterwards to reference this element by this id.
You can also call this element by its css selector everytime - if it's unique enough, it can act like an id, but it introduces additional overhead.
For example, your question's selector is:
var el = $('#question table td.postcell div.post-text p');
You can set it's id:
el.attr('id','your_question');
Now you can reference it by this new id:
alert($('#your_question').text());
try it in your Firebug console.

Related

Angular 10 | Different ID types | How to add css style with css file

I do not really understand the difference between these three ways to declare an ID in html:
[id] = "'example'"
id = "example"
#example
The first two seem to be identical, is this correct?
These I can style in my example.component.css file.
The third one is special. I understand I can use it everywhere in the current html view, but I cannot apply CSS styles with example.component.css, is this correct?
Which one shall I use in angular? A combination of 1/2 and 3?
I also noticed if I use the same ID in different components, I will have duplicate ID's, which is really bad, so eventhough I use angular and different components I must be very careful how I name ID's, is this correct?
Version 2 is the default html syntax for an id
Version 1 is the angular way, if the id is a variable, e.g. [id]="myId"
Version 3 is the angular way to export/reference a html element to angular. This is not an id.
The id is a HTML Element (not angular), so you have to look that the id in html after building is unique.
Yes the first two have an identical end result. The second one is a string while the first one is a javascript expression and is evaluated by angular. This means you can use things like component properties such as [id]="'example-' . foo" which outputs id="example-2" if you had a property foo = 2; in your component.
The third one actually doesn't have anything to do with the ID attribute in HTML, but I understand why it may seem like it. It's actually a template reference variable and it allows you to access this element from anywhere else in your template, or even from your component code.
You're right, the html specification requires an ID to be unique, browsers are forgiving so they may permit you to use duplicate IDs but it should be avoided at all costs.
You can use id="unique_id" if you don't want to change it dynamically. If you want to change your HTML element id dynamically through Component.ts then you should use [id]="your_variable" & #example serves for different purpose described below.
id with [] brackets is angular directive to set HTML id attribute value through a variable or expression
id is a HTML attribute which sets a unique id on an element
#example if you are writing like this in Component.html you are basically creating a template reference variable which is a reference to a DOM element within a template. You can then access this using Angular #ViewChild decorator. It can also refer to a directive (which contains a component), an element, TemplateRef, or a web component.
Angular Template Reference Variable
[id] = "'example'" => This one set assign example as id and it is same as id = "example".
Suppose if we want to assign a variable value then use [id] = "example".For this in ts file you have to declare the example variable
Public example ="your-class-name";
So id value will be your-class-name
#example => These are templare refference variable.
A template reference variable is often a reference to a DOM element within a template.
For example,
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>

Get A Google Doc Element By ID with Google App Script

Question:
I am trying to avoid looping through the document until I find the tag and then grabbing the parent. Does anyone know if there is a way to find a google doc element by an id or handle?
Context:
I have a script that opens a defined template doc; copies it into a new document element by element, and then replaces any mustache tags with the values from a passed in object using the replaceText function. This part works fine, but there is one section where I would like to repeat a table row based on the object value being an array. Unfortunately I can not seem to figure out how to locate the table in the template doc other than something like:
if('{{ some tag }}' in aElement){
var repeatableElement = aElement.getParent();
if(repeatableElement){
goRunRepeatFunction();
}
}
Just seems like there should be a way to jump directly to an element by id.
Your task can be accomplished by using this snippet:
function getElement() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var numOfElements = body.getNumChildren();
var element = body.getChild(INDEX_OF_THE_CHILD).asText();
console.log(element.getText());
}
This gathers the body of the document and retrieves the number of children it has. This number represents the elements the document has. So, in order to access a certain element, you just have to make use of the getChild(index) method
Note
Please bear in mind that the getNumChildren() method will end up returning the number of all the elements in the document, including empty lines - these will be considered elements as well.
Usually, when working with a document in Apps Script, the elements are retrieved by their types in order to preserve them. So for example, if you have images in your document, it'd be best to retrieve those by using the getImages() and this will end up returning a list of containing all the images in the document, with each image being accessible by their index.
Another method would be to retrieve all the paragraphs in the body by using the getParagraphs() method, but if you know the exact structure of your document, you can retrieve all the elements by their type, and then access them as such.
Reference
Class ContainerElement - getNumChildren();
Class ContainerElement - getChild(Integer);
Class Body - getParagraphs().

VBA - IE Nest selection item with ID

Trying to select the Export button below which has an ID and name. I know I can getelementbyID but not sure how to then specify to further drill into the getattribute("name") because the getelementbyID wil only return 1 value, not an array
Thanks!
#Mturks83
getElementsByName("export")(0) the first part will give you the array of elements called export the (0) gives you the first.
It is faster to use querySelector than getElementsBy.
For example, just got direct with an attribute = value selector
ie.document.querySelector("[name=export]")
If more than one then add the parent td element id
ie.document.querySelector("#bottomButtonRow [name=export]")
Reading:
css selectors

How to capture a nested HTML element?

I am trying to capture a HTML element, for the purpose of sending the value into GA as an event. I am using GTM, and want to use a click trigger to push this HTML value into a variable.
For example, the tags are set up like this:
<div class ="xxxyyyyzzzz" value1="qwejsdkfj" value3="akhdfjksh">
<div class ="fjk" >
<h1> "xyz2"</h1>
with each level nested under the other. The value we want to capture for GTM purposes is the one that sits under h1 ("xyz2"). Is this possible?
You need to select the value in JS and transmit it to GA via event (or the initial pageview, if you want to hold the number of requests low).
Method without GTM:
Select the value of your HTML tag via selector
// select the value via CSS selector, catch the first result of your query
var selector = document.querySelectorAll(".fjk h1")[0];
// select your category, action and label (I set label with the value of your selector
if(selector) ga('send', 'event', [eventCategory], [eventAction], selector, [eventValue], [fieldsObject]);
Method within GTM:
Create a variable which holds the information of your HTML tag. Use "CSS Selector" in variable definition and use the CSS selector I mentioned above.
Use the variable within your Universal Analytics Tag definition. You can set the value of a custom dimension index with the value of your defined variable.

How to find the index of HTML child tag in Selenium WebDriver?

I am trying to find a way to return the index of a HTML child tag based on its xpath.
For instance, on the right rail of a page, I have three elements:
//*[#id="ctl00_ctl50_g_3B684B74_3A19_4750_AA2A_FB3D56462880"]/div[1]/h4
//*[#id="ctl00_ctl50_g_3B684B74_3A19_4750_AA2A_FB3D56462880"]/div[2]/h4
//*[#id="ctl00_ctl50_g_3B684B74_3A19_4750_AA2A_FB3D56462880"]/div[3]/h4
Assume that I've found the first element, and I want to return the number inside the tag div, which is 1. How can I do it?
I referred to this previous post (How to count HTML child tag in Selenium WebDriver using Java) but still cannot figure it out.
You can get the number using regex:
var regExp = /div\[([^)]+)\]/;
var matches = regExp.exec("//[#id=\"ctl00_ctl50_g_3B684B74_3A19_4750_AA2A_FB3D56462880\"]/div[2]/h4");
console.log(matches[1]); \\ returns 2
You can select preceeding sibling in xpath to get all the reports before your current one like this:
//h4[contains(text(),'hello1')]/preceding-sibling::h4
Now you only have to count how many you found plus the current and you have your index.
Another option would be to select all the reports at once and loop over them checking for their content. They always come in the same order they are in the dom.
for java it could look like this:
List<WebElement> reports = driver.findElements(By.xpath("//*[#id='ctl00_ctl50_g_3B684B74_3A19_4750_AA2A_FB3D56462880']/div/h4")
for(WebElement element : reports){
if(element.getText().contains("report1"){
return reports.indexOf(element) + 1;
}
}
Otherwise you will have to parse the xpath by yourself to extract the value (see LG3527118's answer for this).