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>
Related
I'm going crazy trying to figure out what the heck is going on. In practice I have an angular v9 app that uses a shared.js file where I have stored some functions that I share with part of the static frontend. At some point from the angular app I start the call to the addToCart () function. This function among many actions has the task of emitting the onAddToCart event to do other UI update stuff. I have other similar calls (ex. Login) and they work fine, this one doesn't.
ANGULAR COMPONENT HTML
<button (click)="addProductToCart(product)">Add</button>
ANGULAR COMPONENT TS
declare function addToCart(request): any;
-----
addProductToCart(product: Product): void {
addToCart(product);
}
SHARED.JS
function addToCart(product) {
...
dispatchEventAddToCart(cartItem);
}
function dispatchEventAddToCart(cartItem) {
const addToCart = new CustomEvent('onAddToCart', {
detail: cartItem
});
window.dispatchEvent(addToCart);
}
(() => {
refreshCartCounter();
window.addEventListener('onAddToCart', (e) => {
refreshCartCounter();
console.log('add to cart executed'); <= I see two log always!
});
})();
ANGULAR COMPONENT TEMPLATE
<div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th scope="col">Prodotto</th>
<th scope="col">SKU</th>
<th scope="col">Descrizione</th>
<th scope="col">Categoria</th>
<th scope="col">Marca</th>
<th scope="col">Preventivo</th>
</tr>
</thead>
<tbody *ngIf="productFindResponse">
<tr *ngFor="let product of productFindResponse.products">
<td>
<figure class="media">
<img src="{{ product.image}}" class="rounded img-thumbnail img-sm" #img (error)="img.src = getDefaultImage()" alt="{{ product.sku }} - {{ product.description }}">
</figure>
</td>
<td>{{ product.sku }}</td>
<td>{{ product.description }}</td>
<td>{{ product.category.name }}</td>
<td>{{ product.brand.name }}</td>
<td>
<button type="button" class="btn btn-primary" (click)="addProductToCart(product)"> Add <i class="fas fa-cart-plus"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
What i'm doing wrong?
Im tried to set bubble = false but the result is the same..
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.
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}">
i have this table that outputs a set of records in my view file here is what it looks like
what im trying to do is that when the user clicked the edit button on a specific row, it would get the data from each row, put it in a <p>Data here</p> then display it on the same page
what i have done so far is this, i made an onlick function
here is the code for the table in my view
<table class="table table-striped table-hover" id="detailTable">
<thead>
<tr>
<th>Record ID</th>
<th>School Year</th>
<th>School Quarter</th>
<th>Student Name</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach ($srs as $key => $vu)
<tr>
<td>{{ $vu->StudentRecordID }}</td>
<td>{{ $vu->SchoolYear }}</td>
<td>{{ $vu->SchoolQuarter}}</td>
<td>{{ $vu->full_name}}</td>
<td><button class="btn" id="gid" onclick="tgPanel();" >Edit</button></td>
</tr>
#endforeach
</tbody>
</table>
and here is the code in my javascript
function tgPanel()
{
document.getElementById("rid").innerHTML = document.getElementById("detailTable").rows[0].cells[1].innerHTML ;
document.getElementById("sy").innerHTML = document.getElementById("detailTable").rows[0].cells[2].innerHTML ;
..and so on..
}
well as of now the only thing im getting is the header i dont know how to indicate in the row[0]on what row o clicked the button any ideas?
Your onclick function needs a parameter.
onclick="tgPanel(this)"
Then you can work with the button and get the information.
function tgPanel(button) {
var tr = button.parentElement.parentElement;
}
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.