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

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>

Related

Angular - Two Way Binding

I am a beginner at Angular and I covering two way binding but for some reason I do not understand what I am doing wrong with the below any input would be appreciated.
I am simply trying to understand the concept so the below code is rather simple. Per my understanding
Adding the two way binding [()] to <app-child-comp> I pass the parent field "name" from the parent component to the parent view and using property binding it provides an initialization value ( default value ) to the child component that receives the value in the #Input field.
Once the field "#Input childName " has its value using normal interpolation I can use the value how ever I please in the child template.
Now by defining an EventEmitter and then using its .emit method I should be able to pass any changes on the variable back up to the parent component and update the DOM property to reflect the changes.
Problem:
Now this is my problem the parent --> child direction the bindings are working as intended,
the name "Fin" is appearing as I expect in the input of the parent Template and in the interpolation in the child template but when I want to alter the name in the child template and have it bubble back up to the parent property it fails to update although it updates the interpolation in the child template.
Ive been trying to figure this out now for a while and everything im researching I feel says im doing it correctly but if you could please explain what im doing wrong I would much appreciate it.
Im adding this so that anyone looking in the future can learn from my mistake.
There are two ways to perform event binding given a child component
The first way is by explicitly declaring the property and event bindings as follows <app-child-comp [childName]="name" (childNameChange)="name =$event"></app-child-comp>
The second way is to use the "Banana Box" Method where the child tag transforms into <app-child-comp [(childName)]="name"></app-child-comp>
I was trying to use the second method and something that wasn't immediately clear is that there is a naming convention when it comes to the field names in the child component that needs to be followed in order for the "Banana Method" to work
Rule: If your #Input field is named "x" then your #Output EventEmitter needs to be named "xChange" the "Change" is required as the second part of the name .
Syntax: inputName + Change
So in order to resolve my problem I needed to change the naming convention from
#Input() childName:string;
#Output() changedName = new EventEmitter<string>();
to
#Input() childName:string;
#Output() childNameChange = new EventEmitter<string>();
You have to add the output in your root component:
<app-child-app [(childName)]="name" (changedName)="name = $event"></app-child-app>

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

Why 'ng-attr-' can't be used with attribute 'multiple'?

I'm trying to make a <select> behave with single or multiple selection depending on a condition. So far I have tried:
<select
ng-model="data.model"
ng-attr-multiple="{{myCondition ? '' : undefined}}">
(here's a plnkr I have been testing with https://plnkr.co/edit/ACKBMZSJc2MVSJaDBGMY?p=preview)
But it won't work. Even leaving ng-attr-multiple alone won't work. What am I missing here?
https://docs.angularjs.org/error/$compile/selmulti
Binding to the multiple attribute of select element is not supported
since switching between multiple and single mode changes the ngModel
object type from instance to array of instances which breaks the model
semantics.
If you need to use different types of select elements in your template
based on some variable, please use ngIf or ngSwitch directives to
select one of them to be used at runtime.

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.

Angular - Setting value in input text box in another component

I am trying to set the value in an HTML input text box which is a part of ComponentA from the typescript code which is a part of ComponentB.
Taking a clue from this SO i tried doing:
(<HTMLInputElement>document.getElementById("name")).value = response.name;
But this is not working. Is there anything else i need to take care of?
EDIT: The element with Id "name" is in ComponentA and the above code that is trying to manipulate that element is in ComponentB
If you are trying to set the value of component1's textfield from the compoenent2 then you must have to use of ngModel i.e two way data binding. by providing component2 in the providers list you are able to access all the functions and variables of that component, then you can easily set your value. like this
suppose this is your component 2's value property
name:string = 'Pardeep Jain';
than you can access this in component like this-
<input type="text" [(ngModel)]='name'>
....
constructor(private delete1: Delete){
this.name = this.delete1.name;
}
Working Example
Also
(<HTMLInputElement>document.getElementById("name")).value = response.name;
is used to set the value of current template's field with id named as **name**
This is one of the cases when user interaction on one component ComponentA triggers an update on another component ComponentB.
This article describes multiple approaches, with example code, on how to pass information between components.
My personal favorite is the third approach mentioned in that article in which one of the component (say ComponentA) "listen" for update it is concerned about from any component (say ComponentB) via a service in between them, resulting in a loosely coupled components.
For more approaches here is another link.