I'm doing a table with angular using ng-repeat. And all it's work but in some cases the json return me some data like PA-AC-DE and i want to change this in the table in Pending, Active and deactivate. And i don't know how i can do it.
<table class="table table-bordered table-hover table-striped dataTable no-footer" data-sort-name="name" data-sort-order="desc">
<tr role="row" class="info text-center">
<th ng-click="order('msisdn')">Número Teléfono</th>
<th ng-click="order('icc')">ICC</th>
<!--th>IMEI</th-->
<th ng-click="order('ActivationStatus')">Estado</th>
<th ng-click="order('sitename')">Instalación</th>
<th ng-click="order('siteaddress')">Dirección</th>
<th ng-click="order('sitecity')">Ciudad</th>
<th ng-click="order('sitezip')">Código Postal</th>
<th ng-click="order('phonedesc')">Modelo Teléfono</th>
<th ng-click="order('ContractingMode')">VBP</th>
</tr>
<tr class=" text-center" ng-repeat-start="object in filteredsites = (objects | filter:searchText) | filter:tableFilter| orderBy:predicate:reverse" ng-click="showDetails = ! showDetails">
<td>{{object.msisdn}}</td>
<td>{{object.icc}}</td>
<td>{{object.ActivationStatus}}</td>
<td>{{object.sitename}}</td>
<td>{{object.siteaddress}}</td>
<td>{{object.sitecity}}</td>
<td>{{object.sitezip}}</td>
<td>{{object.phonedesc}}</td>
<td>{{ object.ContractingMode ? 'Yes': 'No'}}</td>
</tr>
</table>
You can use a filter
{{object.ActivationStatus | statusFilter}}
and statusFilter will be like:
angular.module('module', []).filter('statusFilter', function() {
return function(input) {
//switch-case
};});
You could use ng-show to show text depending on the value returned from your API like so:
<td><span ng-show="object.ActivationStatus=='AC'">Active</span><span ng-show="object.ActivationStatus=='PA'">Other Label</span></td>
and so on.
With a custom filter method it would look like in the demo below or here at jsfiddle.
But also a getter function with the same code would be OK.
angular.module('demoApp', [])
.controller('mainController', function() {
this.data = [
{status:'AC'},
{status:'AC'},
{status:'DE'},
{status:'PA'},
];
})
.filter('filterStatus', function() {
var labels = {
AC: 'active',
DE: 'deactive',
PA: 'pending'
};
return function(input) {
return labels[input];
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as ctrl">
<ul>
<li ng-repeat="row in ctrl.data">
status: {{row.status | filterStatus}}
</li>
</ul>
</div>
Based on AWolf answer with filter, here is using a function in the controller:
http://jsfiddle.net/f4bfzjct/
angular.module('demoApp', [])
.controller('mainController', function() {
var vm = this;
vm.data = [
{status:'AC'},
{status:'AC'},
{status:'DE'},
{status:'PA'},
];
vm.getFullStatus = function(value) {
var labels = {
AC: 'active',
DE: 'deactive',
PA: 'pending'
};
return labels[value];
}
});
<div ng-app="demoApp" ng-controller="mainController as ctrl">
<ul>
<li ng-repeat="row in ctrl.data">
status: {{ctrl.getFullStatus(row.status)}}
</li>
</ul>
</div>
I think you should create a filter in your module:
ngModule.filter('phoneNumberStatus', function() {
statuses = {
AC: 'Active'
DE: 'Unactive'
}
return function(value) {
return statuses[value] || "Unknown"
}
})
and then use it in your template:
<td>{{ object.ActivationStatus | phoneNumberStatus }}</td>
This way will enable you to reused this filter in any template, avoiding duplicated code.
You can create a javascript function that returns your desired value:
$scope.getFullActivationText = function(input) {
if (input === 'PA') {
return 'Pending';
}
else if (input === 'AC') {
return 'Active';
}
else if (input === 'DE') {
return 'Deactivate';
}
}
Now you can keep everything the same in your HTML but replace:
<td>{{object.ActivationStatus}}</td>
into
<td>getFullActivationText(object.ActivationStatus)</td>
Related
I have a very basic array
[
{
ticketId: 1,
name: "John",
},
{
ticketId: 124,
name: "Ads"
}
]
I show the data in the select
<ul class="dropdown-menu">
<li ng-repeat="ticket in tickets">
{{ticket.ticketId}}
</li>
</ul>
But how do I use the data from the selected ticket from another place in my code
like
<tr>
<th>Name</th>
<td>{{???}}</td>
</tr>
Controller
$http.get(ticketAPIBaseUrl + '/tickets/' + customerNumber,
{withCredentials: false}).then(response => {
console.log(response);
vm.tickets = response.data;
}, error => {
console.log(error);
});
You can use to that filter like so:
HTML:
<input type="number" ng-model="tick"/>
<table>
<tr ng-repeat="ticket in tickets | ticketFilter:tick">
<td>{{ticket.name}}</td>
<td>{{ticket.ticketId}}</td>
</tr>
</table>
JS:
app.filter('ticketFilter', function(){
return function(data, tick){
if (!tick) return data;
var ticketItems = [];
angular.forEach(data, function(item){
if(item.ticketId == tick) {
ticketItems.push(item);
}
});
return ticketItems;
};
})
plunker: http://plnkr.co/edit/q2ixIBCm9tfUW0c2V1BC?p=preview
Use the ng-click directive:
<ul class="dropdown-menu">
<li ng-repeat="ticket in tickets">
<a ng-click="selected=ticket">{{ticket.ticketId}}</a>
</li>
</ul>
Then display the selected item:
<tr>
<th>Name</th>
<td>{{selected.name}}</td>
</tr>
For more information, see AngularJS ng-click Directive API Reference.
I have the following table:
<table class="table main-table" ng-if="linesArray && linesArray.length > 0">
<!-- HEADER-->
<thead class="table-head">
<tr>
<th ng-repeat="column in ::columns" width="{{::column.width}}">{{::column.label}}</th>
</tr>
</thead>
<!-- BODY -->
<tbody>
<tr ng-repeat="line in linesArray">
<td ng-repeat="column in ::columns" width="{{::column.width}}" ng-class="{
'center-text' : (!line[column.key] || line[column.key].length === 0)
}">{{line[column.key] !== undefined ? line[column.key] : '--'}}
</td>
</tr>
</tbody>
</table>
Which renders as shown:
WHAT I'M TRYING TO ACHIEVE:
To concatenate the data of two separate fields into one in the first column, which should appear something like this:
As you can see, the column shows the date and time with certain formatting.
The directive which operates the logic of the table:
function historicalSummaryTable($filter) {
return {
restrict: 'EA',
link: link,
templateUrl: 'jfrontalesru/app/components/historicalSummary/historicalSummaryTable.html',
scope: {
linesArray: "=",
columns: "=",
groupField: "#",
groupFieldFilter: "#",
groupFieldFilterFormat: "#"
},
};
function link(scope, element, attrs) {
var _groupField = 'groupField';
var _subgroupField = 'subgroupField';
scope.$watch('linesArray', function(value) {
scope.linesArray.forEach(function(line) {
// Applies the filter for every column if set
scope.columns.forEach(function(column, index) {
// Applies the filter
if (column.filter && column.filter.length > 0) {
line[column.key] = $filter(column.filter)(line[column.key], column.format);
}
});
});
});
}
}
In this directive the input date data is formatted, then it's passed through the controller like this.
vm.historicalColumns = [
{label: $translate('columnDateTime'), key: "timestamp",width:"18%", filter:"date",format:"mediumTime", group:false},
{label: $translate('columnDetails'), key: "detail",width:"50%", group:false},
{label: $translate('columnOrigin'), key: "origin",width:"17%", group:false},
{label: $translate('columnUser'), key: "user",width:"15%", group:false}
];
I'm in the dark here, as I'm not sure how to do this.
Could add a span that uses ng-if to check index
<td ng-repeat="column in ::columns" width="{{::column.width}}" ng-class="{
'center-text' : (!line[column.key] || line[column.key].length === 0)
}">
<span ng-if="$index==0">first column only</span>
{{line[column.key] !== undefined ? line[column.key] : '--'}}
</td>
Or map your data in controller and do the concatenation there
I am working with AngularJS and angular-datatable and I want to work with the event in a row, I have setup the controller to listen the event but it is not work. My code is :
html
<div class="panel panel-flat">
<div class="panel-heading">
<h6 class="panel-title">Planilla</h6>
</div>
<div class="panel-heading">
<table class="table datatable-basic table-hover" datatable="ng" dt-options="empleadoList.dtOptions" dt-column-defs="empleadoList.dtColumnDefs" >
<thead>
<tr>
<th style="width: 30px;">Nro.</th>
<th>Nombre Completo</th>
<th class="col-md-2">DNI</th>
<th class="col-md-2">Celular</th>
<th class="col-md-2">Teléfono</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="empleado in empleadoList.empleados">
<td style="width: 30px;">{{$index + 1}}</td>
<td> <span class="text-muted"><i class="icon-user"></i>{{empleado.apellidoPaterno}} {{empleado.apellidoMaterno}} {{empleado.nombre}}</span></td>
<td><span class="text-success-600"><span class="status-mark border-blue position-left"></span>{{empleado.dni}}</span></td>
<td><span class="text-success-600"><i class="icon-mobile position-left"></i> {{empleado.celular}}</span></td>
<td><h6 class="text-semibold"><i class="icon-phone position-left"></i> {{empleado.telefono}}</h6></td>
</tr>
</tbody>
</table>
</div>
</div>
controller.js
App.controller('EmpleadoListController', function($scope,$resource,EmpleadoService,DTOptionsBuilder,DTColumnDefBuilder) {
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withDisplayLength(10)
.withOption('bLengthChange', false)
.withPaginationType('full_numbers')
.withOption('rowCallback', rowCallback);
$scope.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0),
DTColumnDefBuilder.newColumnDef(1),
DTColumnDefBuilder.newColumnDef(2),
DTColumnDefBuilder.newColumnDef(3),
DTColumnDefBuilder.newColumnDef(4)
];
function rowCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('td', nRow).unbind('click');
$('td', nRow).bind('click', function() {
$scope.$apply(function() {
console.log('click row');
});
});
return nRow;
}
EmpleadoService.fetch().then(
function(response){
return $scope.empleadoList = { empleados: response.data};
},
function(errResponse){
console.error('Error while fetching users');
return $q.reject(errResponse);
}
);
});
app.js
'use strict';
var App = angular.module('myApp', ['ngRoute','ngResource','datatables']);
App.config(function($routeProvider) {
var resolveEmpleados = {
empleados: function (EmpleadoService) {
return EmpleadoService.fetch();
}
};
$routeProvider
.when('/planilla', {
controller:'EmpleadoListController as empleadoList',
templateUrl:'static/js/planilla.html',
});
});
Thanks for all.
Since you are using the angular way for rendering, why not use ng-click as well :
<tr ng-repeat="empleado in empleadoList.empleados" ng-click="click(empleado)">
$scope.click = function(empleado) {
console.log(empleado.apellidoPaterno+' clicked')
}
I see you miss function in your code:
function someClickHandler(info) {
vm.message = info.id + ' - ' + info.firstName;
}
function rowCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
// Unbind first in order to avoid any duplicate handler (see https://github.com/l-lin/angular-datatables/issues/87)
$('td', nRow).unbind('click');
$('td', nRow).bind('click', function() {
$scope.$apply(function() {
vm.someClickHandler(aData);
});
});
return nRow;
}
and don't forget this:
vm.someClickHandler = someClickHandler;
you can read document in here
Hope help you.
You were almost there. The row element is accessible from within the row callback function as nRow.
So for instance you can for instance change the colour of the row by toggling the selected class as follows
$scope.$apply(function() {
$(nRow).toggleClass('selected');
// do your stuff with the row here
});
nRow gives you access to the row element.
Then there is aData which gives you an array containing the values of the td or column elements in that row.
$scope.$apply(function() {
console.log(aData);
// do your stuff with the row here
});
Maybe this code can help us:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-row-click-event',
templateUrl: 'row-click-event.component.html'
})
export class RowClickEventComponent implements OnInit {
message = '';
dtOptions: DataTables.Settings = {};
constructor() { }
someClickHandler(info: any): void {
this.message = info.id + ' - ' + info.firstName;
}
ngOnInit(): void {
this.dtOptions = {
ajax: 'data/data.json',
columns: [{
title: 'ID',
data: 'id'
}, {
title: 'First name',
data: 'firstName'
}, {
title: 'Last name',
data: 'lastName'
}],
rowCallback: (row: Node, data: any[] | Object, index: number) => {
const self = this;
// Unbind first in order to avoid any duplicate handler
// (see https://github.com/l-lin/angular-datatables/issues/87)
$('td', row).unbind('click');
$('td', row).bind('click', () => {
self.someClickHandler(data);
});
return row;
}
};
}
}
```
Link where i found this example:
[Link github datatables examples][1]
[1]: https://github.com/l-lin/angular-datatables/blob/master/demo/src/app/advanced/row-click-event.component.ts
I want to disable button Assign when it clicked, bacause it should assign only once so i can achieve this, I have done the following code in HTML:
<table class="table details">
<thead>
<tr>
<th sort-by="firstName">User Name</th>
<th sort-by="lastName">Description</th>
<th sort-by="Budget" sort-init="desc">Bid Amount</th>
<th sort-by="lastName">Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="issue in issues | filter:filter">
<td><strong><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{ issue.UserName }} </strong></td>
<td><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{ issue.Description }}</td>
<td><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{issue.Bid_amt}}</td>
<td>
<div ng-controller="ExampleCtrl_Assign">
<div ng-show="AsgHide">
<button type="button" ng-click="AssignRecord(issue.ID,issue.Description,issue.Bid_amt)">Assign</button>
</div>
</div>
<div ng-controller="ExampleCtrl_Delete">
<div ng-show="AsgHide" >
<button type="button" ng-click="DeleteRecord(issue.ID)">Delete</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
And JavaScript Code is as following:
var app = angular.module('siTableExampleApp_Assign', []);
app.controller('ExampleCtrl_Assign', ['$scope','$http', function ($scope, $http) {
var user2 = window.localStorage.getItem('UserId');
var Basic = window.localStorage.getItem('Basic');
var Token = window.localStorage.getItem('Token');
$scope.FunctionDisable = function (i) {
$("#rbutton'+i+'").attr("disabled", "disabled");
}
$scope.AssignRecord = function (ID, Description, Bid_amt) {
var BidID = ID;
var date = new Date();
encodedString = {
"ID": 1,
"Travel_Info_ID": travel_info_id,
"Bid_ID": parseInt(BidID),
"Description": Description,
"Bid_amt": Bid_amt,
"Status": "InProcess",
"User_ID": user2,
"Entry_Date": date,
"Update_Date": date
}
$http({
method: 'POST',
url: 'http://saisoftwaresolutions.com/v1/Assigned_Bids/Assigned_Bid/Create',
data: encodedString,
headers: {
'Authorization': 'Basic ' + Basic,
'Token': Token
}
})
.success(function (data, status, headers, config) {
console.log(headers());
console.log(data);
if (status === 200) {
//window.location.href = 'http://localhost:22135/BDetail/Index';
} else {
$scope.errorMsg = "Login not correct";
}
})
.error(function (data, status, headers, config) {
$scope.errorMsg = 'Unable to submit form';
})
Use can always use ng-disabled directive provided by Angular to disabled html elements.
I have made one example based on your requirements and help it will solve your issue:
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in items">{{item.User_ID}}: {{item.User_Name}}
<button ng-click="handleClick($index)" ng-disabled="item.disabled">
{{item.User_Name}}
</button>
</li>
</ul>
</div>
function MyCtrl($scope) {
$scope.items = [
{
User_ID: '10',
disaled: false,
User_Name: 'ABC'
}, {
User_ID: '11',
disaled: false,
User_Name: 'XYZ'
}
];;
$scope.handleClick = function(index){
$scope.items[index].disabled = true;
}
}
Angular has a directive just for this: ng-disabled.
From their official documentation:
This directive sets the disabled attribute on the element if the
expression inside ngDisabled evaluates to truthy.
So you can set a boolean value in your code-behind to true and have that evaluate inside your button. For example:
<button type="button" ng-disabled="issue.IsDisabled" ng-click="AssignRecord(issue.ID,issue.Description,issue.Bid_amt)">Assign</button>
Also, check out the example in their documentation and this jsfiddle: https://jsfiddle.net/simpulton/q8r4e/.
I'm trying to create a stateful filter with AngularJS to eventually call a service that will return data asynchronously. To test this, I'm just using a simple $timeout function that console.logs a string. However, this console.log is just running infinitely.
export default angular.module('components.filters.combine-name', [])
.filter('combineName', ['$timeout', function ($timeout) {
function combineName(input) {
$timeout(function () {
console.log('test');
}, 1000);
return input.firstName + ' ' + input.lastName;
}
combineName.$stateful = true;
return combineName;
}]);
html
<table class="table table-bordered table-striped table-responsive">
<thead>
<tr>
<th>
<div class="th">
Name
</div>
</th>
<th>
<div class="th">
Status
</div>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in vm.results">
<td>{{result | combineName}}</td>
<td>{{result.status}}</td>
</tr>
</tbody>
</table>
controller:
this.results = [
{
firstName: 'Johnny',
lastName: 'Utah',
status: 'Active'
},
{
firstName: 'Richard',
lastName: 'Reynolds',
status: 'Inactive'
},
{
firstName: 'Randy',
lastName: 'Johnson',
status: 'Active'
}
];
With $timeout, you basically turn on the looping and it will keep doing so, unless you tell it to stop.
Inside your loop use: $timeout.cancel();