i'm developing using ASP.Net mvc 4. I have a delete function in my Index view. Before user proceed to delete an item, this is the steps to go through
pop-up a confirm dialog to get the 'yes' or 'no' answer using javascript.
If the user say 'yes', I call the delete action from my controller
the delete action remove the item from database
the delete action return 'RedirectToAction ("Index");'
.. suppose the view will be updated with latest update
Step 5 is my problem.. its not working
Here is my code
The delete button
<a href="#Url.Action("DeleteFile", new { id = #item.Id })"
onclick = "return confirm2delete(this);"
class="btn btn-danger btn-sm"
data-toggle="tooltip" title="Delete File">
<i class="fa fa-trash-o"></i>
</a>
The javascript
function confirm2delete(obj)
{
deleteLinkObj = $(this);
w2confirm("Are sure to delete this file ?")
.yes(function () {
$.get(obj.href, function (data) {
alert(data); // i checked ..this return the html page created from the delete action
window.open (data); // not the right approach ???
});
})
.no(function () {
alert("no");
result = false;
});
return false;
}
The delete action in my controller
public ActionResult DeleteFile(int id)
{
FileUpload f = db.FileUploads.Find(id);
try
{
FileInfo dfile = new FileInfo(f.fileUrl);
if (dfile.Exists) { dfile.Delete(); }
fileUrl = f.FileUrl.Replace("Images/Uploads", "Images/Thumbnails");
FileInfo thumbnail= new FileInfo(fileUrl);
if (thumbnail.Exists) { thumbnail.Delete(); }
db.FileUploads.Remove(f);
db.SaveChanges();
}
catch (Exception ex)
{
}
return RedirectToAction("Index"); // or may i should return something else to make it work in javascript ???
}
Hope you guys can help me. I've been searching and trying for days to come to this level and I feel its time get some help. Just a little bit more. Almost there.
Ajax calls stay in the same page, so calling return RedirectToAction("Index"); is pointless (it will not redirect). In any case it is unnecessary to return the new view. Instead you can just remove the existing elements from the DOM if the controller successfully deleted the item. You have not shown your view, but assuming you have a table where a row might be something like
<tr>
<td>the name of the file</td>
<td>the delete link</td>
</td>
Then you can use the following where the 'delete' link is
<td><button type="button" class="delete" data-id="#item.Id">Delete</button></td>
The key points are the class and the data-id attributes - modify the rest to suit your display but remove the onclick attribute (stop polluting you markup with behavior and use unobtrusive javascript - its the 21st century!)
Then the script
var url = '#Url.Action("DeleteFile")';
$('.delete').click(function() {
var id = $(this).data('id');
var row = $(this).closest('tr'); // modify if the containing element is not a <tr>
w2confirm("Are sure to delete this file ?")
.yes(function () {
$.post(url, { id: id }, function(response) { // its a POST, not a GET!
if (response) {
row.remove(); // remove the row
} else {
// Oops, something went wrong
}
}).fail(function (response) {
// Oops, something went wrong
});
})
.no(function() {
alert("no");
});
});
Note if your using jquery version 1.9+ then the else block in the $.post() functuion is not required since return Json(null); in the method below will go to the .fail() callback
Then in the controller, return json to indicate the item was successfully deleted
[HttpPost]
public ActionResult DeleteFile(int id)
{
FileUpload f = db.FileUploads.Find(id);
try
{
....
db.SaveChanges();
return Json(true); // signal success
}
catch (Exception ex)
{
return Json(null); // signal failure
}
}
Related
I'm doing a spa with AngularJS and consuming an api with mvvm in C #.
I can delete a line after clicking the delete button, but on the server I want only to change a boolean flag to true by keeping the data in Sql Server.
I've tried other ways, and I was even deleting the object through Postman, but I do not want to delete but only change a Boolean property to the record that no longer exists in my view table.
I'll leave my code so it can be better understood.
Any help is welcome.
I have tried to pass the id and the object in api controller, similar to http.put, because I want to change a Boolean property, so I wanted to keep the id, name, last name, email and isdelete that after the click, changes to delete the line in the view becomes true in the database.
<tbody>
<tr ng-repeat="register in registers">
<td style="display:none">{{register.UserId}}</td>
<td>{{register.Name}}</td>
<td>{{register.LastName}}</td>
<td><input type="checkbox" ng-model="register.IsActive" disabled /></td>
<td>{{register.Email}}</td>
<td>
<a ng-click="editRegister($event, register)" class="glyphicon glyphicon-edit"></a>
</td>
<td>
</td>
</tr>
</tbody>
My controller.js:
$scope.deleteRegister = function (register) {
var index = -1;
var listOfRegister = eval($scope.registers);
for (var i = 0; i < listOfRegister.length; i++) {
if (listOfRegister[i].register === register) {
index = i;
break;
}
}
if (index === -1) {
alert("Something gone wrong");
}
$scope.registers.splice(index, 1);
$http({
method: 'Delete',
url: 'http://localhost:51734/api/UserAPI/',
}).then(function (res) {
alert('Exc');
$scope.GetAllRegisters();
})
};
And My controller.api:
[HttpPut]
[Route("api/UserAPI")]
public HttpResponseMessage Delete(UserViewModel uservm)
{
try
{
var registerDeleted = ctx.User.Find(uservm.UserId);
uservm.IsDelete = false;
uservm.IsActive = true;
if (registerDeleted != null)
{
uservm.IsActive = false;
uservm.IsDelete = true;
registerDeleted.Name = uservm.Name;
registerDeleted.LastName = uservm.LastName;
registerDeleted.IsActive = uservm.IsActive;
registerDeleted.Email = uservm.Email;
registerDeleted.IsDelete = uservm.IsDelete;
ctx.Entry(registerDeleted).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "User not found");
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
Thanks!
what you are talking about is soft deleting rows of data.
in the database add a new boolean field called Status or IsDeleted or whatever you fancy, with a default value of false.
When you hit the Delete button on the UI, issue a request to simply update that flag from false to true
When you request the list of things to show on the UI, oly return those where the flag is set to false.
This is basically the whole idea behind soft deleting data. You only mark the data is deleted, you don't actually delete it.
If you want, later on you can add a process where you move the soft deleted data to an archived table, just to keep things tidy. Doing things this way has the added benefit that you can always undelete the data, should you need to. All you need really is to change the flag back to false and you're done, everything works and the data gets displayed.
One final point from me, if you all you want to do is soft delete an item, then all you need is to pass the id of the record. you don't need to worry about changes to other fields. You wouldn't normally update information AND delete it at the same time. So create a simple controller which responds to PUT, for example:
[HttpPut]
[Route("api/UserAPI")]
public HttpResponseMessage Delete(int userId)
{
var foundUser = ctx.User.Find(userId);
foundUser.IsDeleted = true;
ctx.SaveChanges();
}
of course, add all your validation, return codes, everything you need, but this is essentially all you need.
Don't forget to change the method which returns the active users, to ignore those where the IsDeleted flag is true.
If the API is the issue you are setting uservm.IsDelete = false; then setting registerDeleted.IsDelete = uservm.IsDelete; therefore it would always be false in the database.
If the template is the issue i would recommend getting the index from the data-ng-repeat, this would reduce the amount of code you have written and make it easier to see what is going on.
This will remove the row from the table:
<tr data-ng-repeat="(index, register) in registers">
<td>
</td>
</tr>
$scope.deleteRegister = function (index) {
$scope.registers.splice(index, 1);
}
Update from comment:
You need to retrieve the object then make the change, and save it.
var registerDeleted = ctx.User.Find(uservm.UserId);
if (registerDeleted != null)
{
registerDeleted.IsDelete = true;
registerDeleted.IsActive = false
ctx.SaveChanges();
}
Now I already know how to delete a record from my View.index, which is with splice in my controller.js
$scope.deleteRegister = function (index) {
$scope.registers.splice(index, 1);
$http({
method: 'PUT',
url: 'http://localhost:51734/api/UserAPI/',
}).then(function (res) {
alert('Exc');
$scope.GetAllRegisters();
})
};
But I can not get it to communicate with my method in my controller.api, I want to change only the flag isDelete = true, after clicking the delete button on my UI.
My controller.api
//DELETE: api/UserAPI/5
[HttpPut]
[Route("api/UserAPI")]
public HttpResponseMessage Delete(int userId)
{
try
{
var foundUser = ctx.User.Find(userId);
if (foundUser != null)
{
foundUser.IsDelete = true;
ctx.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
}
And my view.index
<tr ng-repeat="(index, register) in registers">
<td>
</td>
</tr>
I am Trying To Update the status of Order In My App. When Page Refreshes and I try to Update it, It successfully Update. But When I try to Update Some Other Order, Update Method Return Success on OnComplete Method But Does Not Update Data On Real Time Database.
Its causing me headaches, I have Already Tried All Possible Solutions but nothing worked.
var dbRef = firebase.database();
var requestsRef = dbRef.ref('requests');
var onComplete = function (error) {
if (error) {
console.log('Synchronization failed');
} else {
console.log('Synchronization succeeded');
}
};
function sendToProcessing(e) {
var confirmation = confirm("Really Wanna Send To Processing?");
if (confirmation) {
var key = parseInt($(e).data("key"));
requestsRef.child(key).update({
'status': "Processing"
}, onComplete);
$('#orderDetailsModel').modal("hide")
} else {
return false;
}
}
HTML Part:
<button type="button" class="btn m-2 btn-outline-success " onclick="sendToProcessing(this)" id="btn-processing"><i class="fas fa-utensils"></i></button>
Image Display:
Image Model When Clicked On Eye Button
your are trying to retrieve key using $(e).data("Key"). And in your case e is the button element. The button element doesn't have any attribute called data-key.
Try adding your key to the button as below.
<button type="button" class="btn m-2 btn-outline-success " data-key="keyvalue "onclick="sendToProcessing(this)" id="btn-processing"><i class="fas fa-utensils"></i></button>
Also try debugging your sendToProcessing Method, and try to console.log(key) which might be a null.
I have a link in partial view, which is an easy list of items which I can open to edit/delete.
The link to delete has confirm
- when I press OK, everything is fine
- when I press cancel, it redirects it anyway but not even to the Delete controller's action but to the Detail.
EDIT
this one redirects to the DETAIL always => doesnt delete anything
Delete
this one redirects to detail only if pressed cancel => deletes when OK, doesnt work on cancel
#Html.ActionLink("Delete", "Delete", "Items", new { id = item.ItemID }, new { onclick = "return confirm('Are you sure to delete this item?')" })
I have tried it without the return false, putting to onclick return confirm(..), but nothing seems to work and if I press cancel I end up redirected to /Items/Detail/ID, which I completely dont understand and the delete method in the controller is not called.
controller - detail that is being called if I press cancel
[HttpGet]
public ActionResult Detail(int id)
{
TravelRequest model = DB.TravelRequests.Where(m => m.TravelRequestID == id).FirstOrDefault();
ViewBag.AttachmentFilePath = model.AttachmentFilePath;
SetDetailCommons(model);
return View("Create", model);
}
Delete which does not happen (which is OK because it shoult not be called if I press cancel...)
[HttpGet]
public ActionResult Delete(int id)
{
var model = DB.TravelRequests.Where(m => m.TravelRequestID == id).First();
DB.TravelRequests.Remove(DB.TravelRequests.Where(m => m.TravelRequestID == id).First());
DB.SaveChanges();
return RedirectToAction("Detail", "Assignment", new { id = model.AssignmentID });
}
Thank you for any suggestions :)
I'm pretty new to MVC and Javascript; I'm trying to make a delete action work; I'm using an ActionLink with a Javascript function for confirmation. The JAvascript confirm doesn't work, the delete action is fired even when I press Cancel; additionally, I cannot seem to be able to use [HttpDelete] verb for the action: I need to pass two parameters to the Delete action but after applying #Html.HttpMethodOverride(Http.Delete) on the action link it searches
for an URL with just one parmaeter: id.
Here is my code: action link
#Html.HttpMethodOverride(HttpVerbs.Delete)
#Html.ActionLink(
"Delete",
"Delete",
new {id=notification.Id, typeId=notification.TypeId},
new {onclick="confirmDeleteAction()"})
function confirmDeleteAction() {
return confirm('Are you sure you want to delete the notification ?');
}
Delete action:
[HttpDelete]
public ActionResult Delete(int id, int typeId)
{
Service.DeleteNotification(id, typeId);
NewIndexViewModel model = Service.GetNewIndexViewModel();
return View("Index", model);
}
Try this
#Html.ActionLink(
"Delete",
"Delete",
new {id=notification.Id, typeId=notification.TypeId},
new {onclick="return confirmDeleteAction();"})
You need to cancel the default behaviour of the browser when the user clicks cancel. You can do this by returning the result of confirmDeleteAction() to your <a> tag:
#Html.ActionLink(
"Delete",
"Delete",
new {id=notification.Id, typeId=notification.TypeId},
new {onclick="return confirmDeleteAction()"})
For clarity, I added the return keyword to your onclick handler which will return the result of confirmDeleteAction() to the browser -
true = perform the default behaviour of the link
false = do nothing
You can do this type by also.
#Html.ActionLink(
"Delete",
"Delete",
new {id=notification.Id, typeId=notification.TypeId},
new {onclick="confirmDeleteAction(" + notification.Id + ")" })
function OnDeleteClick(id) {
var ActionID = id;
var flag = confirm('Are you sure you want to delete this record?');
if (flag) {
return true;
}
else{
return false;
}
I have list page to show all images with its name from database in asp.net mvc list action (PhotoList - get).. in that view page (PhotoList.aspx), I have created checkbox to delete multiple rows. I want scenario like following
First page shows the list with in first column checkbox and in second column PhotoName and on the down page one button for delete selected rows .
when selects checkboxes and clicks the delete button, according to selection the rows will be deleted from database and return the same list page..
I don't understand where to write code for delete and how?
<% foreach (var item in Model) { %>
<tr>
<td>
<input type="checkbox" name="deleteImage" value="<%= item.PhotoId %>"/>
</td>
<td>
<%= Html.ActionLink("Edit", "Edit", new { id=item.PhotoId }) %>
</td>
<td>
<%= Html.Encode(item.PhotoName) %>
</td>
</tr>
<% } %>
<input type="button" name="Delete" value="Delete Selected items"/>
The Code for delete will be written in the HttpPost action for delete. Something like below should work if you are using myModel
[HttpPost]
public ActionResult Delete(myModel deleteEntries) //This is the post-version of your Action that rendered the view..If it's Edit, then change the name to Edit
{
var deleteList = db.deleteEntries.where(d => d.checkBox == true).ToList();
foreach (myList my in deleteList)
{
db.myList.Remove(my); // remember db should be your DbContext instace
}
db.SaveChanges();
}
UPDATE
You will first need to make a ViewModel because otherwise you cannot recognize which entries are checked for deletion with the help of checkbox.
Make a ViewMode class like following
using pratice3.Models;
public class MyPhotoViewModel
{
public UserManagementDbEntities.tblPhoto TablePhoto { get; set; }
public bool checkBox { get; set; }
}
Return this to your view
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PhotosList()
{
var viewModel = _datamodel.tblPhoto.Select(g => new MyPhotoViewModel
{
TablePhoto = g;
checkBox = false;
}).ToList();
return View(viewModel);
}
In View, change the using statement to reflect IEnumerable<MyPhotoViewModel> and make appropriate changes accordingly.
Then, define your Post Action like following
[HttpPost]
public ActionResult PhotosList(IEnumerable<MyPhotoViewModel> myPhotoList)
{
var deleteList = myPhotoList.where(d => d.checkBox == true).ToList();
foreach (var deletePhoto in deleteList)
{
_datamodel.tblPhoto.DeleteObject(deletePhoto.TablePhoto);
}
db.SaveChanges();
}
Using jQuery you can do this.
On button click get all the Ids of photos, something like this
var selected = new Array();
$('name="deleteImage" input:checked').each(function () {
selected.push($(this).attr('id')));
});
var selectedIds = selected.join(',');
Now on button click, make ajax call to some function on server side which will accept these ids and will delete from DB or so.
$.ajax({
url: '#Url.Action("DeleteRecord", "UserManage")',
data: 'ids=' + selectedIds + '&time=' + new Date(), //Date makes each call unique
success: function (data) {
//You can reload page
},
error: function (data) {
//You can show error
}
});
Hope this helps.