smart-table page not reset to 1 on collection refresh - angularjs

I have setup the smart-grid as per the documentation and everything is working fine. I am adding a new record in a modal dialog and on successful add of new record, I would like to refresh the smart-grid. I understand from the documentation that I just need to refresh the collection as I am using st-safe-src attrubute.
My issue is, Suppose, I am displaying 17 records and I am on page 2 now, and now I open the modal to add new record and close it after successfull addition, I am resetting the collection. But in this scenario, the page remains in page 2 only, and not getting reset to page 1. How to do that?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table st-table="displayedCollection" st-pipe="getMasterJobs" st-safe-src="rowCollection" class="table table-condensed table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th></th>
</tr>
</thead>
<tbody ng-show="!isDataLoading">
<tr ng-repeat="row in displayedCollection">
<td>{{row.name}}</td>
<td>{{row.description}}</td>
<td>
<button type="button" ng-click="editRow(row)" class="btn btn-xs btn-info">
<i class="fa fa-edit"></i> Edit
</button>
</td>
</tr>
</tbody>
<tbody ng-show="isDataLoading">
<tr>
<td colspan="3" class="text-center">Loading...</div>
</td>
</tr>
</tbody>
<tfoot ng-hide="isDataLoading">
<tr>
<td class="text-center" st-pagination="" st-items-by-page="10" st-displayed-pages="displayedPages" colspan="4"></td>
</tr>
</tfoot>
</table>
I have this in my controller.js file:
$scope.rowCollection = [];
$scope.isDataLoading = false;
//copy the references (you could clone ie angular.copy but then have to go through a dirty checking for the matches)
$scope.displayedCollection = [].concat($scope.rowCollection);
$scope.getMasterJobs = function(tableState) {
console.log(tableState);
var start = 0;
var length = 10;
var pagination = tableState.pagination;
start = pagination.start || 0; // This is NOT the page number, but the index of item in the list that you want to use to display the table.
length = pagination.number || 10; // Number of entries showed per page.
$scope.isDataLoading = true;
AdminJobMasterService.getMasterJobs(start, length).success(function(response, status, headers, config) {
$scope.rowCollection = response.data;
$scope.displayedCollection = [].concat($scope.rowCollection);
//set the number of pages so the pagination can update
tableState.pagination.numberOfPages = response.numberOfPages;
$scope.displayedPages = Math.ceil(response.numberOfPages / length);
$scope.isDataLoading = false;
}).error(function(data, status, headers, config) {
console.error(data);
$scope.isDataLoading = false;
});
};
Now, I call a different controller when I click the new/edit button and on click of close on the modal, I trigger the event and handle that event in the above controller. Please see that, I am resetting the collection observed by smart-table and also, tried initializing the tableState variable. Without tableState
variable, I cannot call getMasterJobs() as tableState.pagination will be null.
$scope.$on('new-job-added', function(event, data) {
$log.info("Time to refresh!");
$scope.rowCollection = [];
$scope.displayedCollection = [].concat($scope.rowCollection);
var tableState = {
sort: {},
search: {},
pagination: {
start: 0
}
};
$scope.getMasterJobs(tableState);
});

Related

Selecting default value using ngModel ngRepeat, ngOptions

Hopefully someone can help.
I am developing an application using HTML AngularJs which uses ng-repeat,ng-options and ng-model and populates multiple rows based on the data in the database for a user. Each row has static data coming from DB (returned as object via restAPI) and dynamic select option for user selection. Select option is hardcoded in app.js and linked to model on HTML for DB update upon selection using update button. Each row has its own button and i can see update function is working at row level.
I want to set the default value of the drop down list dynamically as value of an element coming from database. Object is same as one being used to populate rows with static data .
Code is in the fiddle at https://jsfiddle.net/6j88L61y/4/
HTML below
<body>
<h1 align="center">User Tracker</h1>
<div ng-controller="MainController as main">
<div>
<p>Please Enter ID </p>
<p>
<input type="text" ng-model="main.model.userName"></input>
<button ng-click="main.model.getOrgList()">List State List</button>
</p>
</div>
<hr ng-show="main.model.formSubmitted"></hr>
<div>
<table class="table table-bordered" border="1">
<thead>
<tr>
<th>ID</th>
<th>User Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="org in main.model.orgList" id="{{org.id}}">
<td>{{org.id}}</td>
<td align="center">{{org.user}}</td>
<td align="center">
<select ng-model="main.model.selectedRecord.appCurrentStateSelected[$index]" ng-options="option.value as option.value for option in main.model.appCurrentStateList" ></select>
</td>
<td>
<button ng-click="main.model.updateAppDetailsList({id:org.id,userName:org.name,appCrntState:main.model.selectedRecord.appCurrentStateSelected})">Update</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
JS
"use strict";
angular.module('myApp',[]);
angular.module('myApp').service('AppModel', function( $http) {
this.userId='';
this.userName ="";
this.formSubmitted="";
this. selectedRecord ={appCurrentStateSelected:''};
this.appCurrentStateList =[{name: 'New',value:'New',id:1}, {name: 'InUse',value:'InUse',id:2},{name: 'Inactive',value:'Inactive',id:3},{name: 'Deleted',value:'Deleted',id:4}];
this.submittedAppDetailsList=[];
console.log(' json sample:'+this.submittedAppDetailsList);
var path = 'home';
var currentProtocol = location.protocol;
var host =location.host;
var apiHost = currentProtocol+'//'+host+'/api/';
console.log('API url is : ' +apiHost);
// Get method
this.getOrgList = function() {
var path = 'home/userid';
console.log(this.userName);
console.log(this.selectedRecord);
$http.get(apiHost+path+'/'+this.userName+'/')
.then(function(response) {
this.orgList =response.data;
this.formSubmitted = true;
console.log(response.data);
}.bind(this),
function(response) {
console.log(response.data);
});
}
// Post method
this.updateAppDetailsList = function(appdetailsList) {
var path = 'home/update';
console.log(this.selectedRecord);
$http.post(apiHost+'home/update/',appdetailsList)
.then(function(response) {
this.submittedAppDetailsList.push(response.data);
this.formSubmitted = false;
console.log(response.data);
}.bind(this),
function(response) {
console.log('Error : '+response.data);
});
}
});
angular.module('myApp').controller('MainController', ['AppModel', function (AppModel) {
this.model = AppModel;
}]);

Count clicks and add to input

First of all I am very new in Angular JS.
I have a list of items and by clicking on each one, it should be added to the table. The items are stored in a json file.
If the click event repeated several times the counter input which is located on the table must increases.
<ul class="list-inline" >
<li ng-repeat="food in foods" class="food_list">
<img class="img-box" src="images/{{ food.food_photo }}" ng-click = 'addRow(food)'><br/><span>{{food.food_name}}</span>
</li>
</ul>
<table class="table" id="table-right">
<tr>
<th>Item Name</th>
<th>Quantity</th>
<th>Price</th>
<th class="hidden-print">Delete</th>
</tr>
<tr ng-repeat="row in rows">
<td>{{row.food_name}}</td>
<td><input type="number" class="form-control" ng-model="row.food_count"></td>
<td>{{row.food_cost}}</td>
<td class="hidden-print"><button class="btn btn-info hidden-print" data-ng-click="removeRow($index)">Remove</button></td>
</tr>
app = angular.module('app',[]);
app.controller('MyCtrl', ['$scope','$http', function($scope, $http){
$scope.rows = [];
$scope.addRow = function(obj) {
$scope.foodname = obj.id;
$scope.foodprice = obj.price;
$scope.rows.push(obj);
$scope.counter++;
}
}]);
Could you please help me? Thank You.
First you have to understand that food_count property of a row object is the variable that should be updated on repetitive clicks. Updating any other $scope variables won't change row specific data because your view is bound to $scope.rows object.
Your addRow function should look like this.
$scope.addRow = function(obj) {
if($scope.rows.indexOf(obj) >= 0){ // if this obj already exist
$scope.rows[$scope.rows.indexOf(obj)].food_count++;
}
else
$scope.rows.push(obj);
}
Then the objects of $scope.foods should have a property called food_count to display.
$scope.foods = [
{food_name:'Jani',food_cost:'10', food_count:0},
{food_name:'Hege',food_cost:'8',food_count:0},
{food_name:'Kai',food_cost:'5',food_count:0}]
solution

loading or progress screen appear on click event

I want when click on switchery button the loading screen appear or modal and this loading screen or modal will dismiss only when http request completed and get all data.In short when click on switch then user cannot perform any action and cannot click on other buttons.so how can i do this.I'm using angular with laravel 5.2
<div class="table-responsive">
<table class="table table-hover ">
<thead>
<tr>
<th>Device Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="device in devices">
<td>[[device.device_name]]</td>
<td>
<switch id="enabled" name="enabled" on="ON" off="OFF"
ng-init="enabled=device.status" ng-model="enabled" class="green "
ng-change="changeStatus([[device.device_id]],[[device.user_id]],enabled)"
></switch>
</td>
</tr>
</tbody>
</table>
</div><!-- /.table-responsive -->
Angular file
myapp.controller('AutomationController',function(dataFactory,$scope){
$scope.devices;
$scope.userId=null;
loadDevices();
function loadDevices()
{
dataFactory.httpRequest('/user_devices').then(function (data) {
console.log(data);
$scope.devices=data;
})
}
$scope.changeStatus=function($device_id,$user_id,$status){
if($status)
{
$status=1;
}
else {
$status=0;
}
dataFactory.httpRequest('/device_status/'+$device_id,'PUT',{},
{"user_id":$scope.userId,
"status":$status
}).then(function(data) {
});
}
});
Before making your $http request, set $scope.loading = true; and in your promise's finally(function(){}); set $scope.loading = false;
In your HTML template, add something like <div class="modal loading" ng-if="loading">Loading...</div>. Use CSS to make it take up whole screen and have higher z-index so it blocks clicks on the rest of UI.

AngularJS - Not update table-pagination after http-get success's event

i have a problem. I'm using AngularJs with WebService-Rest, and can't update some table after the call HTTP-GET to WebService. I did tested everything but i can't get it.
Next, i attach the code. Thanks!
HTML:
...
<div class="row" ng-app="SIGA" ng-controller="CreateTable">
<div class="container-fluid">
<table class="table table-striped">
<tbody>
<tr>
<td>Buscar</td>
<td><input type="text" ng-model="search.nombre" /></td>
</tr>
<tr ng-repeat="e in estaciones | filter:paginate| filter:search" ng-class-odd="'odd'">
<td>
<button class="btn">
Detalle
</button>
</td>
<td>{{e.nombre}}</td>
</tr>
</tbody>
</table>
<pagination total-items="totalItems" ng-model="currentPage"
max-size="5" boundary-links="true"
items-per-page="numPerPage" class="pagination-sm">
</pagination>
</div>
</div>
...
JS: ...
app.controller('RestEstacion', function ($rootScope, $http) {
$http.get('http://localhost:8080/sigarest/webresources/entity.estaciones').
success(function(data) {
$rootScope.estaciones = data; UpdateTable($rootScope);
}).
error(function(status) {
alert('error:'+status);
});
});
app.controller('CreateTable', function ($scope,$rootScope) {
$rootScope.predicate = 'nombre';
$rootScope.reverse = true;
$rootScope.currentPage = 1;
$rootScope.order = function (predicate) {
$rootScope.reverse = ($rootScope.predicate === predicate) ? !$rootScope.reverse : false;
$rootScope.predicate = predicate;
};
$rootScope.estaciones = [];
$rootScope.totalItems = $rootScope.estaciones.length;
$rootScope.numPerPage = 5;
$rootScope.paginate = function (value) {
var begin, end, index;
begin = ($rootScope.currentPage - 1) * $rootScope.numPerPage;
end = begin + $rootScope.numPerPage;
index = $rootScope.estaciones.indexOf(value);
return (begin <= index && index < end);
};
});
JS (Update Function):
function UpdateTable($rootScope){
$rootScope.totalItems = $rootScope.estaciones.length;}
** Original Answer (what comments refer to) **
I think you are assigning the get response object rather than the data inside it. Try this:
success(function(response) {
$rootScope.estaciones = response.data;
UpdateTable($rootScope);
}).
** EDIT **
Now that we have established that you are returning data from the API, the real issue appears to be the double controller using $rootScope as a bridge, which can work but is a bit of an anti-pattern in Angular.
The first controller in your app is trying to act like a service, and so really needs to be converted into one. Here is some SAMPLE PSUEDO CODE to give the idea. I do not fully understand your code, like the pagination directive. There should be a click handler in the pagination directive that would call the service method changePagination and pass in the new page number. There should be no need for $rootScope anywhere in this.
JS
app.service('RestEstacionService', function ($http) {
var RestEstacionService = this;
this.apiData = null;
this.tableData = null;
this.currentPage = 1;
this.numPerPage = 5;
this.url = 'http://localhost:8080/sigarest/webresources/entity.estaciones';
this.getData = function (url) {
return $http.get(url).then(function(response) {
RestEstacionService.apiData = response.data;
// do success stuff here
// figure out which page the view should display
// assign a portion of the api data to the tableData variable
})
};
this.changePagination = function (newPage) {
// do your your pagination work here
};
});
app.controller('RestEstacionController', ['$scope', 'RestEstacionService', function ($scope, RestEstacionService) {
$scope.service = RestEstacionService;
RestEstacionService.getData(RestEstacionService.url);
}]);
HTML
<div class="row" ng-app="SIGA" ng-controller="RestEstacionController">
<div class="container-fluid">
<table class="table table-striped">
<tbody>
<tr>
<td>Buscar</td>
<td><input type="text" ng-model="search.nombre" /></td>
</tr>
<tr ng-repeat="row in services.tableData | filter:paginate| filter:search" ng-class-odd="'odd'">
<td>
<button class="btn">
Detalle
</button>
</td>
<td>{{row.nombre}}</td>
</tr>
</tbody>
</table>
<pagination total-items="services.apiData.length" ng-model="services.currentPage"
max-size="5" boundary-links="true"
items-per-page="services.numPerPage" class="pagination-sm">
</pagination>
</div>

Populate and update a table with data from a different table

My site allows for a user to search for a term which returns a table of associated songs. When the "Add Track" button in a particular row is clicked after the search, the respective track name and trackId are added to the table "playlist". The problem I am having is that once "Add Track" is clicked within a different row, the data from that row is not added to the "playlist" table, but rather it just replaces the previous information. I need to be able to generate a cumulative table. Any help would be great and thanks in advance!
<body ng-app>
<body ng-app>
<div ng-controller="iTunesController">
{{ error }}
<form name="search" ng-submit="searchiTunes(artist)">
<input type="search" required placeholder="Artist or Song" ng-model="artist"/>
<input type="submit" value="Search"/>
</form>
<div class="element"></div>
<table id="SongInfo" ng-show="songs">
<thead>
<tr>
<th>Album Artwork</th>
<th>Track</th>
<th></th>
<th>Track Id</th>
<th>Preview</th>
<th>Track Info</th>
<th>Track Price</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="song in songs">
<td><img ng-src="{{song.artworkUrl60}}"
alt="{{song.collectionName}}"/>
</td>
<td>{{song.trackName}}</td>
<td><button ng-click="handleAdd(song)">Add Track</button></td>
<td>{{song.trackId}}</td>
<td>Play</td>
<td>View Track Info</td>
<td>{{song.trackPrice}}</td>
</tr>
</tbody>
</table>
<table id="playlist">
<thead>
<tr>
<th>Playlist</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="song in addedtracks">
<td>{{song.trackName}}</td>
<td>{{song.trackId}}</td>
</tr>
</tbody>
</table>
</div>
</body>
itunes_controller.js
var iTunesController = function($scope, $http){
$scope.searchiTunes = function(artist){
$http.jsonp('http://itunes.apple.com/search', {
params: {
'callback': 'JSON_CALLBACK',
'term': artist,
limit: 5,
}
}).then(onSearchComplete, onError)
}
$scope.handleAdd = function(song) {
// this song object has all the data you need
console.log("handle add ", song)
$scope.addedtracks = [{song:'trackName', song:'trackID'}]
$scope.addedtracks.push(song)
}
var onSearchComplete = function(response){
$scope.data = response.data
$scope.songs = response.data.results
}
var onError = function(reason){
$scope.error = reason
}
}
I saw some issues with your code. First the code below
$scope.addedtracks = [{song:'trackName', song:'trackID'}]
$scope.addedtracks.push(song)
Acording to your html, you are passing the song object to the handleAdd. So just remove the first line from code above. After that step, declare addedtracks array before handleAdd like below
$scope.addedtracks = [];
Modify the ng-repeat for the playlist like below:
<tr ng-repeat="song in addedtracks track by $index">
<td>{{song.trackName}}</td>
<td>{{song.trackId}}</td>
</tr>
And that's it. Note that I used track by $index because ngRepeat does not allow duplicate items in arrays. For more information read Tracking and Duplicates section.
Finally this is working plunker

Resources