Searching through JSON Object with ng-class (AngularJS) - javascript

I have two JSON objects defined in a controller (NotificationsController). One with all the notifications and another one with only the ID of the newest notifications (last 3 days).
Format of object "notifications": (t_notifications)
[{"0":"1","1":"4","2":"14-APR-16","3":"ALERT 1","ID":"1","ID_USER":"4","DATE":"14-APR-16","NOTIFICATION":"ALERT 1!"},{"0":"2","1":"1","2":"07-APR-16","3":"ALERT 2!","ID":"2","ID_USER":"1","DATE":"07-APR-16","NOTIFICATION":"ALERT 2!"},{"0":"3","1":"1","2":"13-APR-16","3":"ALERT 3!","ID":"3","ID_USER":"1","DATE":"13-APR-16","NOTIFICATION":"ALERT 3!"}]
Format of object "newest notifications": (newest_notifications)
[{"0":"1","ID_NEWNOTIF":"1"},{"0":"3","ID_NEWNOTIF":"3"}]
I'm displaying all the notifications in a view like this:
<div class="panel-body" ng-controller="NotificationsCtrl">
<table datatable="ng" class="row-border hover">
<thead>
<tr>
<th><b>ID</b> </th>
<th><b>ID_USER</b> </th>
<th><b>DATE</b> </th>
<th><b>NOTIFICATION</b> </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in t_notifications" ng-class="{selected: data.ID == **TO COMPLETE**>
<td>{{ data.ID }}</td>
<td>{{ data.ID_USER }}</td>
<td>{{ data.DATE }}</td>
<td>{{ data.NOTIFICATION }}</td>
</tr>
</tbody>
</table>
</div>
I would like to know how it is possible to select in my table only the newest notifications - searching through the JSON object newest_notifications - with ng-class?
PS: "selected" is already defined with a blue background color.

Just use a strict filter
... ng-class="{'selected': (newest_notifications | filter : { ID_NEWNOTIF: data.ID } : true).length !== 0 }"
Fiddle - https://jsfiddle.net/dyxf5xqj/

You can use a expression against data.DATE. For example
<tr ng-repeat="data in t_notifications" ng-class="{selected: data.DATE > someDateInThePast}">

Related

Bootstrap-vue - Display array data as dropdown in vue js

I have an array of JSON data like :
loggers = [{
"allAvailableLevel": ['WARN', 'DEBUG', 'INFO'],
"level": "WARN",
"logger": "com.test1",
"status": "success"
},
{
"allAvailableLevel": ['WARN', 'DEBUG', 'INFO'],
"level": "WARN",
"logger": "com.test2",
"status": "success"
}
]
I am using dropdown inside a table column and for that using below code, and basically traversing Loggers array but not able to extract allAvailableLevel data.
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Class</th>
<th>Current Level</th>
<th>All Available Levels</th>
<!-- Only display "Action" header if level is changed-->
<th>
Action
</th>
</tr>
</thead>
<tbody>
<tr v-for="(logger, index) in loggers" :key="logger">
<td>{{ index + 1 }}</td>
<td>{{ logger.logger }}</td>
<td>{{ logger.level }}</td>
<td>
<b-dropdown
boundary="viewport"
id="dropdown-dropup"
size="sm"
:text="selectedLevelText"
split
class="m-2"
>
<b-dropdown-item-button
v-for="logger in loggers[0].allLevel"
:key="logger"
#click.prevent="changeLevel(level)"
>{{ logger }}</b-dropdown-item-button
>
</b-dropdown>
</td>
<td v-if="levelChanged">
<b-button
size="sm"
variant="secondary "
#click.prevent="updateLevel(selectedLevelText)"
>Update</b-button
>
</td>
</tr>
</tbody>
</table>
with above code my dropdown looks like :
I want to display it like this :
How do I traverse my data inside the vue template to get only the data of "allAvailableLevel"?
You should iterate over that nested array as follows :
<b-dropdown-item-button
v-for="level in logger.allAvailableLevel"
:key="level"
#click.prevent="changeLevel(level)"
>{{ level }}</b-dropdown-item-button
>
Do this:
<tr v-for="(logger, index) in loggers" :key="logger">
<td>{{ index + 1 }}</td>
...
<td>
<b-dropdown
boundary="viewport"
id="dropdown-dropup"
size="sm"
:text="selectedLevelText"
split
class="m-2"
>
<b-dropdown-item-button
v-for="level in logger.allAvailableLevel"
:key="level"
#click.stop="changeLevel(level)"
>{{ logger }}</b-dropdown-item-button
>
</b-dropdown>
</td>
</tr>

Get place in table of icon using ng-click

I have a table that's generated using ng-repeat with some columns headers. On the column headers, I want to columns to be sorted. I included a font-awesome sort icon next to their text and when it's clicked, I call an ng-click with ng-click="sortColumn()". I'm calling this for every column header.
How do I know which column header got clicked on? Right now it fires for each header column.
How do pass the current column in using ng-click?
I tried to pass in this, but it returns the $scope object.
Here's what I have so far:
HTML:
<table class="table">
<thead>
<tr>
<td><b>Product </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
<td><b>Code </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
<td><B>Available </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
<td><B>Price </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
</tr>
</thead>
<tbody>
{{ vm.noProducts }}
<tr ng-repeat="product in vm.products">
<td>{{ product.productName}}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate | date }}</td>
<td>{{ product.price | currency }}</td>
</tr>
</tbody>
</table>
Javascript:
vm.sortColumn = function (obj) {
console.log(obj);
}
I don't think that you can just pass column as object to sortColumn(). If you need column in that function you can loop trough products and make a new array that will be populated for example with all product names.
Maybe that function could look like this:
function getColumn(val){ // 'productName'
var column = [];
for(var i in $scope.products){
column.push(column.push($scope.products[i][val]))
}
return column
}
If you want to sort table you can use orderBy filter.
To your sortColumn() function pass parameter name and in your ng-repeat use orderBy to order column ascending/descending by one of the parameters.
<table class="table">
<thead>
<tr>
<td ng-click="sortColumn('productName')"><b>Product </b></td>
<td ng-click="sortColumn('productCode')"><b >Code </b></td>
<td ng-click="sortColumn('releaseDate')"><b >Available </b></td>
<td ng-click="sortColumn('price')"><b >Price </b></td>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in products | orderBy: criteria">
<td>{{ product.productName}}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate | date }}</td>
<td>{{ product.price | currency }}</td>
</tr>
</tbody>
</table>
In your controller set default value for orderBy criteria. (I used here productName)
$scope.criteria = 'productName';
$scope.sortColumn = function(val){
console.log(val)
if($scope.criteria == val){
$scope.criteria = "-"+val;
} else {
$scope.criteria = val;
}
If user clicks on productCode for example, all rows will be sorted by that criteria ascending ('productCode'), if user click on productCode once again all will be sorted descending by criteria '-productCode'
I created small plunker to demonstrate that. Hope it helps.

nested ng-repeat that one depend on the other

I have an issue with angular, I want to use two nested ng-repeat in a data table where the first get the data, and the second get the name of field to be retrieved from the data (retrieved in the first ng-repeat)
here is what I tried to do with code :
<table md-table flex-order-gt-sm >
<thead md-head>
<tr md-row >
//1st : get the name of fields, not a problem
<th md-column ng-repeat="field in fields">{{item.name}}</th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="item in items">
<td md-cell ng-repeat="field in fields" >
//here is the problem I want to get the item that it's field name is field
{{item.{{field}} }}</td>
</tr>
</tbody>
</table>
for example if fields contain :{'a','b','c'}
and items contains {'a':'1','b':'2','c':'3'};
I want for example for the 1st iteration of {{item.{{field}} }} to return 1
Use toString() to retrieve the scope data in an scope object.
<tr md-row ng-repeat="item in items">
<td md-cell ng-repeat="field in fields" >
{{item[field.toString()]}}
</td>
</tr>
Here is the plunker
As an alternative you could also use a filter:
<td md-cell ng-repeat="field in fields | filter: { name: 'field' }">
</td>
You need to get fields collection according to item of items collection after
getFieldsByItem(item)
Then you can get field from fields collection
{{field}}

Datatable in responsive mode ng-click doesn't work

I have a datatable that is populated by angulars ng-repeat. the code below is what I am using, I have only changed the headers and what is being repeated.
It all works perfectly until I test it on a mobile device and the table turns responsive, adding the little circled + sign to expand and view the data from the hidden columns. When this happens the "More Info" button simply doesn't work any more.
From what I have surmised, the information that appears when you click the little + sign is dynamically added at the time you click it, meaning the "more info" button is a duplicate of the original which is still in the hidden table column. I believe that is causing the ng-click event to not be "wired up".
Does anyone know if I'm correct and/or how to fix this?
<table id="dtTransactions" datatable="ng" class="table table-bordered dt-responsive dataTable no-footer dtr-inline collapsed">
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
<th>header 3</th>
<th>header 4</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in people">
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.eyecolour }} }}</td>
<td>{{ person.shoesize }} }}</td>
<td align="center">
<button type="button" class="btn btn-default" ng-click="doSomething(person)">More Info</button>
</td>
</tr>
</tbody>
</table>
Here is my typescript for the controller. I'm very new to using typescript and am essentially copying what is already in this system and rejigging it for my own work:
module app.agreement {
'use strict';
class DetailController {
// some variable declared
static $inject = ['$compile', '$scope', 'data', 'app.services.AgreementService', '$mdDialog']
constructor(private $compile: ng.ICompileService,
private $scope: ng.IScope,
private data: any,
private agreementService: app.services.IAgreementService,
private mdDialog: angular.material.IDialogService) {
$('#dtTransactions').on('responsive-display', function () {
alert('asd');
//var c = $compile($('#dtTransactions').html());
//c($scope);
//$scope.$apply();
});
this.init();
}
init(): void {
// variables initialised
}
}
angular.module('app.agreement')
.controller('app.agreement.DetailController', DetailController);
}
I think you need ngTouch for mobile devices.
Your approach to achieve your functionality is wrong. You may try workaround with $index without repeating button as below.
<tr ng-repeat="person in people">
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.eyecolour }} }}</td>
<td>{{ person.shoesize }} }}</td>
<td align="center">
<button type="button" class="btn btn-default" ng-click="doSomething($index)">More Info</button>
</td>
</tr>

Using ng-switch to populate a table

I'm using a Angular.js on the front end to populate a table. I want to use ng-switch to display only data that has specific data in one column, for example only show ‘week 1’ data from a list of a NFL schedule, where one column in the data is Weeks.
So right now this code doesn't show anything in the table. If anyone could help explain this it would be greatly appreciated. Maybe I should be using ng-if ? Maybe I should have a button to press to show week 1, week 2 etc.. What's the best solution for this type of situation?
Here's the controller..
// #########################
// Predictions Controller
// #########################
BLV_app.controller('PredictionsController', function($scope, PredictionsFactory, $routeParams) {
PredictionsFactory.getPredictions(function(data) {
$scope.predictions = data;
});
});
Here's the factory..
// ---------------------------
// Prediction Factory
// ---------------------------
BLV_app.factory('PredictionsFactory', function($http) {
var factory = {};
var predictions = [];
factory.getPredictions = function(callback) {
$http.get('/predictions').success(function(output) {
predictions = output;
console.log("prediction factory", predictions);
callback(output);
});
};
return factory;
});
Here's the html..
<table class="table-striped" id="table-style">
<thead id="table-header">
<tr>
<th class="text-center">HomeTeam</th>
<th class="text-center">AwayTeam</th>
<th class="text-center">Prediction</th>
<th class="text-center">Result</th>
</tr>
</thead>
<tbody ng-repeat="predict in predictions" >
<div ng-model="predict.Week"></div>
<tr ng-switch="predict.Week">
<div ng-switch-when="1">
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.HomeTeam }}</td>
<td ng-if="$even">{{ predict.HomeTeam }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.AwayTeam }}</td>
<td ng-if="$even">{{ predict.AwayTeam }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.Prediction }}</td>
<td ng-if="$even">{{ predict.Prediction }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.Result }}</td>
<td ng-if="$even">{{ predict.Result }}</td>
</div>
</tr>
</tbody>
</table>
I believe there is something wrong with ng-repeat and ng-switch when binding to elements like tbody and td. Replace them with div and li makes it working properly: JSFiddle.
<div ng-repeat="predict in predictions">
<div ng-model="predict.id"></div>
<div ng-switch="predict.id">
<div ng-switch-when="1">
<li ng-if="$odd" style="background-color:#f1f1f1">{{ predict.name }}</li>
......
Changing from <div ng-repeat="predict in predictions"> to <tbody ng-repeat="predict in predictions"> makes it not working: JSFiddle.
In ng-repeat docs and ng-switch docs, it says:
Usage
as attribute:
<ANY
ng-repeat="">
...
</ANY>
But obviously they cannot be used on ANY elements.

Categories