I am trying to change a row in my database when the user clicks the delete button in my angular ui-grid. When the button is clicked, the row should be removed from the grid, and the table in the database should be updated with a value so that the row will no longer appear in the grid, but it will still be in the database (soft-delete). My table is called applicants and has rows id, firstname, lastname, email, position, resume, and deleted. Deleted is a boolean column defaulted to false, if true, the row should not appear in my ui-grid. I have this portion completed, however I cannot get my code to update the deleted column in the database when the button is pressed on the grid. This is the controller for the grid (gets the applicants from the database):
angular.module('myApp')
.controller('gridController',['$scope','$http','$log',function ($scope, $http,$log){
$scope.deleteRow = function(row) {
var index = $scope.gridOptions.data.indexOf(row.entity);
$scope.gridOptions.data.splice(index, 1);
$http({
method:'POST',
url:'/directives/updateApplicant'
})
}
$scope.gridOptions = {
enableFiltering:true,
columnDefs: [
{name: 'id', field:'id'},
{name:'firstName',field:'firstName'},
{name:'lastName',field:'lastName'},
{name:'email',field:'email'},
{name:'position',field:'position'},
{name:'resume', field:'resumeFileName', cellTemplate:'<div class="ui-grid-cell-contents">{{ COL_FIELD }}</div>'},
{name:'delete',cellTemplate: '<button class="btn primary" ng-click="grid.appScope.deleteRow(row)">Delete</button>', enableFiltering:false}
]
}
$scope.data = []
$http({
method:'GET',
url:'/directives/applicants'
}).then(function(success){
$scope.gridOptions.data = success.data;
},function(reason){
$scope.error = reason.data;
$log.info(reason);
})
}])
when it hits the post route this code runs:
module.exports.updateApplicant = function(req,res){
applicant.forge({id: '31'})
.fetch({require:true})
.then(function(applicant){
applicant.save({
deleted:'true'
})
.then(function(){
res.json({error:false,data:{message:'applicant details updated'}})
})
.catch(function(err){
res.status(500).json({error:true, data:{message: err.message}})
});
})
.catch(function(err){
res.status(500).json({error:true,data:{message:err.message}})
})
}
this works just fine the only problem is that i have the ID hardcoded. Is there a way i can pass the ID from the selected row in the grid to this variable?
Send http request when you click button
$scope.deleteRow = function(row) {
var index = $scope.gridOptions.data.indexOf(row.entity);
$scope.gridOptions.data.splice(index, 1);
$http({
method:'POST',
url:'/directives/updateApplicant',
data: $scope.gridOptions.data[index],
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
console.log("success");
}).error(function (data, status, headers, config) {
console.log(status);
})
}
you need install body-parser and use it as middleware (app.use(bodyParser.urlencoded({ extended: false })) to get the POST body.
module.exports.updateApplicant = function(req,res){
var bid = req.body.id;
applicant.forge({id: bid})
.fetch({require:true})
.then(function(applicant){
applicant.save({
deleted:'true'
})
.then(function(){
res.json({error:false,data:{message:'applicant details updated'}})
})
.catch(function(err){
res.status(500).json({error:true, data:{message: err.message}})
});
})
.catch(function(err){
res.status(500).json({error:true,data:{message:err.message}})
})
}
Related
I want to instantly showing new data after http request without reloading the whole page. I found that I can use $apply from angularjs for this. But I'm stucked. The data is not showing instantly.
This is the code in controller.
$scope.reload = function(data){
$timeout(function () {
$scope.$apply(function () {
console.log(data);
$scope.data = data;
});
});
};
// This part is not working
$scope.addMilestone = function (){
$http({
url: httpUrl + 'api/milestone/add',
method: 'post',
data: $.param($scope.formData),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function (result) {
$scope.data = result.data;
$scope.reload($scope.data);
});
};
// This part is working
$scope.deleteMilestone = function(id){
$http.get(httpUrl + 'api/milestone/delete?id=' + rowid).then(function(result){
if (result.data === 'OK'){
$http.get(httpUrl + 'api/carts/content').then(function (returns) {
$scope.data = returns.data;
$scope.reload($scope.data);
});
}
});
};
What confused me is that this method is working for deleting data, but it's not for inserting new data. In $scope.deleteMilestone, the data deleted is removed from the view instantly. I want it also work for $scope.addMilestone
Try like this for the part you have written it is not working.
$scope.addMilestone = function (){
$http.post('api/milestone/add', $scope.formData, {'Content-Type': 'application/x-www-form-urlencoded'})
.then(function (result) {
$scope.data = result.data;
$scope.reload($scope.data);
});};
Your delete is working because, you called get api after your delete, but for add you didnt make that API call, so data isnt being reloaded for you.
Change your add milestone method to,
$scope.addMilestone = function (){
$http({
url: httpUrl + 'api/milestone/add',
method: 'post',
data: $.param($scope.formData),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function (result) {
if (result){
$http.get(httpUrl + 'api/carts/content').then(function (returns) {
$scope.data = returns.data;
$scope.reload($scope.data);
});
}
});
};
how to keep open edit mode if server response with error?
Now, when I click submit and send data to API, my form automatically is close, but I want to close edit mode only if server response with success, and stay opened if a response with an error. Thank you
<form editable-form name="tableform" onaftersave="saveTableConfig()" oncancel="cancel()">
<span editable-textarea="currentKlupa.description" e-name="description" e-
rows="3">Text</span>
</form>
$scope.saveTableConfig = function () {
var config = {
headers: {
'Content-Type': 'application/xml',
'X-HTTP-Method-Override': 'PUT'
}
};
var configCopy = angular.copy($scope.currentConfig);
$http.post(serviceBase + 'cd/saa/' + $stateParams.aaaID + '/config', configCopy, config)
.success(function (data, status, headers, config) {
Notification.success({message: $filter('translate')('BENCH_EDITED_SUCCESSFULLY'), delay: 3000, positionY: 'bottom', positionX: 'right'});
})
.error(function (data, status, header, config) {
Notification.error({message: $filter('translate')('BENCH_EDITED_ERROR'), positionY: 'bottom', positionX: 'right'});
});
};
I fix this if someone need help with this.
Thnx to #ckosloski (github).
You need to return a string value in your onaftersave method:
If you need to send data on server after writing to local model then you should define form's onaftersave.
The result of form's onaftersave is also important for next step:
string: form will not close (e.g. server error)
not string: form will be closed
This is my ctrl
$scope.saveTableConfig = function () {
var config = {
headers: {
'Content-Type': 'application/xml',
'X-HTTP-Method-Override': 'PUT'
}
};
var configA = angular.copy($scope.currentConfig);
return $http.post(serviceBase + 'nnnn/config', configA, config)
.then(function (response) {
//your code
})
.catch(function (error) {
//your code
return 'return string';
});
};
I have an ng-repeat of employees. One of the result fields returned is an employee number e.g. "12345".
How can I perform an ajax lookup and replace the employee number with the corresponding name?
Example: /_api/web/lists/getByTitle('allStaff')/items?$select=fullName&$filter=userid eq '12345'
would return: "Doe, John".
I've tried using a filter but nothing ever gets displayed even though I can see results returned.
<div ng-repeat="emp in employees"">
<i class="fa fa-user"></i> {{emp.id}}
</div>
app.filter('getName', function($http) {
return function(id){
if (id) {
var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('allStaff')/items?$select=fullName&$filter=userid eq '"+id+"'";
$http({
method: 'GET',
url: url,
cache: true,
headers: { "Accept": "application/json;odata=verbose" }
}).success(function (data, status, headers, config) {
userInfo = data.d.results[0].pn;
console.log(userInfo);
}).error(function (data, status, headers, config) {
userInfo = "0";
});
return userInfo;
}
};
});
The filter function is synchronous, while the $http call is asynchronous. The success callback isn't even going to be executed until after the filter function has already returned, so it looks like the return value will be undefined.
An angular filter isn't really appropriate for loading data from an API, and there's an easier approach. Add userInfo to the employees array in the appropriate service/factory/controller (that's up to how you're organizing your code, but the controller where you set $scope.employees is the quick and dirty option). Something like a forEach through the array making an API call for each one and setting employee.userInfo in the success callback:
app.controller('EmployeeController', function($scope, $http) {
// $scope.employees is initialized somehow
$scope.employees.forEach(function (employee) {
if (employee.id) {
var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('allStaff')/items?$select=fullName&$filter=userid eq '"+employee.id+"'";
$http({
method: 'GET',
url: url,
cache: true,
headers: { "Accept": "application/json;odata=verbose" }
}).success(function (data) {
employee.userInfo = data.d.results[0].pn;
}).error(function () {
employee.userInfo = "0";
});
}
});
});
And in your template:
<div ng-repeat="emp in employees">
<i class="fa fa-user"></i> {{emp.userInfo}}
</div>
It's up to you to figure out what to do before the ajax request is finished, while emp.userInfo is undefined - hide the element, show a placeholder, etc.
I am stuck with this problem:
I'm trying to delete a row from a table by passing the ID of that row (i.e. record) into the path of my API. Unfortunately it isn't recognized. However, when I replace $scope.ID with a hardcoded ID-number, all is working as expected.
This is my code:
Controller:
$scope.go = function(record) {
$scope.ID = record.ID;
}
$scope.deleteRow = function() {
$http.delete("api.php/bml/"+$scope.ID)
.success(function(data, status, headers, config){
console.log('successfully deleted ID: ' + $scope.ID);
})
};
Of course in my HTML I have a TR tag with ng-click="go(record) in it.
Strange enough the right ID number is showing up in the console.log message!
Use like this
$scope.deleteRow = function(ID) {
$http.delete("api.php/bml/"+ID)
.success(function(data, status, headers, config){
console.log('successfully deleted ID: ' + ID);
})
};
EDIT:
<button ng-click="deleteRow(id)">Delete</button>
I want to bind dropdowns in edit mode but with value selected according to each record
My Edit View
<select ng-model="user.StateId" ng-init="user.StateId=#Model.StateId" data-ng-options="s.Id as s.State for s in States " data-ngchange="GetCities()"></select>
<select ng-model="user.CityId" data-ng-options="c.Id as c.City for c in Cities " ></select>
My Angular Js
function GetStates() {
$http({
method: 'Get',
url: '/Home/GetStates'
}).success(function (data, status, headers, config) {
$scope.States = data;
}).error(function (data, status, headers, config) {
$scope.message = 'Unexpected Error';
});
}
$scope.GetCities = function (obj) {
var stateId = $scope.user.StateId;
alert(stateId);
if (stateId) {
$http({
method: 'POST',
url: '/Home/GetCities/',
data: JSON.stringify({ stateId: stateId })
}).success(function (data, status, headers, config) {
$scope.Cities = data;
}).error(function (data, status, headers, config) {
$scope.message = 'Unexpected Error';
});
}
else {
$scope.states = null;
}
}
$scope.edit = function (user) {
var ref = user;
$http
({
method: 'GET',
dataType: 'html',
url: location.href = '../Home/Edit?Id=' + ref.Id,
})
}
Now when user click on edit i want to open user details in edit mode and i m doing so using $scope.edit user is my object in which i m getting data to edit now i want dropdown of edit view to show state and city selected as per the state and city i got as a response in function(user)