What does a `#` attribute do in HTML? - javascript

I am writing a handler to do something to some element when a user clicks on a different element.
At first I had the following (This is using Angular2 but I suspect the only different is how the onclick event is handled):
<span>
<input type="text" id="bioName">
</span>
<span class="icon-pencil" (click)="editField(bioName);"></span>
...but this didn't work. I then found an example that identified the input field differently, and this did work for me. It was as follows:
<span>
<input type="text" #bioName>
</span>
<span class="icon-pencil" (click)="editField(bioName);"></span>
Unfortunately I can't find anything that explains this. Searching for "hash" and "pound" with HTML and Javascript yield too many results that have nothing to do with this in the subject area.
So what does # do in this case? Can id not be used to obtain a reference to the DOM element when setting up an event handler? What is this called so I can google it and read the appropriate documentation?

This is Angular2 specific, regular HTML doesn't recognize this syntax, i.e. you have to use id="bioName" in order to access the tag with CSS/JavaScript.
Here is more information on how to use # in Angular2.

Hash (#) is syntax for defining template variable in Angular 2 templates. It is used to assign unique identifiers to template elements which you can later use to get a reference to template elements in component. In your case, for example, you can use bioName variable to get a reference to input element in your component and you can do whatever you want with it there - get file name, file size or even file itself. This is done using ViewChild decorator. You can check out answer I wrote few days ago and see what template variables are mostly used for.

Related

Simplest way to access the value of text input field in html form JavaScript?

I want to access input field value as simple as possible from JavaScript.
<form name="F">
<input name="searchTxt" type="text" id="searchTxt">
</form>
I can access the value with following method (tested on Firefox debugger):
document.F.searchTxt.value
But I found this method is a dialect from Internet Explorer (and works on most browsers for compatibility), and it is obsoleted on W3C DOM.
(reference: Using the W3C DOM - Archive of obsolete content | MDN )
Another way I found is using forms and elements attributes with its child's name:
document.forms.F.elements.searchTxt.value
I like this method and I feel it is simple because it doesn't require any parentheses or quotes but only dots in the statement.
(reference: Obtaining References to Forms and Form Elements in JavaScript - Dynamic Web Coding )
I think the secret of this method is the form has its name (instead of or additional to id), so it can be accessed by its simple name.
Please tell me more simple, more stable or the best method to access the field values.
You can use document.querySelector to access the form's DOM element and it has all the properties that you need:
const form = document.querySelector('form');
console.log(form.elements.searchTxt.value);
let searchTxt= document.forms["F"]["searchTxt"].value;

Automatic click element after all data loaded in Angular 2

I am trying to figure out how to automatic trigger a click event on certain element after all data are loaded.
the code is like this in html file:
<div *ngFor="let location of locations; let i = index;" class="location-wrapper" (click)="onSelect($event, i); $event.stopPropagation();">
<div class="location">{{ location }}</div>
</div>
the onSelect() method is doing some expansion of something that related to current location.
What I am trying to achieve is that I want the very first element of the *ngFor can be automatically clicked to show the things that related to it every time I get to this page.
Or maybe we can achieve it using other similar approach?
I have tried several ways to do this,
like putting some code in window.on('load', function() { // blablabla });
or using ngAfterViewInit() and ngAfterViewChecked(), both not work well.
You can do this in at least 2 ways. The first one would be old-fashioned javascript click(). The second would be just using component logic, just create an variable like selectedLocation which would hold current index or Object that is currently expanded. Don't forget to add initial value to it to make it after load page visible.
Javascript dispatchEvent (not Angular friendly solution)
Simply we just need to grab our item and use click() function. That's it. To grab an element we can use basic javascript method document.getElementById(elementId)" or with template variable.
<div
[id]="'location_' + i" <!-- For biding with document.getElementById -->
#locationPanel <!-- For biding with template variable -->
*ngFor="let location of locations; let i = index;" class="location-wrapper" (click)="onSelect($event, i); $event.stopPropagation();">
<div class="location">{{ location }}</div>
</div>
With Id it would look like document.getElementById("location_0").click() this gonna dispatch click event on element.
For template variable in your component you need to add
#ViewChildren locationPanel: QueryList<any>;
openFirstLocation() {
if (this.locationPanel && this.locationPanel.first)
this.locationPanel.first.nativeElement.click();
}
And in afterViewInit just call this.openFirstLocation();
Please note that it's not Angular friendly because Angular does not like when you interfere directly with DOM. However as long we don't change anything in structures then everything should be fine, but we should avoid manipulating dom with plain javascript.
Please note that too about using #ViewChild and document.* methods.
Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by Angular instead. Alternatively you can take a look at Renderer2 which provides API that can safely be used even when direct access to native elements is not supported.
Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.
From Angular docs link

Using auto generated (ie random) IDs in HTML forms

I'm creating a form from various complex controls that I have built as Backbone views. Understandably I want to reliably link the labels to the <input> elements, which I am doing with the normal for attribute.
However, sometimes I need to use the same control multiple times. I am using data attributes to drive the form, so I do not need the id attribute for my own use, and can use classes to identify each control.
Therefore, I am considering whether it makes sense to generate random ids, just to link the <label> and <input> together? This seems a really bad idea, but I am unsure there is a better one?
I can't just put the <input> inside the <label>, as they have to be separate from each other.
There's nothing bad in auto-generating IDs. If they have not to be human- (== developer) readable, you can go crazy there. Create a simple function, that spits out unique strings, and there you go:
function generateId() {
return 'GENERATED_ID_' + (++generateId.counter);
}
generateId.counter = 0;
id = generateId();
html = '<label for="'+id+'">Foo</label> <input id="'+id+'">';
Nothing bad happening here.
(Of course, if you could nest the input in the label, that would be a wee bit nicer.)
I would use the cid attribute of the Backbone view. This is already unique. Probably then override _.template in a base view to always include this (to save passing in each time).

Functionality of Javascript functions and jquery selectors from within html

I have this javascript function:
function clearDiv(div_id) {
alert(div_id);
$(div_id).empty();
}
And the following html:
<input value="Clear" type="button" onClick="clearDiv(div_to_clear)" />
<div id="div_to_clear">
<!-- more html -->
</div>
Why is it that the above will actually find the javascript div object with id div_to_clear and use the $ selector to access it?
If I had done the input as :
<input value="Clear" type="button" onClick="clearDiv('div_to_clear')" />
I would need to change my function to
function clearDiv(div_id) {
alert(div_id);
$('#' + div_id).empty();
}
Is there any documentation about this? Are there advantages to using one method or the other?
IE (and Chrome in an effort for compatability) will create properties on the window with names of elements with ids, corresponding to those elements.
In the first example are are passing window.div_to_clear which points to your element directly. In the second, you are passing a string telling jQuery which element to select.
The first one is non-standard behavior so you should not rely on it.
The first one is actually a browser bug (they called it a feature) to access the DOM node by window.div_to_clear (the global variable) - and jQuery creates its wrapper around the element. For legacy reasons, it still exists in current browsers, but is deprecated. Your really should use the selector solution.
This is because there is a widely-implemented (although not best practice) method by browsers to automatically place html elements with id's into their correlating variable name. For example:
<div id="someId"></div>
will end up psuedo creating the variable someId which holds that html element.
These questions have similar information on the behavior:
Do DOM tree elements with ids become global variables?
Where does the variable holding an element with an id get stored?
Element accessible with ID
Here is a jsperformance test showing that accessing the id in that manner is slower than using document.getElementById: http://jsperf.com/global-id-vs-document-getelementbyid

How to name a Javascript Function specific to id of a div encapsulating it in ASP.NET MVC

I have a partial View, which I am trying to load twice onto a cshtml file.
Now inside my partial View I have a javascript function as well. At this point, when I load my
cshtml onto the page, I will have two Javascript functions with same name.
I want to avoid this kind of scenario and name the Javascript function uniquely depending upon the Model which I am binding the Partial View to.
Please Not I could achieve the uniqueness for each control inside my partial by associating it with a parameter like "#Model.Id". But I am unable to apply the same kind of thing for uniqueness of Javascript function.
I am sorry for my Bad English. Kindly let me know if you need additional details.
Instead of having many functions with different names for each partial you could have a single javascript function which operates on each control. So for example you could assign a class to those controls and then write your function under the form of a jQuery plugin attached to all controls with this classname.
Now the function could be declared inside a separate javascript file without mixing markup and javascript in a partial which is a bad design. The plugin could then be simply attached to all controls with this class with a standard jQuery syntax:
$(function() {
$('.someClass').myFunction();
});
You could also use the HTML5 data-* attributes on your DOM elements to associate some metadata with them such as an unique identifier coming from your model. This metadata will then be accessible in your jQuery plugin.
For example:
<div class="someClass" data-id="#Model.Id">
This is some div with associated metadata
</div>
In order to achieve scenario like that you can use data-attribute.
For example we have identical html code surrounded by a div, those div's had different id.
Each div will have a data-attribute and with jquery you can catch an event (Like Click)
Now Code Example
HTML
<div id="id1" data-attribute="doSomething">Element</div>
<div id="id2" data-attribute="doSomething">Element</div>
In your case those div represent the results coming from the partial view
also you can change the value store in the id attribute to come from your model something like id="id#{Model.Id}"
JQuery
$("div[data-attribute=doSomething]").click(function() {
alert("Clicked element: " + $(this).prop("id"));
});
Fiddel Example
I am using attribute selector of Jquery to achieve it
Note That you can achieve it also by defining a class attribute.
But I think you should use this when you actually need a class otherwise use custom attribute like data-value="something"

Categories

Resources