Update table cell value dynamically using angular6 - html

I am working with an angular 6 application, in the HTML template I have some code as per below, just showing the table cell part of the array, also the table is built using divs.
<div class='table_small'>
<div class='table_cell'>Status</div>
<div class='table_cell'>
<p class="status" >{{incomingData.status}}</p>
</div>
</div>
Please note here that "data" is an array (*ngFor) and is being used in row data and there are multiple data in the table.
Now I have a situation wherein there is a button inside the table rows to cancel the particular order, when the user clicks in, a pop up/modal asks for user confirmation, if the user opts for 'Yes' it would change the status field value to "cancellation is in process" temporarily before it hits the service, once there is a successful response from the customer it would change the station to "cancelled".
I am really not sure how to do the cancellation within the table cell here, if anyone can give insight on this please do.
Thanks

You could pass the element to the function and edit its status:
<div class='table_small'>
<div class='table_cell'>Status</div>
<div class='table_cell'>
<p class="status" >{{incomingData.status}}</p>
</div>
<div class='table_cell'>
<button (click)="showCancelModal(incomingData)"> Cancel</p>
</div>
</div>
And then in the component something like this:
showCancelModal(incomingData) {
// logic for showing modal and retrieving user response
if( response === 'yes') {
incomingData.status = 'Cancel in progress';
yourService.cancel(incomingData)
.pipe( finally(() => incomingData.status = 'Cancelled') )
.subscribe();
}
}

Related

How do I improve performance when constructing a grid in Angular?

Everytime the route changes (recordTab.Id changes) I have to construct a new grid with five columns and output it.
The following code generates the grid every route change
// used later in html code to generate five columns with *ngFor
this.columns = [0,1,2,3,4]
// the records are filtered based on the id
this.id = recordTab["id"];
//allRecords has 1300 elements in it
this.records= allRecords.filter(record => record.recordTabId == this.id); // filter by recordTabId
// construct grid with 5 columns
// the maximum number of cells per column are 300
for(let i=0; i<5; i++){
this.grid[i] = [];
this.grid[i] = new Array(recordTab["gridCells"]); // number of cells in a column
}
if(this.records){
for(let record of this.records){
// assigning record to its corresponding cell
this.grid[record.column - 1][record.row - 1] = record;
}
}
// has maximum 5*300 entries
// 600 entries filled
// rest is empty to simulate empty cells
console.log(this.grid)
Now I am displaying the grid in the following way:
<div class="grid-container">
<div class="column" *ngFor="let column of columns">
<div class="cell" *ngFor="let record of grid[column]">
<ng-container *ngIf="record">
<div class="record checkboxes" [ngStyle]="{'background-color': record.categorie==1 ? record.rgbFarbeHex : 'white'}" [ngClass]="{'heading-container': record.categorie==1}">
<label [ngClass]="{'heading': record.categorie==1}" [title]="record.name" (contextmenu)="showRecordInformation($event, record)"> <span *ngIf="record.categorie==0"> <input type="checkbox"> </span> {{record.name}}</label>
</div>
</ng-container>
</div>
</div>
</div>
The problem is that the grid takes some time to show up for the grid with 5*300 entries and 600 actually filled entries. How could I improve the performance?
I dont think the css is the problem, that is why I dont show it. If it is necessary, tell me.
You should take a look at trackBy. It will tell your ngFor to only rerender what changed based on what you are tracking. It's hard to tell if it can work in your case but there is no other solution since as soon as the array changes, angular loose track of what's going on and needs to render the *ngFor again.
It would look like that:
<div class="column" *ngFor="let column of columns; trackBy:trackByFn">
trackByFn(index, item) {
return item.id;
}

How to post SQL values into checkboxes

First of all, my question might be a duplicate question to this one: Need html checkbox to be checked by mysql result but I do not understand the answer - the op didn't post any code and I don't see how to fit the suggested code into my case because I need to get the values from SQL (?).
Here all the data:
I have an HTML form with checkboxes, which stores the values as for checked as "1" and unchecked as "0" into an SQL database on submit of the form. Now I want to make it so that it (on page load) pulls data from database and populates the form's checkboxes when the same user comes back to the page. (I know my code is faulty in some places, I still need to resolve quite some things on this project) for right now, what I want to solve is to get the SQL to output the result to existing HTML checkboxes (not create new checkboxes or new HTML form).
Note: my HTML form and my php form are in two separate files and they cannot be merged (I don't know if that makes a difference).
All checkboxes in the form are empty by default. I am using Ajax in my form so that on pageload the userid is passed to a php file which then runs the SQL Query to pull up "1" if the checkbox should be checked and "0" if it should be left unchecked.
Here the piece of HTML which is relevant to the case:
<input type=text id="userid" name="userid" value="">
</div>
<div class="grid">
<div>
<div class="grid-item">
<img src="image.png" alt="">
</div>
<div class="grid-item-title">
<h2>Title</h2>
</div>
<div class="grid-item">
<p>
<input type="hidden" name="owns[item1]" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">I own this<br>
</p>
</div>
</div>
<div>
<div class="grid-item">
<img src="image.png" alt="">
</div>
<div class="grid-item-title">
<h2>Title 2</h2>
</div>
<div class="grid-item">
<p>
<input type="hidden" name="owns[item2]" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">I own this<br>
</p>
</div>
</div>
This is the Ajax code I am using:
document.addEventListener("DOMContentLoaded", function myFunction() {
var x = 3 //replace with user ID
$.ajax({
url: 'libraryRequest.php',
method: "post",
data: {"userid": x }, // sends id to PHP
dataType: "html",
async: false,
success: function(data){
$('#content').html(data); // currently this overwrites all HTML on the page...
},
error: function (xhr, ajaxOptions, thrownError) {
var errorMsg = 'Ajax request failed: ' + xhr.responseText;
$('#content').html(errorMsg); // currently this overwrites all HTML on the page...
}
})
});
And this is the PHP code I managed to put together sofar:
$userid = 0;
$userid = $_POST['userid'];
if ($userid != 0) { //only execute if there is a user id
$userquery = "SELECT * FROM libraryG WHERE userid =$userid"; //find if userid exists
$result = mysqli_query($con, $userquery);
if(mysqli_num_rows($result)>0) { //if user id exists run this code to pull the data
$sqlupdate = "SELECT * FROM libraryG WHERE userid = $userid";
mysqli_query($con, $sqlupdate);
if ($result->num_rows > 0) {
while($row = $result->fetch_row()) {
print json_encode($row); // edited
}
} //if user id doesn't exist in db or there is no user id - do nothing
}
Each checkbox value is stored in a separate column in SQL.
I have been on this for hours now but in most cases the similar questions I found are explaining solutions for C# or ASP which I have never used and being kinda new in everything I try to avoid those things I don't know anything about if there is a way to do it otherwise.

how can i set a time to show something with angular?

i've a search field and when i search for something and nothing is found, i show a message for user, but when has content to show, the message error appear for 3~4 seconds and after this time the message is disappear and the result of search appear...
my html:
<div>
<h2>Search page</h2>
<div class="container clearfix" ng-controller="restaurantsDataCtrl" group-by="category">
<restaurants-gallery ng-show="restaurants.length" category="{{list.category}}" restaurants="{{list.restaurants}}" ng-repeat="list in restaurantsByCategory">
</restaurants-gallery>
<p ng-show="!restaurants.length">Message nothing found.</p>
</div>
</div>
what i need is set a time for this message appear and when this time is ended angular will know if show or not the message.
One thing you could do is create a flag to indicate whether your data request has started:
$scope.completed = false
then in the callback for your data request set that flag as true:
...
$http.get(...).then(function(response) {
$scope.completed = true;
$scope.restaurants = response.data;
}
if you combine that with your conditional to see if there are in fact no restaurants you can be guaranteed the message will only show up after you've tried to get data and nothing came back:
<p ng-show="!restaurants.length && completed">Message nothing found.</p>
Here's a small working example of that idea: http://plnkr.co/edit/IYtSKMHco52rHGWTT55W?p=preview

How to set the outer div values in html page

I have an html page in Angularjs. In the page there are two divs one contains the data regarding total no of users and other div contains the table in which the data are populated from the service a list of user.
The code is.
app_user.html
// IN this div i am getting the total no of users by users.length
<div id ="total_user"> no of users {{users.length}} </div>
<div id ="user_table">
// In this the no of users keeps changing as soon filter is applied
<tr ng-repeat="row in users | filter : {status: search['_status']} | filter : {payment_type:search['pay_type']}| orderBy : orderBy:reverse ">
<td >
<div ng-if="row.status !== 'Failure'"><!--{{$index}} -->
<input type="checkbox" checklist-model="user.roles" checklist-value="row.id">
</div>
</td>
<td>
<a ng-href="https://userapp.com/{{row.id}}" target="_blank">{{row.username}}</a>
</td>
<td>
<div>
<div>{{row.location}}</div>
</div>
</td>
</div>
In the first div i am finding the total no of users and in the second div i am showing the list of user with details.
I have applied the filters which are working fine. Now what i want is when i apply the filter the No of user should also change for a particular filter applied. I am not getting the way of how to pass the row.length to the outer div.
For ex : before applying filters i have total no of user say 100, When i applied the filters the total no of users are now 40. Now in the first div i want to show the total no of user as 40 instead of 100.
Please use the below way to get the count.
ng-repeat="row in filteredusers = (users | filter:{status: search['_status']} | filter : {payment_type:search['pay_type']} | orderBy:reverse)"
Would create the filtered list on the fly, you can use filteredusers.length anywhere else in the current scope to show the count.
Filtered Count
{{filteredusers.length}}

Angularjs load json into a specific div

I'm new to AngularJS but I love the framework.
What I have right now, is a (stub) single page that loads json data.
JS
var merlinoApp = angular.module('merlino', []);
merlinoApp.controller('mainController', function ($scope, $http) {
...
$http.get('#Url.Action( "consoledatapull", "ConsoleElaborazioni")')
.then(function (res) {
$scope.jobs = res.data.jsonjobs;
$scope.clienti = res.data.jsonclienti;
$scope.console = res.data.jsonconsole;
});
...
});
HTML
<div ng-repeat="roll in jobs | orderBy:sortType:sortReverse | filter:searchJob | filter:searchCliente | filter:searchStato" class="console-row my-row">
...
<div class="console-cell-id console-cell console-cell-padding console-cell-no-border-sx">{{ roll.id }}</div>
...
<div ng-click="collapsed=!collapsed" ng-class="{'console-cell-esito-selected' : collapsed}" class="console-cell-esito console-cell console-cell-no-border-sx">SHORT DESC</div>
<div ng-show="collapsed" class="console-cell-esito-long console-cell console-cell-no-border-sx">{{ roll.esito }}</divng-show></div>
</div>
This populates ng-repeat, and the ng-click shows/hides the `ng-show div.
So far so good(?).
What Ì'm trying to achieve, is to load json data into
<div ng-show="collapsed" class="console-cell-esito-long...
if
<div ng-click="collapsed=!collapsed" ng-class="{'console-cell...
is clicked.
That is each div of ng-repeat, can be loaded with specific data:
<ul>
<li ng-repeat="logelem in jsonlog">
{{ logelem.log }}
</li>
</ul>
I thought about using a function:
<div ng-click="function(id)...
and then load json into a div identified by an id, so i used $index...
The result was, being able to load same data into all divs at once :/
Help would be appreciated.
My suggestion woudl be to add the information to the jobs elements itself.
So for example, the ng-click would become:
<div ng-click="loadData(id, roll)">CLICK ME</div>
and then the loadData would be something like:
$scope.loadData = function(id, roll){
// Do something
roll.result = result;
}
and then you can use the result from that object in the view like you would do in other places. You can then for example hide the object where you want the final result until the variable result is defined.
I think this will be the easiest solution.
Update from comments
Why not change the collapsed value in the method? Or you could use a $watch to listen to changes on the collapsed variable.