React/HTML Best practices for table element vs divs - html

Bill Component
This would be my item component which gets instantiated through my bill component
export default function Item (props) {
return (
<div className="item">
<span>{props.itemName}</span>
<span>$ {(props.price * props.quantity).toFixed(2)}</span>
<button className='qtyminus' field='quantity'
onClick={() => {props.decrementFunction(props.itemName, props.price)}}
><span>-</span>
</button>
<button className='qtyplus' field='quantity'
onClick={() => {props.incrementFunction(props.itemName, props.price)}}
><span>+</span></button>
<button className='deleteItem'
onClick={()=> {props.deleteItemFunction(props.itemName, props.price)}}
><span>x</span>
</button>
{/* <div>{props.quantity}</div> */}
</div>
)
}
and here's basically the category bar above the bill container div which
lists the categories of each item
<div className="bill-category">
<div>Item</div>
<div>Price</div>
<div>Quantity</div>
</div>
As I'm working through finishing this component, I'm having quite some trouble adjusting the CSS category alignments with the item names, price and buttons that come along with it. Would it be better practice to completely refactor my code to use table/rows/cols tags in this case? Please let me know your opinions.

Write semantic markup
Apply CSS to make it look the way you want
You appear to have tabular data. Use a table.

From a personal experience, you may gain some performance if you use DIV instead of TABLE in case you have really huge data and you want to dynamically add or remove columns.
But in long term I still prefer table since it is more semantically correct, easily accessible out of the box and leads to less issues if printed or exported.
If you look at the rendering of the big component vendors who provide datatable/grids you would see some are using tables and some divs, both approaches scale and are usable in big projects so it would be hard to tell what is best or if it really matter for a simple pages.

Related

Dynamically create another row of images using Aurelia

I am creating a mobile application using HTML, Cordova, Aurelia, and Bootstrap. The application has the ability to upload images and create a row of thumbnails. Being that this is a first time using Aurelia for me, the challenge is that I need a row to consist of only 4 images. I need to have the application create a new row of images after the current row reaches it's fourth image. I searched the web for solutions but didn't really find anything to suit my needs other than I might need to incorporate a value converter somehow. Does anyone know how I would go about accomplishing this task? Any assistance would be greatly appreciated. I have included my original code below, which is pretty much the code I had before knowing that I would have to dynamically create additional rows.
<div class="row">
<div class="col-sm-3" repeat.for="image of images">
<div class="thumbnail">
<img src.bind="image | blobToUrl" />
<div class="caption text-center">
<button type="button" class="btn btn-default" click.trigger="setCoverPhoto($index)" data-toggle="tooltip" title="Use as cover">Set Cover</button>
<button type="button" class="btn btn-default" click.trigger="removeAttachment($index)" data-toggle="tooltip" title="Remove photo">Remove</button>
</div>
</div>
</div>
</div>
Thanks for your help!!!!!
Ashley's answer is correct in this scenario.
Sometimes however it may be necessary to render a list with a wrapping element that contains x amount of items from this list.
You can solve this by grouping the list and iterating twice. Once on the grouped list and inside this loop another loop on the children lists.
You shouldn't pollute your VM with this grouped list if it's for UI purposes only, so it belongs in a converter. Example : https://gist.run/?id=9d624d96d86c7e0ad1c0919fd5fb8819
I put your code in a gist here: https://gist.run/?id=fb3631fe09d44395fd352c29e145c4a0
It looks fine to me as is.
Bootstrap is responsive, so you can't "lock" to 4 images per row, per se. It will go to one image per row below a certain screen width.
You can play with the dimensions in the images array in app.js to see how bootstrap will handle different things.

Insert large amounts of Elements to DOM with Polymer Data-Binding in Dart causes lags

To be honest, I am just waiting for Günter to answer my question (lol) ^_^
Anyhow, I am writing on a project which starts with a pretty huge list of items (1500+). Some of them are used for a selection mask inside DropDowns and about 800 of them are displayed in a grid.
I tried to do the best I can to keep everything fast and smooth but loading the website takes about 20-30 seconds which is a little bit too long.
To address this issue I wanted to make use of <core-list> which allows me to render only about 8 items per DropDown instead of all of them. This would reduce the amount of items rendered for DropDowns from 700 to 32. However, I HAVE to use some observables in the DropDowns and since there is a bug accessing those I cannot make use of <core-list>.
My HTML Code for DropDowns:
<div relative flex>
<paper-input-decorator label="Committee" on-click="{{openDropdown}}" dropdown="{{committeeDropdownId}}">
<input is="core-input" value="{{committee}}">
</paper-input-decorator>
<paper-shadow absolute z="2" class="dropdown" hidden?="{{!openedState[committeeDropdownId] || committees.length < 2}}" style="width: 100%">
<div id="{{committeeDropdownId}}" style="width: 100%">
<template repeat="{{item in committees}}">
<paper-item
hidden?="{{!activeCommittees[item['v']] || !containsText(item['k'], committee)}}"
on-click="{{onItemSelected}}"
value="{{item['v']}}">{{item['k']}}</paper-item>
</template>
</div>
</paper-shadow>
</div>
As you can see, I have to access containsText(..) as well as activeCommittees inside the template which would be the template I have to use for <core-list>. With that in mind I added containsText(..) to my item class which I would use for <core-list> and added observable getters for committee and activeCommittees. Since these getters have to access the 'original' variables I declared these variables static and pretty much everything was dirty and ugly and didn't really work any longer.
First Question: So the first part of my question is, can I tweak the performance of the creation of my DropDowns WITHOUT <core-list>?
But there is more. There is a grid containing about 800 little 20x20 pixel cells. Constructing this also takes a while.
The grid HTML code looks like this:
<div vertical layout>
<template repeat="{{row in rows}}">
<div row horizontal layout>
<template repeat="{{col in row.items}}">
<template if="{{!col.dummy}}" bind="{{col.delegate as item}}">
<core-tooltip disabled?="{{!activeMEPs[item['v']]}}">
<div mep="{{item['v']}}" class="grid-item item"
low?="{{mepFactors[item['v']][0] <= 0.1}}"
style="opacity: {{mepFactors[item['v']][0]}}; background: {{color(item['v'], activeMEPs[item['v']])}};">
</div>
<div tip>
<!-- Name in Tooltip -->
<h4 style="margin: 0em 0 0.1em;">{{Database[item['v']]['k']}}</h4>
</div>
</core-tooltip>
</template>
<template if="{{col.dummy}}">
<div class="grid-item dummy"></div>
</template>
</template>
</div>
</template>
</div>
This may look more complicated than it is, but I create N rows mit M columns and fill the remaining columns with empty dummy container.
Second Question: So here comes the second part of my question, how can I increase the performance of creating my grid?
It's all about performance, right? Thanks for reading the longest post I ever made!
What core-list does to improve performance, is to only render to the DOM what is visible to the user. Everything outside the current view is only rendered when it is scrolled into view. This is usually not trivial work.
Currently development of core-/paper-elements seems a bit stale because of the transition to Polymer 0.8. I doesn't make sense to put too much effort in the 0.5 versions of the elements when a lot of work has to be redone when 0.8 is in a state that more advanced elements can be ported.
Instead of core-list you could try bwu_datagrid which also has a lot of such optimizations. BWU Datagrid also doesn't use Polymer data binding which is known to be not the fastest possible way to show data on the page. BWU Datagrid also has some issues. For example, it doesn't work well on other browsers than Chrome yet, because I also don't want to put too much effort into it before 0.8 is ready.
If you don't plan to release your application within the next weeks it might make sense to pub such performance optimizations on hold until you get them for free but it is possible that it takes some months until it becomes available.

Repeated content (sub-template) in AngularJS

I have a template which contains (in part) exactly the same content repeated two or three times with minor changes to the bindings, eg:
<div class="xyz-state0" data-ng-hide="data.error || !data.states[0].name">
<div class="xyz-content">
<img data-ng-src="{{data.states[0].image}}" width="48" height="48">
<span>{{data.states[0].name}}</span>
</div>
</div>
<div class="xyz-state1" data-ng-hide="data.error || !data.states[1].name">
<div class="xyz-content">
<img data-ng-src="{{data.states[1].image}}" width="48" height="48">
<span>{{data.states[1].name}}</span>
</div>
</div>
How do I write this to avoid duplicating this HTML? This is specific to its parent view (it won't be used anywhere else) so creating a full-blown widget seems wrong.
Basically I want something similar to ngRepeat, but I can't use that for the following reasons:
I need a specific (and different) style on each parent div.
I need to render a specific number of divs (2 in this case, 3 in another) regardless of whether or not they exist in the scope (ie. data.states could only have 1 element in it, but it still needs to create both divs).
In the other case the items need to be rendered out of order (first 1, then 0, then 2).
I've managed to get a template fragment in a separate HTML file and included it with ngInclude, but I don't know how to get a single name in its new scope to refer to a specific item. My first attempt was this, which doesn't work:
<div class="xyz-state0" data-ng-include="'state.tpl.html'" data-ng-init="state=data.state[0]"></div>
<div class="xyz-state1" data-ng-include="'state.tpl.html'" data-ng-init="state=data.state[1]"></div>
I suspect I could probably do it with a custom controller, but that seems like a heavy solution too. What's the Right Way™?
This is pretty much a textbook case for a custom directive. Define a directive, and then you can do
<state ng-repeat="item in data.states" item="item">.
Alternatively, if a custom directive is too much overkill (depends on whether you'll be reusing that view component elsewhere, mainly), you could just put an ng-repeat on the entire div. The only real issue is the class="xyz-stateN" stuff, but I bet you could hoke that up with ng-class usage.
EDIT:
if you do an ng-repeat, you can just use the $index key (as long as you're always counting up from zero and the state class is the same as the index). Something like
<div ng-class="{{'xyz-state'+$index}}" ng-repeat="state in data.states" data-ng-hide="data.error || !state.name">
<div class="xyz-content">
<img data-ng-src="{{state.image}}" width="48" height="48">
<span>{{state.name}}</span>
</div>
</div>
Would probably work fine. All that said, it's almost always worth making a directive in my opinion. Code gets recycled all the time, plus you can be cautious with namespacing and modularizing if that makes you nervous.
Well, this seems to do the trick (thanks to pfooti for the hint). I'm still not entirely happy with it as the directive is registered globally, whereas I really only want it in this one place.
state.tpl.html:
<div class="xyz-content" data-ng-show="state.name">
<img data-ng-src="{{state.image}}" width="48" height="48" />
<span>{{state.name}}</span>
</div>
view.tpl.html:
<div data-xyz-state="data.states[0]" class="xyz-state0"
data-ng-hide="data.error"></div>
<div data-xyz-state="data.states[1]" class="xyz-state1"
data-ng-hide="data.error"></div>
app.js:
app.directive('xyzState', [function() {
return {
templateUrl: 'state.tpl.html',
scope: {
state: '=xyzState',
},
};
}]);
Interestingly it doesn't work if I try to declare the introducing element as <xyz-state ...> instead of <div data-xyz-state="" ...>, despite the docs saying that this ought to work too. I assume there's some sort of validation thing interfering here.
Just as an FYI, I later revisited this code and decided to do it like this instead: (I'm letting my original answer stand as that is more like what I was originally asking for, and they both seem reasonable in different cases.)
view.tpl.html
<div data-ng-repeat="state in data.states" data-ng-if="!data.error"
data-ng-class="state.class">
<div class="xyz-content" data-ng-show="state.name">
<img data-ng-src="{{state.image}}" width="48" height="48" />
<span>{{state.name}}</span>
</div>
</div>
app.js
...
while ($scope.data.states.length < 2)
$scope.data.states.push({});
$scope.data.states[0].class = 'xyz-state1';
$scope.data.states[1].class = 'xyz-state2';
...
I've done something similar for the other (3-item) case, except there as I wanted to rearrange the order of the items I added an order property for the desired order in the controller and then used data-ng-repeat="button in data.buttons|orderBy:'order'" in the view.
This does mean that a bit of view definitions (display order and CSS classes) have leaked into the controller, but I think the benefit to code clarity outweighs that.

Flex 4 - Reduce amount of nested containers to improve performance

A very well known fact to improve the performance of a Flex app is to reduce the amount of nested containers, yet doing so seems particularly hard for me to do.
I'm developing a mobile app and resizing some of my components at runtime is quite slow (I can switch components to fullscreen and back again), we're speaking of 500-1000ms, which isn't really nice. Less complex components resize instantly with no noticeable lag, which is what I'd like for all components.
Let's assume the following component (simplified of course and some groups are components by themselves, but the nesting level is quite accurate);
<VGroup "the component's base">
// I guess this is fine
<HGroup "the component's title bar">
<SkinnableContainer "title bar skin">
<title bar components, labels etc. />
</SkinnableContainer>
</HGroup>
<HGroup "options bar that has switchable components">
<button />
<array "holds 'views' for the options bar that can be switched">
<HGroup "one option view">
<option view contents, labels etc. />
</HGroup>
<HGroup "another option view">
<option view contents, labels etc. />
</HGroup>
</array>
<button />
</HGroup>
That's it for the basic component layout. I'm not sure if the options bar can be optimised, the two buttons are used to switch the content which itself is placed between the buttons, hence the upper HGroup. The components inside the array need to be aligned horizontally as well, hence the child HGroups. That's already down to nesting level 3 in this component, which by itself is already a level 3 container (due to my navigation).
To the component's content area;
<Group "this is the content area">
// this group needs two different layouts (vertical and horizontal) that
// are switched based upon the user's choice of having the component maximised
// or minimised
<layouts />
// this list changes it's size based on the selected layout
<List />
this group also changes it's size based on the layout
<VGroup>
<scroller>
// the group here holds a large label that needs to be scrollable
<group>
</scroller>
<HGroup>
<some basic components like `SkinnableContainer` and `Label` />
</HGroup>
</VGroup>
</Group>
And that's pretty much the layout of my worst performing (layout resizing wise) component, closing tag...
</VGroup>
... and we're done.
So the big question, is there room to optimise this? If so, where can I start? Obviously the layout manager has to calculate quite much during the layout switching process.
Unfortunately, since this is a mobile app, I can't work with absolute sizes at all as I need this app to work on a variety of platforms and resolutions, thus all groups have relative sizes assigned, usually 100% for both width and height.
I'd really like to streamline this, but I just don't know where to start. Any tips what I could do?
I was in charge of much of the same thing for a previous project, and while there was no 1 magic bullet that eliminated a chunk of problems, it fell in line with the "death by a thousand papercuts" theory.
A few examples of improvement based on yours:
The TitleBar: The skinnable container also has a layout property, why not just eliminate the outer Group shell, and start with the SC as the base?
<!-- <HGroup "the component's title bar"> -->
<SkinnableContainer id="originalGroupId" "title bar skin">
<layout>
<HorizontalLayout />
<layout>
<title bar components, labels etc. />
</SkinnableContainer>
<!-- </HGroup> -->
The OptionsBar: I don't know if there are limitations in the mobile space, but can you use a container that uses the INavigatorContent interface? IE. Something that will essentially use a creationPolicy flag that will only create the grandchildren of the container until the user actually requests it. With groups there is no concept of virtualization so all components get created at the instantiation of the parent.
<ViewStack "options bar that has switchable components">
<button />
</ViewStack>
The Component Area: This gets a little more challenging, sometimes it helps (at least it does for me) to take a 10,000ft view of what information you really want to display. For instance, the scrolling for a really long label, can you use something like a TextAera instead? If so that would eliminate the outer shell:
// the group here holds a large label that needs to be scrollable
<TextArea text="my really large label">
</TextArea>
Hope that helps...
Might be irrelevant, but I'd also advise against using Lists. Maybe it's not the same, but I changed one of my components from using List to dynamic skin parts and rendering of said component was noticeably faster (600 vs 100ms). Lists are pretty heavy in Spark.

"partial views" best practices for 'container' divs?

What is the 'best' way to handle the html markup for partial views? (which are also refreshed using AJAX) The biggest issue I run into is where to place the 'container' div...
Consider having a masterpage and a partial view.
(class="" could be interchanged with id="" depending if the partial is guaranteed to be unique, however this isn't really important to the issue i think)
Masterpage:
<div id="place1" class="placeholder">
<!-- render partial -->
</div>
Partial:
<div id="partial1" class="partial">
<!-- content -->
</div>
I feel that something isn't being done right. However I cannot remove the div in the masterpage, because I need that to 'encapsulate' the response from AJAX partial updates. And also I cannot move the div in the partial to the masterpage, because that would require to move 'partial' info to the masterpage...
How do you handle this?
I would say that it terms of the semantic description of what is happening here, of providing good hooks for styling and scripting, and also in terms of general robustness against future uses and changes, that using both divs is the best way to go.