I get this ExpressionChangedAfterItHasBeenCheckedError when i am using random numbers progress bar in my html grid table.It says "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: some value. Current value: some value.". Someone please help me with the issue.
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" routerLinkActive="active">
<button class="btn btn-primary" (click)="goToAddUser()">Add User</button>
</a>
</li>
</ul>
</nav>
<div class="panel panel-primary">
<div class="panel-heading">
<h2>User List</h2>
</div>
<div class="panel-body">
<table class="table table-striped">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Actions</th>
<th>Progress</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | async">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>{{user.email}}</td>
<td>
<button (click)="goToEditUser(user.id)" class="btn btn-info">Update</button>
<button (click)="deleteUser(user.id)" class="btn btn-danger" style="margin-left: 10px">Delete</button>
<button (click)="goToViewUser(user.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
</td>
<td>
<mat-progress-bar [value]="number" style="margin-right: 300px"></mat-progress-bar>
{{ number }}%
</td>
</tr>
</tbody>
</table>
</div>
</div>
The getRandomNumber() return value changes after angular change detection already checked its value. To understand the error better, read this article:
https://hackernoon.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4
Here's one solution, make a class field called randomNumber and assign it to the value of getRandomNubmer().
class YourComponentClass { randomNumber : number = this.getRandomNumber(); ... }
In Html
<td> <mat-progress-bar [value]="randomNumber" style="margin-right: 300px">
</mat-progress-bar> {{ randomNumber }} </td>
if you want to change your randomNumber just create a click event handler to reassign randomNumber to getRandomNumber() method
You need to manually check for changes.
// Import
import { Component, OnInit, ChangeDetectorRef } from '#angular/core';
// Inject
constructor(private cd: ChangeDetectorRef)
// Call after making changes in component
someMethod() {
this.cd.detectChanges();
}
Related
Have a question about the HTML view related to the table.
In my HTML view, I have a table.
This is worked in a responsive way when changing the view.
Here I want to change the view that the responsive view comes with a scroll bar.
I want to change it to fit all columns to the view and wrap the column contents.
Any suggestions to do it?
<div class="col-md-12 col-sm-12 grid-margin stretch-card">
<div class="card shadow-card-l">
<div class="card-body">
<center><h4 class="card-title">Task Related Documents</h4></center>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Document Type</th>
<th>Document Note</th>
<th>File Name</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TaskFilesHistoryViewModel.OrderByDescending(x => x.Id))
{
<tr class="even pointer">
<td>#item.File_Type</td>
<td>#item.Note</td>
<td>#item.File_Name</td>
<td>
<a href="#Url.Action("DownloadTaskImage","Ajax", new { id = item.Id})" target="_blank" rel="publisher tag" class="btn btn-outline-info ti-import" />
<a href="#Url.Action("RetrieveTaskImage","Ajax", new { id = item.Id})" target="_blank" rel="publisher tag" class="btn btn-outline-success fa ti-eye" />
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
I'm using Angular2-Collapsible for my project. On clicking the table row, I want the details to be displayed. The code is attached below. Basically if I add [detail]= "detail1" then the collapsible-table-row-detail would be displayed on click. But since I'm using a for loop, I have to use the variable i. I've tried [detail]= "'detail'+i" and [attr.detail]= "'detail'+i". Nothing seems to be working.
<collapsible-table [type]="'accordion'" borderedVertically="true" class="table">
<thead class="table-heading">
<collapsible-table-row>
<th></th>
<th>Reference ID</th>
<th>Order ID</th>
<th> OName</th>
<th>FP</th>
<th>SP</th>
<th>Stat</th>
<th>date</th>
</collapsible-table-row>
</thead>
<tbody>
<collapsible-table-row *ngFor="let detail of details; let i = index" [attr.data-index]="i" [detail]="'detail'{{i}}">
<td><div class="input-group-text">
<input type="checkbox" aria-label="Checkbox for following text input">
</div>
</td>
<td (click)="showFirst=!showFirst"><i class="material-icons" *ngIf="showFirst"><span class="bulleticon"> - </span></i><i class="material-icons" *ngIf="!showFirst"><span class="bulleticon"> + </span> </i>{{detail.Reference_Id}}<br></td>
<td> {{detail.OId}} </td>
<td>{{detail.OName}}</td>
<td>{{detail.FP}}</td>
<td>{{detail.SP}}</td>
<td>{{detail.Stat}} </td>
<td>{{detail.date}}</td>
</collapsible-table-row>
<collapsible-table-row-detail #detail1 class="hidden-table">
<div class="container">
<div class="list col-5">
<span class="heading"> Order details </span>
<ul class="unorderedlist">
<li> data1 </li>
<li> data2 </li>
<li> data3</li>
</ul>
</div>
</div>
</tbody>
</collapsible-table-row-detail>
Thanks in advance!
Edit: Here's a stackblitz implmentation of what I'm trying to acheive. I've used [detail]= "detail1" for demo purposes. But I need to use a variable "i" in the for loop.
Visit https://stackblitz.com/edit/angular-fw5upv.
Try using
[detail]=" 'detail' + i "
Or
detail="detail{{i}}"
Try this:
<tbody>
<ng-container *ngFor="let detail of details; let i = index" >
<collapsible-table-row [attr.data-index]="i" [detail]="detail1">
<td>
<div class="input-group-text">
<input type="checkbox" aria-label="Checkbox for following text input">
</div>
</td>
<td >6565</td>
<td> {{detail.oid}} </td>
<td>{{detail.pname}}</td>
<td>{{detail.price}}</td>
<td>{{detail.qoh}}</td>
</collapsible-table-row>
<collapsible-table-row-detail #detail1 class="hidden-table">
<div class="container">
<div class="list col-5" >
<span class="heading"> Order details </span>
<ul class="unorderedlist">
<li> data4 </li>
<li> data5</li>
<li> data6 </li>
</ul>
</div>
</div>
</collapsible-table-row-detail>
</ng-container>
</tbody>
You can check in your stackblitz just replace the html code.
You could try using a method in your HTML like:
[detail]="getDetail(i)"
And then in your ts file:
getDetail(i: number) {
return 'detail' + i;
}
I have not tried this myself, so I'm not sure if it will work.
I use angular cli 1.4.3, node 6.11.3, npm 5.4.2, I want to read the records by using angular2. The output at localhost should be like this:
but the output that I get is like this:
here the html code:
<div class="row m-b-18px">
<div class="col-md-12">
<!-- button to create new product -->
<a (click)="createProduct()" class='btn btn-primary pull-right'>
<span class='glyphicon glyphicon-plus'></span> Create Product
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- HTML table for our list of product records -->
<table class='table table-hover table-responsive table-bordered'>
<tr>
<th>Product</th>
<th>Price</th>
<th>Description</th>
<th>Category</th>
<th>Actions</th>
</tr>
<!-- Use *ngFor directive to loop throught our list of products. -->
<tr *ngFor="let product of products">
<td>{{product.name}}</td>
<td>{{product.price}}</td>
<td>{{product.description}}</td>
<td>{{product.category_name}}</td>
<td>
<!-- read one product button -->
<a (click)="readOneProduct(product.id)" class='btn btn-
primary m-r-5px'>
<span class='glyphicon glyphicon-eye-open'></span> Read
</a>
<!-- edit product button -->
<a (click)="updateProduct(product.id)" class='btn btn-info
m-r-5px'>
<span class='glyphicon glyphicon-edit'></span> Edit
</a>
<!-- delete product button -->
<a (click)="deleteProduct(product.id)" class='btn btn-danger
m-r-5px'>
<span class='glyphicon glyphicon-remove'></span> Delete
</a>
</td>
</tr>
</table>
</div>
</div>
Here the css code:
.m-b-18px{ margin-bottom: 18px; }
.m-r-5px{ margin-right: 5px; }
.w-40-pct{ width: 40%; }
.text-align-center{ text-align: center; }
Thank you
Looks like you do not include Bootstrap in your project. First, install it:
npm install --save bootstrap
Then go to angular-cli.json file, find styles properties and add "../node_modules/bootstrap/dist/css/bootstrap.min.css" so it looks like this:
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
],
Are you use the View encapsulation in the component?
When a field value is too long in my bootstrap table, the table will extend to the length of the parameter even if its past the container. The only way I was able to somewhat prevent this is by using responsive-table, however then a scroll bar shows up on the bottom and you have to scroll all the way to the right to see the table data. How can I make it so when my table reaches the length of the container, the row data will wrap?
Here is an image of what is going on: http://i.stack.imgur.com/Bo1dO.jpg
Here is a portion of my view, the CSS and example can be seen here: https://jsfiddle.net/bsxtpoqd/
<div class="container">
<div class="row tab-content">
<div class="row">
<h3>Assigned Games</h3>
<p>Please enter a search string in the textbox to search for users</p>
<form class="form-inline">
<div class="form-group">
<input type="text" class="form-control" id="tableSearch" placeholder="Enter search term...">
</div>
</form>
<div class="table">
<table id="userTable" class="table">
<thead>
<tr>
<th>UserName</th>
<th>Alternate</th>
<th>Email</th>
<th>Assigned Games</th>
<th>Unassigned Games</th>
</tr>
</thead>
<tbody>
#foreach (var user in Model)
{
<tr>
<td>#Html.ActionLink(user.UserName, "_GameAssigner", "Admin", new { insUserId = user.InstitutionUserId }, new { #class = "modal-link" })</td>
<td>
#user.AlternateId
</td>
<td>#user.Email</td>
<td>
#if (user.Assigned.Any())
{
<a href="#" tabindex="0" role="button" data-toggle="popover" title="Games" data-trigger="focus"
data-content="#foreach (var gameName in user.Assigned){<div>#gameName</div>}">
#user.Assigned.Count</a>
}
else
{
<div class="text-warning">0</div>
}
</td>
<td>
#if (user.Unassigned.Any())
{
<a href="#" tabindex="0" role="button" data-toggle="popover" title="Games" data-trigger="focus"
data-content="#foreach (var gameName in user.Unassigned) {<div>#gameName</div>}">
#user.Unassigned.Count</a>
}
else
{
<div class="text-warning">0</div>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
You need to break up the long word.
<td style="word-break:break-all">
This is you need:
<style>
td
{
word-break: normal;
}
</style>
I'm trying to display different templates on selecting the menu options. I'm able to display it, but I want the menu to be displayed along with respective template selected in menu list (i.e., I want both menu and the respective option selected on same page). When I change the menu option, only the option template has to change and load different template keeping still displaying the menu.
Hope you got the idea. Can someone please suggest a way? Thank you.
Below are my codes:
UI Routing
"use strict";
angular.module('fleetOperate').config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("main");
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/landingPage/main.html'
})
.state('settings', {
url: '/settings',
views: {
'': {
controller: 'settingsController',
templateUrl:'app/landingPage/features/settings/settingsTemplate.html'
},
'settingsControlPanel#settings': {
controller: 'settingsControlPanelController',
templateUrl:'app/landingPage/features/settings/settingsControlPanel/settingsControlPanelTemplate.html'
},
'truckSettings#settings': {
controller: 'truckSettingsController',
templateUrl: 'app/landingPage/features/settings/settingsControlPanel/truckSettings/truckSettingsTemplate.html'
},
'trailerSettings#settings': {
controller: 'trailerSettingsController',
templateUrl: 'app/landingPage/features/settings/settingsControlPanel/trailerSettings/trailerSettingsTemplate.html'
}
}
})
});
main HTML
<div class="icon-bar" ui-view="main">
<a ui-sref="settings" class="item">
<i class="fa fa-cog" style="font-size:48px;"></i>
<label>Settings</label>
Settings HTML
<div ui-view="settingsControlPanel"></div>
Menu HTML
<div class="panel settings-panel panel-primary">
<div class="panel-heading" align="center">Settings</div>
<ul>
<li><a ui-sref="truckSettings"><i class="fa fa-truck settings-truck-icon"></i>Truck Settings</a></li>
<li><a ui-sref="trailerSettings"><i class="fa fa-train settings-truck-icon"></i>Trailer Settings</a></li>
</ul>
</div>
<div ui-view="truckSettings"></div>
<div ui-view="trailerSettings"></div>
Truck Settings HTML
<div class="panel truck-settings-panel panel-primary">
<div class="panel-heading">Truck Settings</div>
<table class="table truck-settings-table table-bordered table-condensed table-striped">
<tr>
<th>Model: </th>
<td class="list-truck-settings-data"></td>
</tr>
<tr>
<th>
Make Month & Year:
</th>
<td class="list-truck-settings-data"></td>
</tr>
</table>
</div>
Trailer Settings HTML
<div class="panel trailer-settings-panel panel-primary">
<div class="panel-heading">Trailer Settings</div>
<table class="table trailer-settings-table table-bordered table-condensed table-striped">
<tr>
<th>Model: </th>
<td class="list-trailer-settings-data"></td>
</tr>
<tr>
<th>
Make Month & Year:
</th>
<td class="list-trailer-settings-data"></td>
</tr>
</table>
</div>
If you don't need to route to individual pages, but are satisfied with just toggling on and off different sections of HTML from the same controller view, you could use ng-includes. Clicking the menu would set the variable for a particular include on or off, making it visible or invisible.
Example:
Menu HTML
<div class="panel settings-panel panel-primary">
<div class="panel-heading" align="center">Settings</div>
<ul>
<li ng-click="showTruck = true; showTrailer = false;"><i class="fa fa-truck settings-truck-icon"></i>Truck Settings</li>
<li ng-click="showTruck = false; showTrailer = true;"><i class="fa fa-train settings-truck-icon"></i>Trailer Settings</li>
</ul>
</div>
<div ng-if="showTrailer" ng-include="path/to/trailerSettingsTemplate.html"></div>
<div ng-if="showTruck" ng-include="path/to/truckSettingsTemplate.html"></div>
Ideally, the menu click logic should be a method in the controller that sets all values false, and only the one to show as true.
This pattern does not use routing, so if you want users to be able to navigate with history, this will not work. But if you have no need for individual controllers for each of these subviews, includes will do the job.
Angular docs for ngInclude
I found this as one option to the above posted question. We can simply use ng-show to trigger the views, while the controllers are still binded to each views in router.
Menu HTML
<div class="panel settings-panel panel-primary">
<div class="panel-heading" align="center">Settings</div>
<ul>
<li><a ng-click="truck=true; trailer=false"><i class="fa fa-truck settings-truck-icon"></i>Truck Settings</a></li>
<li><a ng-click="truck=false; trailer=true"><i class="fa fa-train settings-truck-icon"></i>Trailer Settings</a></li>
</ul>
</div>
<div ui-view="truckSettings" ng-show="truck"></div>
<div ui-view="trailerSettings" ng-show="trailer"></div>