Dynamically adding onscroll function - html

I have a set of tabbed tables. tabs are added during runtime, and each tab has 4 tables with data associated with the tab.
I also have a requirement that each table scrolls data but the header remains visible and consistent with the scroll.
I have seen examples of this and implemented it just fine, well for the first tab.
Since the ids need to be unique, I use the Angular Js ng-attr-id to generate unique ids.
My problem now is how to reference the unique ids when creating the onscroll function.
With a single tab, I can use this code:
<table id="Orders" onscroll="$('#Orders > *').width($('#Orders').width() + $('#Orders').scrollLeft());">
This works absolutely fantastic, now using Angular's ng-attr-d, I don't know how to set the function since it needs to be dynamically created using the dynamic id:
<table ng-attr-id="Orders{{GroupDetails.length}}" onscroll="$('#Orders{{GroupDetails.length}} > *').width($('#Orders{{GroupDetails.length}}').width() + $('#Orders{{GroupDetails.length}}').scrollLeft());">
This above does not work. Inspection shows that the {{}} parts are rendered as string.
Is there an Angular JS way to 'inject' event functions?

Issue with syntax, you can add a variable to string and assign it to ng-attr-id.
Try this:
<div ng-attr-id="{{ 'orders-' + GroupDetails.length }}"></div>

Related

How to add a specific metadata using jquery into a div with an ID

I am trying to figure out how to write jQuery code to insert meta data in to an element, specifically this: data-section-name="home"
I want to insert this in a div with an ID of home-section and the output would be like this:
<div id="home-section" data-section-name="home">
(some code here...)
</div>
I am using a divi builder in Wordpress
If you need the data attribute to appear in the HTML source use attr():
$('#home-section').attr('data-section-name', 'home');
If the data attribute is going to be read by a jQuery library then you can use the data() method instead, which is more performant:
$('#home-section').data('section-name', 'home');
The caveat in both cases is to ensure that you execute this line of code before whatever library depends on that data attribute being present.

In an Angular page containing custom components, how should I make sure all IDs are unique to get rid of the warnings?

I have a custom component for text input and each of them has an internal field ID'ed as data. It causes the warning below to appear.
[DOM] Found 13 elements with non-unique id #data
I'm clear on why it happens and I understand that's a warning not an actual error. I also recognize the appropriateness of an ID being unique (in its scope).
I'm not entirely sure regarding the implications in my particular case. In my opinion, warnings are tolerable but not acceptable.
Is there a best-practice approach to get rid of the error? By the very concept of a GP component, some parts will be alike in each instance. Or is there a trick to unique'fy the IDs? Or perhaps a directive or such to let Angular know we're cool with the state as is?
The component uses #ViewChild("data") to refer the input control in the template below.
<div id="outer">
...
<label for="data">{{label}}</label>
<input #data id="data" ... >
<div *ngFor="let error of errors" class="row"> ... </div>
</div>
As far as I understand the purpose of using ids is querying it inside of Angular. You could use a directive or another attribute to query without any warnings. Also you could make a kind of wrapper which would apply common ID to input and its label and just concat UUID and ID you want to use. But if it's only about querying just choose another attribute. For example data-id or data-qa whatever gives you an ability to query and have no errors at the same time. Just in case #ViewChild("data") refers to #data and not id="data" whilst you may wrap input with label tag.

Angular2 function call from html element with no load event (or similiar)

I am new to Angular and have run into a problem that seems to have a javascript work around but they aren't very elegant.
I have a model with an array property. I ngfor the list property to build some html selection options. This is all working nicely. The problem comes when I am trying to set default value...the html elements don't have a load event.
I tried numerous html elements and they don't appear to have a load event either but I certainly could be doing it wrong.
I have seen a solution to put javascript tag right after the html and I could do that but I was really looking for a more elegant way in Angular.
I saw this SO post and thought that was my answer but there is a warning given that I agree with and thus it doesn't appear to be a good solution.
Regardless I tried it just to see if it would work and I got:
Failed to execute 'setAttribute' on 'Element': '{{loadDefaults()}}' is not a valid attribute name
<span {{loadDefaults()}} ></span>
So how can I fire an AS2 function in the component to load the default values?
HTML (btw this is NOT a full page load so there is no body tag):
<tr>
<td *ngFor="let loc of locOptions;">
<span>{{loc.text}}</span>
<input type="radio" name="radiogroup" [value]="loc.value" (change)="onSelectionChange(loc.value)">
</td>
</tr>
Edit
I thought perhaps mistakenly that ngoninit would fire too soon...before the html elements are rendered.
So perhaps what is being suggested is that I add a boolean is default to the model and bind THAT as the element is rendered.
In your ngonit function set this.locOptions to your default values. The value can be changed later on in any function and the change will be reflected in the view. Hope this helps you.
You should use ngOnInit to init you data, and call retrieve your data from your component :
defaults : any;
ngOnInit {
this.defaults = loadDefaults();
}
loadDefaults() {
//get data
}
HTML :
<span>{{defaults}}</span>

Dynamically re-bind html.ValidationMessageFor html helper?

Some background information, I am using ASP.NET with the MVC framework and html helpers.
I currently have a dynamic table where each row has a series of input boxes. Each of these input boxes has a validation message. This works completely fine for the first row. However, when other rows are dynamically added (with the IDs' being changed along with other attributes to match the row number) the validation message no longer works.
Both the row and validation message span are being replicated properly.
In JQuery, this is usually just a problem with the binding, so for each row I would simply re-bind the IDs'. However I am not really to sure how to approach them in ASP.NET.
Any assistance would be appreciated.
Thanks
Alright, I have finally figured this out.
In MVC, in order to handle the validation, it import a JQuery file known as jquery.validate.unobtrusive.js.
However, similar to JQuery, this only occurs at the very beginning when the page is loaded. So, when you add a new dynamic element, you need to remove the bindings and the re-bind them again.
Basically, in your function for adding a new element, put the following lines of code AFTER you have added the new element:
$("#form").removeData("validator");
$("#form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("#form");
For example:
function addInfoDynamic()
{
document.getElementById("#myDiv").innerHTML += "New Content";
$("#form").removeData("validator");
$("#form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("#form");
}

storing additional data on a html page

I want to store some additional data on an html page and on demand by the client use this data to show different things using JS. how should i store this data? in Invisible divs, or something else?
is there some standard way?
I'd argue that if you're using JS to display it, you should store it in some sort of JS data structure (depending on what you want to do). If you just want to swap one element for another though, invisible [insert type of element here] can work well too.
I don't think there is a standard way; I would store them in JavaScript source code.
One of:
Hidden input fields (if you want to submit it back to the server); or
Hidden elements on the page (hidden by CSS).
Each has applications.
If you use (1) to, say, identify something about the form submission you should never rely on it on the server (like anything that comes from the client). (2) is most useful for things like "rich" tool tips, dialog boxes and other content that isn't normally visible on the page. Usually the content is either made visible or cloned as appropriate, possibly being modified in the process.
If I need to put some information in the html that will be used by the javascript then I use
<input id="someuniqueid" type="hidden" value="..." />
Invisible divs is generally the way to go. If you know what needs to be shown first, you can improve user experience by only loading that initially, then using an AJAX call to load the remaining elements on the page.
You need to store any sort of data to be structured as HTML in an HTML structure. I would say to properly build out the data or content you intend to display as proper HTML showing on the page. Ensure that everything is complete, semantic, and accessible. Then ensure that the CSS presents the data properly. When you are finished add an inline style of "display:none;" to the top container you wish to have dynamically appear. That inline style can be read by text readers so they will not read it until the display style proper upon the element changes.
Then use JavaScript to change the style of the container when you are ready:
var blockit = function () {
var container = document.getElementById("containerid");
container.style.display = "block";
};
For small amounts of additional data you can use HTML5 "data-*" attribute
<div id="mydiv" data-rowindex="45">
then access theese fields with jQuery data methods
$("#mydiv").data("rowindex")
or select item by attribute value
$('div[data-rowindex="45"]')
attach additional data to element
$( "body" ).data( "bar", { myType: "test", count: 40 } );