Creating a clickable div dynamically with Angular 6 - javascript

I want the display the user an image, with a varying number of divs (depending on the number of faces detected) which should be clickable (a click on a face will show some attributes for that particular face).
So ideally I would like to create some divs (or buttons) around each face and have something like (click)="divClicked()" for each element.
However,(click) isn't a legit attribute, so, for example, trying something like
d3.select('button').attr('(click)','onClickMe()');
gives an error. onclick is a legit attribute, but by using it I think I should break the way Angular wants me to work (as putting the function inside the component's ts file gives the error onClickMe is not defined).
The very best workaround I could come up with is to assign an id to each div and then do something like
document.getElementById('b1').onclick=this.onClickMe;
but that feels like bad coding.
So, what's the clean way to do that?

I think you should create the div elements by adding a loop with ngFor to your template to display your divs. Of course they may be CSS-styled, based on some properties you have determined beforehand (in particular the CSS properties left and top are useful here). Of course you can add a (click)-event to those divs too.
To do this, your component should hold a list of objects to display which you may update when necessary. Furthermore it should offer a method which gets called when the user wants to see details of a particular face.
The template then only cares for turning those objects into a HTML structure and bind the callbacks.
Structurally something similar to the following will occur in your template:
<div
*ngFor="let face of faces; index as i"
(click)="showFaceDetails(i)"
[style.left.px]="face.x"
[style.top.px]="face.y"
></div>

Related

Is this a valid use case for derived state from props? [react]

React documentation seems to be very insistent on the idea that in almost every situation, deriving state from props is a bad idea, an anti-pattern, verbose, likely to cause bugs, hard to understand, and all-around probably going to place a curse on one's lineage for a thousand years.
My use case isn't that weird, so I'm probably doing something wrong, but the suggested patterns for not needing getDerivedStateFromProps() (i.e. making Your object fully controlled or fully uncontrolled) don't seem like good solutions.
The situation: I have a Table component, that takes in an array rows as a prop. Table is used in many different places in my app. I want the Table to be able to handle row-sorting. It is obviously a bad idea to to make whichever parent component controls Table to have to control the sorting*, so fully controlled is out. Making Table fully uncontrolled with a key, also seems like it doesn't make a lot of sense unless the key is the row-data itself-- but my understanding is that key is meant to be simple data (like an id), and actually having to compare all of the rows, which are typically fairly complicated objects, would be pretty inefficient**. Using memoize-one is also not an option as I am working in a closed system and can't import any new libraries.
My current solution: Table has a state variable sortedRows which is updated either whenever sort() is called or whenever props.rows is updated (via getDerivedStateFromProps), by:
Making a shallow copy of props.rows,
in-place sorting that copy and
updating state.sortedRows on that value.
As I see it, there is still only one source of truth here (which is from props), and the state is always just storing a sorted version of that truth (but always dependent on and in sync with it).
Is this solution bad? If so why? What would be a better way to implement this?
Thanks!
Note: I didn't include my code because I am massively simplifying the situation in this prompt-- in reality Table element already exists, and is pretty complicated.
Note 2: I going to ask if I'd run into issues once I want to be able to modify elements in the tables, but I think I'm actually ok, since Table doesn't manage its elements, just arrange and display them, and the buttons for adding and removing elements from a table are not contained within Table, so all that processing is happening at the level of the parent's logic as passed down as part of props.rows
*Having something like <Table rows={sort(rowsFromParent)}/>every time I call Table is repetitive and error-prone, and since clicking on a table header determines sorting column, we'd actually have to have the parent element passing down an onClick() function in every case, which quickly and unnecessarily ramps up complexity).
**There is also a secondary problem to do with rebuilding an element. The table has an infinite scroll, such that when You reach a certain element more rows are loaded in. Using key will destroy the Table component and create a new one, scrolling the user to the top of the new table (which could potentially have many thousands of rows). Something also feels wrong about having to set key in each use of Table, even though resetting based on changes to props.rows seems like it should be intrinsic to how Table works, rather than something that has to be configured each time.
Edit: I have React 15.4, which is before getDerivedStateFromProps was added and using a later version is not an option, so I guess even if I happened to find a valid use case for getDerivedStateFromProps, an alternative would be nice...

Why does the value attribute from an input[text] is different from what the browser renders?

I'm getting this strange behaviour in a very specific set of inputs on one my applications. I create some inputs and I can see them as I created them on the Elements panel (google chrome), but the way the browser renders it is different.
Note how the input is renders with comma instead of a point, but the value attribute uses a point
When I get a referente to that element using the selector API, I get this:
A direct reference to the Dom Element will return 11,00. The tag has 11.00 and jQuery returns the 11,00. I've removed all js that interacts with this element (masks, events, etc) and the issue still happens.
I've been swearing at the DOM for a day and a half, but I know this is most probably an issue with my application. What bothers me the most is that the browser does not honor what I see in the elements panel.
This is the small piece of code that creates the element, stopped right before the tag is created. Note the variables values in the right panel:
Could someone give me a hint about what could be causing this difference in between element, view and attributes? If possible, I'd like to know what/how this is happening in depth.
Thank you in advance

How should I avoid duplicate IDs when writing JS-heavy web apps?

Specifically, I have areas of my (heavily JS) web page that contain lists of HTML elements and for simplicity let's assume there are just two lists: A and B. Let's also say When I click on the first item in list A (A1) something happens to the first item in list B (B1).
I gave each element in list A a common HTML class and an ID (like <li class='listAmember' id='1'>...</li>). I set up elements in list B in a similar way (like <li class='listBmember' id='1'>). Then I attached some click handlers (using jQuery in this case) and ran into problems with duplicate IDs, even if I qualified my jQuery id-based selectors with the class name, like this
$('.listAmember#1').click(function(){});
I've realised that this is bad practice (IDs are supposed to be unique in the document!) but I'm unsure what good alternatives there are.
I don't really want to create IDs like listAmember-1 because if I have, say, a lookup-table in my JS code that is keyed on the numeric ID, I'd need to parse out the 1 from that ID string to get the 'real' ID. (And I would still need to add a class like listAmember for styling purposes and that seems unnecessarily repetitious?) All in all that seems clumsy and I assume there are better ways?
As Florent says, I would try and avoid IDs altogether. One convention is to use class names like js-list-a to signify it's a class intended for JavaScript usage only. Then you're free to start using the index of the li within the list.
Also, you could just set one click handler on the list and use event delegation .
A combination of these ideas means you won't have to touch IDs.
For Unified ID's maybe in a System that has external Libarys in use, you should always attach them with a Namespace. For Example like: "myFancySlider-container"
This helps to keep names Unique for your special application.
If you generate Dynamic Code, you have to Make sure, to only create One of each object. Or you Assemble them With iterations. An alternative to that, could be the unifying with Timestamps.
EDIT
As others already mentioned, you should avoid Using ID's as you can. ID's only make sense, to benefit from the Unique Attributes. For example, you know exactly what element you want, so an ID can be a verry good shortcut for that. Specialy in dynamic Content Applications.

is it possible to view one html element twice on the same page, or must I create a duplicate?

I am creating a site that allows viewing and editing the contents of the 'src-div' contents within the 'edit-div.' I am not editing the src-div directly, because its thumbnailed using css zoom property.
I have considered using knockout.js to bind both elements to an observable. Currently, I have implemented the feature with jquery .html() function: simply set edit-div innerhtml to src-div innerhtml on 'select', and reverse the process after changes are made to edit-div to update the src-div.
I am wondering if I really need 2 divs here, or if there is some way to actually view the same element twice on a page, and any changes made will automatically reflect in both 'views,' elimiating the need to copy innerhtml property back and forth between two elements.
essentially, this is like a mirror effect, without the flip.
the closest thing I found so far is:
http://developer.apple.com/library/safari/#documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Reflections/Reflections.html
Any recommended practices for performing this task are appreciated.
(Almost) everything you see on a page has a counterpart in the DOM. Everything in the DOM gets exactly rendered one time (apart from pseudo-classes). And every node in the DOM can only have one parent (no exclusions).
Unfortunately you'll have to clone the specific node and add changes to both, as there is no copy & translate mechanism in the current CSS documentation.
If you're using jquery you can use one div and "clone" it. You can read this for more information.
http://api.jquery.com/clone/
If you set the class of the div to the same thing, you can have changes propagated to both. Then you can apply .addClass to the second div to apply a "reflected" affect (if that's your final goal).

using hidden elements in pages to store data

I need to store data in html documents that are associated with elements, and that I can get to with javascript. I think I want to avoid arbitrary attributes on elements, since after reading various posts here I don't trust them. I can't use id or class, since I those are used for other things and I don't want to mess with them (my project has to work on wide varieties of html so I can't make any assumptions as to the design of the class and id structure). Another thing I need is for whatever I do, it needs to survive round-tripping through innerHTML (of a parent or ancestor element of the element I need to tag with data), with data intact.
I have considered various hidden elements (including script tags and html comments), which I insert into the document right before the element I need to tag with data. Currently my favorite is hidden form elements (i.e. input with type "hidden"). I can stick any data I want into the "value" of the element, and I can find all such elements easily enough with getElementsByTagName(). Also importantly, it doesn't seem to affect the layout of the page.
I'm curious about the ramifications of this, and if anyone can think of any any problems with it. I need to be able to put them anywhere in body of the page, before any element. For instance I might need them associated with an option element (a child of a select element), so that rules out using a hidden div, since putting one of those inside a select element is illegal. I don't think they will affect form behavior, since they don't have a name attribute (I can avoid using id's if that helps).
Any thoughts on this, or suggestions for other ways of accomplishing the same that meets my needs?
If this is going to be data for JavaScript's purposes, why even try to put it in the HTML at all? Here's a simple example of what I mean
<script type="text/javascript">
var nodeData = {
foo: {/* Data to associate with div#foo */}
, bar: {/* Data to associate with div#bar */}
};
</script>
<div id="foo">Foo!</div>
<div id="bar">Bar!</div>
It's simple and elegant since the principle of IDs being unique per document nicely matches with javascript's dictionaries requiring unique keys per entry.

Categories