How to display icons in a table depending on model in AngularJS? - angularjs

I am new to AngularJS (and Javascript as well) and I try to display different icons in a table depending on a value in a field from my model.
Let's say this is my model:
$scope.MyList = [{ name: "Production", status: "Running"},
{ name: "Test", status: "Stopped"}];
This is a table for displaying the model in one of my views:
<table class="table table-striped">
<thead>
<tr>
<td>Name</td>
<td>Status</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in MyList">
<td>{{instance.name}}</td>
<td>{{instance.status}}</td>
</tr>
</tbody>
</table>
I would like to display the status using both one icon and the text. What is the recommended way of doing it? I would like to use something that feels natural with AngularJS.
Thank you.

The answer from dolgishev pointed me into the right direction.
I initialice my table elements like this:
<tr ng-repeat="item in itemList">
<td>{{item.name}}</td>
<td class="{{item.status}}">{{item.status}}</td>
</tr>
and then I use CSS for displaying the icon using a font from FontAwesome. This is for example the CSS for the state 'Running':
.Running:before {
font-family: 'FontAwesome';
font-size:1.3em;
color:green;
content: '\f00c'; /* the ok icon */
padding-right: 4px; /* plus 4px spacing */
}
This will display the ok icon in green, then 4 pixel padding and then the text for the state "Running". It is looking great!

For solve this you can use Angular's directive ng-class. It allows you to set class of element depend on expression.
Also you can do this without directive, in this way:
<div class="{{MyList.name}}">

Related

Bootstrap + AngularJS - Multiple page print job with common header/footer

I am using bootstrap with AngularJS and trying to ng-repeat out a table within the template I purchased and when over a certain amount is put into the orderInformation.items array I run into issues with how the print looks.
I want to be able to hit print and have a defined page heading and a defined page footer that will not change and should nest in the top and bottom of the print preview across all pages. The only content that will change is the items that AngularJS is doing an ng-repeat on.
How can this be done? I've been searching for days and days and nothing out there seems to work.
<div class="row">
<div class="col-md-12 card-box">
<table id="invoice-contents" style="width: 100%">
<thead>
<!-- This is where logo, company details, barcode go -->
</thead>
<tbody>
<table id="item-table" class="table m-t-30" style="border-bottom: 1px solid rgba(0,0,0,.1)">
<thead>
<!-- Invoice Item headers -->
</thead>
<tbody>
<tr ng-repeat="item in orderInformation.items">
<td style="text-align: center">{{$index + 1}}</td>
<td style="text-align: center">{{item.qty.ordered}}</td>
<td style="text-align: center">{{item.qty.shipped}}</td>
<td style="text-align: center">{{item.qty.backordered}}</td>
<td style="text-align: center">{{item.binLocation}}</td>
<td style="text-align: center">{{item.partNumber}} - {{item.description}}</td>
<td style="text-align: center">{{item.price.current * item.qty.shipped | number: 2}}</td>
<td style="text-align: right">{{item.price.extended * item.qty.shipped | number: 2}}</td>
</tr>
</tbody>
</table>
</tbody>
<tfoot>
<!-- Special order notes, totals, taxes, terms -->
</tfoot>
</table>
</div>
</div> <!-- end container -->
This doesn't work when I use the recommended CSS that I have found around:
thead { display: table-header-group; }
tbody { display: table-row-group; }
tfoot { display: table-footer-group; }
The documentation says a table can't have two thead so I know the problem lies there, but I can't find any other way to get a block to print top and bottom on all pages other than table-header-group.
A way round this through much trial and error was to product an onscreen display of a single invoice page with how ever many rows of data and then use display:none to hide a view that would only show during print with CSS #media print. I had to calculate how many rows would show on each page and use .splice() and nested ng-repeats to get it displaying properly.

AngularJS: Table with ng-repeat on table row / column

I need to create a table from an array of objects but I don't want to hardcode the table. I can't do this or this for example. I rather need nested ng-repeats like this. But my case is a little bit different because I have columns which contain two values in an array. The data looks like this:
[
{
"foo":"bar",...,
"key1":[
"value1",
"value2"
],
"key2":[
"value1",
"value2"
],...,
"more_foo":"more_bar"
},...
]
I want the values (which are always strings) of all objects (which have always an equal structure) from the array in the table rows where each key should be the column name. Like this:
table,
th,
td {
border: 1px solid black;
text-align: center;
border-spacing: 0;
}
td,
th {
padding: 0.5em;
}
<table>
<thead>
<tr>
<th>foo</th>
<th colspan="2">key1</th>
<th colspan="2">key2</th>
<th>more_foo</th>
</tr>
</thead>
<tbody>
<tr>
<td>bar</td>
<td>value1</td>
<td>value2</td>
<td>value1</td>
<td>value2</td>
<td>more_bar</td>
</tr>
</tbody>
</table>
Here is what I have come up with:
<table>
<thead>
<tr>
<th ng-repeat="(propName, prop) in myArray[0]"
colspan="{{isUpdateable(propName) ? 2 : undefined}}"> {{propName}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in myArray | filter: searchFilter">
<td ng-repeat="(propName, prop) in object" double-col>{{prop}}</td>
</tr>
</tbody>
</table>
isUpdatable(propName) will return true if this value is an array and false if it is not. This will make it possible to have two tds in this column.
The double-col directive:
app.directive('double-col', function () {
return {
transclude: true,
template: "<td>{{prop[0]}}</td><td class=\"changedProp\">{{prop[1]}}</td>"
};
});
I want this directive to replace the existing td with two tds if and only if prop is an array and otherwise do nothing to display prop (see td above).
Because you are on https://stackoverflow.com (the place where people post things that dont't work well yet), you can probably guess that my current code doesn't not work really well. I am also new to angularJS and have basically no understanding of custom directives (and probably most other stuff too) so it would be nice if someone could help me with this problem and provide an explanation as well.
What about
<tr ng-repeat="object in myArray | filter: searchFilter">
<td ng-repeat="(propName, prop) in object" colspan="{{isArray(prop) ? prop.length : 1}}">
<span ng-if="!isArray(prop)"> {{prop}}</span>
<table ng-if="isArray(prop)"><tr>
<td ng-repeat="prop1 in prop">
{{prop1}}
</td>
</tr></table>
</td>
</tr>
$scope.isArray=function(prop){
return Array.isArray(prop);
}
Here is working fiddle

angular smart-table plugin/directive wont work

I am trying to use smart-tables, Select row plugin, I have added 'smart-table' to my application, like so var myApp = angular.module('myApp', ['ui.bootstrap','smart-table']);
I have also changed the first line of the directive (since it didn't work to just copy-paste it), I changed this:
ng.module('smart-table').directive('stSelectRow', ['stConfig', function (stConfig)
To this: myApp.directive('stSelectRow', ['stConfig', function (stConfig) {
In my html I have this
<table st-table="displayedCollection" st-safe-src="safeCollection" class="table">
<thead>
<tr>
<th>Title</th>
<th>FieldOne</th>
<th>FieldTwo</th>
<th>FieldThree</th>
</tr>
</thead>
<tbody>
<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in displayedCollection">
<td> {{row.Title}} </td>
<td> {{row.FieldOne}} </td>
<td> {{row.FieldTwo}} </td>
<td> {{row.FieldThree}} </td>
</tr>
</tbody>
If I remove the st-select-row="row" st-select-mode="multiple" the table works, but obviously not the row selection
I am guessing I'm missing some dependency or something, I have only added smart-table.min.js to my application, but I think that should be enough, the directive (select row plugin) is added inside my app.js file. What could it be?
It is because the documentation on the site isn't exactly clear. But it does say
...and the class attribute st-selected is set on the tr element.
You have to define the CSS for st-selected for it to "work":
.st-selected{
background: #216eff !important;
color: white !important;
}

ngtable how to remove title centered

I'm trying to work on ngTable, and i find it ugly to put Title of column in midle by standard... how can we put the title to the left like the text of the row?
Here is the html code:
<table ng-table class="table">
<tr ng-repeat="survey in vm.surveys">
<td data-title="'#L("Name")'">{{survey.name}}</td>
<td data-title="'#L("CreatedDate")'">{{survey.creationTime}}</td>
<td data-title="'#L("Creator")'">{{survey.creatorUser}}</td>
</tr>
</table>
Just add the following CSS rule:
.ng-table th { text-align: left; }

TrNgGrid display custom column filter

I'm trying to add custom column filter (autocomplete, select ...) but can't find how. I tried to override default filter template with a tr-ng-grid-column-filter attribute on a th, but it does not works. Header is changed somehow (title is not bold anymore) and the new template is not used at all.
Is the tr-ng-grid-column-filter right way to do it at all or there is something else?
Data is sorted, paginated and filtered on the server so it does not have any relation to angular or trnggrid client side filtering & formating. So I just want to display some other input on some columns (e.g. select) instead of default input text rendered by a grid.
I'm using angular 1.2.22 with TrNgGrid 3.0.3
There are some samples floating around the net. Here's one:
http://plnkr.co/edit/I6JJQD?p=preview
<table tr-ng-grid='' items='myItems'>
<thead>
<tr>
<th field-name="name"></th>
<th field-name="computedTagsField" display-format="computedTags:gridItem">
<div>
<div class="tr-ng-title">Tags</div>
<div class="tr-ng-column-filter">
<select class="form-control input-sm" ng-options="tag for tag in [null, 'tennis', 'basketball', 'volley']" ng-model="columnOptions.filter"></select>
</div>
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td field-name="computedTagsField"></td>
</tr>
</tbody>
</table>
I created a directive to implement a custom drop down filter. It, in itself, can be reused on any project, but it will also give you a good working example of how to implement your own custom filter by simply extending TRNG grid.
Tutorial:
http://www.davidcline.info/2015/08/trnggrid-dropdown-column-filter.html
Demo:
http://embed.plnkr.co/w39Xt74pippDajyqUIOD/preview

Resources