I have a small problem in my code.. I'm trying to delete a row from database, but without using DataTables (in asp.net mvc) and it doesnt work. I've displayed every item from the database on a page in div's.. It looks like this
Index:
Default Edit/Delete buttons
<input type="button" value="Edit" class="btn btn-warning btn-sm mt-auto" onclick="location.href='#Url.Action("Edit", "Products", new { id = item.Id })'" />
<input type="button" value="Delete" class="btn btn-danger btn-sm mt-auto" onclick="location.href='#Url.Action("Delete", "Products", new { id = item.Id })'" />
with default button I would have to go to the Delete View and press Delete again,and I dont want that.. thats why I'm using Bootbox with Ajax
So I deleted that Delete button and added this:
<button data-product-id="#item.Id" class="btn btn-danger btn-sm mt-auto js-delete">Delete</button>
This is my controller
// GET: Products/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
// POST: Products/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Product product = db.Products.Find(id);
db.Products.Remove(product);
db.SaveChanges();
return RedirectToAction("Index");
}
and this is my script that I'm using
$(document).ready(function () {
$(".products-panel .js-delete").on("click", function () {
var button = $(this);
bootbox.confirm("Do you want to delete this product", function (result) {
if (result) {
$.ajax({
url: "/Products/Delete/" + button.attr("data-product-id"),
method: "GET",
success: function () {
$(button).parent().parent().remove();
},
error: function (err) {
console.log(err);
}
});
}
});
});
});
Currently it only removes the div of that item until you refresh the page.. (it doesnt remove it from the database).. Is there any way that I can fix this
If someone needs more photo's I can provide them..
I fixed the problem, I just had to remove the GET Delete action from the Controller and Change the name on the Post method from DeleteConfirmed to Delete
Previous:
// GET: Products/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
// POST: Products/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Product product = db.Products.Find(id);
db.Products.Remove(product);
db.SaveChanges();
return RedirectToAction("Index");
}
Working:
// POST: Products/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
Product product = db.Products.Find(id);
db.Products.Remove(product);
db.SaveChanges();
return RedirectToAction("Index");
}
Thanks for the people that tried to help
Related
Shopping cart with many items how to remove any item asynchronously with JavaScript this is my work so far. Can anyone improve on this?
your help would be greatly appreciated. Have a great day
Ok so this works if you remove items from the top of the list but fails if you remove items from some other place.
The problem seems to be that the form names are all the same "remove" without any indexing.
Problem is I'm not sure how to proceed with this.
document.forms['remove'].onsubmit = () => {
let formData = new FormData(document.forms['remove']);
fetch('/sales/cart?handler=RemoveItem', {
method: 'post',
body: new URLSearchParams(formData)
})
.then(() => {
var url = "/sales/cart?handler=CartPartial";
console.log(url)
$.ajax({
url: url,
success: function (data) {
$("#exampleModal .modal-dialog").html(data);
$("#exampleModal").modal("show");
//alert('Posted using Fetch');
}
});
});
return false;
}
<pre>
#foreach (var item in Model.Items)
{
<form name="remove" method="post">
<h4 class="text-left text-body">#item.Price.ToString("c")
<button class="btn btn-sm" title="Trash"><i style="font-size:large"
class="text-warning icon-Trash"></i></button>
</h4>
<input type="hidden" asp-for="#Model.Id" name="cartId" />
<input type="hidden" asp-for="#item.Id" name="cartItemId" />
</form>
}
</pre>
Update
----------
New markup
I added an index to the id and included an onclick event.
<form method="post" id="#i" onclick="removeItem(this.id)">
<button class="btn btn-sm" title="Trash">Item One</button>
<input type="hidden" asp-for="#Model.Id" name="cartId" />
<input type="hidden" asp-for="#item.Id" name="cartItemId" />
</form>
and create a new function that captured the form id including it in a constant.
<script>
function removeItem(formId) {
const form = document.getElementById(formId);
form.onsubmit = () => {
let formData = new FormData(form);
fetch('/sales/cart?handler=RemoveItem', {
method: 'post',
body: new URLSearchParams(formData)
})
.then(() => {
var url = "/sales/cart?handler=CartPartial";
console.log(url)
$.ajax({
url: url,
success: function (data) {
$("#exampleModal .modal-dialog").html(data);
$("#exampleModal").modal("show");
//alert('Posted using Fetch');
}
});
});
return false;
}
}
</script>
If anybody can improve on this please post it here.
Thanks.
Updates code behind Cart.cshtml.cs
using System;
using System.Threading.Tasks;
using Malawby.Models;
using Malawby.Services.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Malawby.Pages.Sales
{
public class CartModel : PageModel
{
private readonly ICartRepository _cartRepository;
public CartModel(ICartRepository cartRepository)
{
_cartRepository = cartRepository ?? throw new
ArgumentNullException(nameof(cartRepository));
}
[BindProperty]
public Cart Cart { get; set; } = new Cart();
public const string SessionKeyName = "_Name";
public string SessionInfo_Name { get; private set; }
public void OnGetAsync()
{
}
public async Task<PartialViewResult> OnGetCartPartialAsync()
{
var userName = GetUserName();
if (userName != null)
{
Cart = await _cartRepository.GetCartByUserName(userName);
}
return Partial("_ToCart", model: Cart);
}
private string GetUserName()
{
return HttpContext.Session.GetString(SessionKeyName);
}
public async Task OnPostRemoveItemAsync(int cartId, int cartItemId)
{
await _cartRepository.RemoveItem(cartId, cartItemId);
}
}
}
Update 2
This is the modified code I used. This is the error in the console.
XML Parsing Error: no root element found Location: localhost:44331/sales/cart?handler=RemoveItem Line Number 1, Column 1
There is no error on the page just nothing happens on the click of the trash can.
<script type="text/javascript">
function removeItem(cartItemId, cardId) {
var removeUrl = "/sales/cart?handler=RemoveItem";
$.post(removeUrl,
{
cartItemId: cartItemId,
cardId: cardId
})
.done(function (data) {
alert(data); //usually return true or false if true
remove card
$('#card_' + cardId).remove();
});
}
</script>
I am not familiar with asp.net core, but I will show how I usually do it without focusing on syntax.
first on the view no need to add multiple form but should use card id as index and delete button sent selected index like this:
#foreach (var item in Model.Items)
{
<div id="card_#item.cardId">
<h4 class="text-left text-body">#item.Price.ToString("c")
<button class="btn btn-sm" onclick="removeItem('#item.cardId') title="Trash"><i style="font-size:large"
class="text-warning icon-Trash"></i></button>
</h4>
</div>
}
then the script function will call remove api and remove selected card with no need to re-render the page:
<script type="text/javascript">
function removeItem(cardId) {
var removeUrl = "your apiUrl";
$.post( "removeUrl", { cardId: cardId })
.done(function( data ) {
alert( data ); //usually return true or false if true remove card
$('#card_'+ cardId).remove();
});
}
</script>
I'm trying to remove or hide items from a list and I'm facing two problems, 1- the newly cannot be removed, 2- Tried to tag the deleted items as isDeleted = true using Javascript then later delete them in the controller following this answer https://stackoverflow.com/a/40572625/10773318 but it didn't work.
Here's my view models
public class CreateEditParentViewModel
{
public int Id { get; set; }
public IList<ChildViewModel> ChildrenLists { get; set; }
}
public class ChildViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool isDeleted { get; set; }
}
In the main view
<div id="editorRows">
#foreach (var item in Model.ChildrenLists)
{
<partial name="_RowPartial" model="item" />
}
</div>
<a id="addItem" asp-action="BlankRow" asp-controller="Home">Add Row...</a> <br />
<input type="submit" value="Finished" />
The javascript in the main view
#section scripts {
<script>
$("#addItem").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editorRows").append(html); }
});
return false;
});
$("a.deleteRow").click(function () {
$(this).parents("div.editorRow:first").remove(); //does not work with newly added
return false;
}); //what it should do: hide and set isDeleted = true if id is not null - remove if null
</script>
Finally the partial view
<div class="editorRow">
#using (Html.BeginCollectionItem("ChildrenLists"))
{
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.isDeleted)
<span>Name: </span> #Html.EditorFor(m => m.Name);
}
delete
1- the newly cannot be removed
You can manually bind click event handler for the new generated <a href="#" class="deleteRow"> element, like below.
success: function (html) {
$("#editorRows").append(html);
$("a.deleteRow").bind("click", function () {
//...
//code logic here
});
}
2- Tried to tag the deleted items as isDeleted = true using Javascript
To achieve the requirement, you can refer to the following code snippet.
<script>
$("#addItem").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) {
$("#editorRows").append(html);
$("a.deleteRow").bind("click", function () {
del_row($(this));
});
}
});
return false;
});
$("a.deleteRow").click(function () {
del_row($(this));
return false;
});
function del_row(el) {
console.log("del");
console.log($(el).siblings("input[id$='__Id']").val());
var childitem_id = $(el).siblings("input[id$='__Id']").val();
if (childitem_id == 0 || childitem_id == "") {
$(el).parent("div.editorRow").remove();
} else {
$(el).siblings("input[id$='__isDeleted']").val("true");
$(el).parent("div.editorRow").hide();
}
return false;
}
</script>
Test Result
When I am saving my data for the first time (when clicked on save button of my view) then I am getting value of submitButton variable in my controller action. But when I am editing my view and then click on save then I am getting null value in submitButton variable in my controller action.
My View Model
public class TermiViewModel : ViewModelBase
{
public long Id { get; set; }
public string Name { get; set; }
}
My View
#model TermiViewModel
#using (Html.BeginForm("MyActionMethod", "MyController", FormMethod.Post))
{
#Html.HiddenFor(model => model.Id)
<div>
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
</div>
<button name="submitButton" value="Save" type="submit"
onclick="return JavaScriptFunction();">Save</button>
<button name="submitButton" value="Cancel" type="submit"
onclick="return JavaScriptFunction();">Cancel</button>
}
Below is the Javascript I am using in my view.
<script language="javascript" type="text/javascript">
function JavaScriptFunction() {
return true;
}
</script>
Below is my Controller class.
public class MyController : CoreMvcController
{
private readonly ITermiRepositoryService _termiRepository;
public MyController(ITermiRepositoryService termiRepository)
{
_termiRepository = termiRepository;
}
}
Below is my action Method where I am getting values from my view.
[HttpPost]
public ActionResult MyActionMethod(TermiViewModel termiViewModel, string submitButton)
{
try
{
voucherViewModel =_termiRepository.Save(termiViewModel);
switch (submitButton)
{
case "Cancel":
return RedirectToAction("Edit",termiViewModel.Id);
default:
return RedirectToAction("Index");
}
}
catch (Exception exception)
{
}
return RedirectToAction("Index");
}
In my above Controller method I get the null value for my submitButton variable while editing my view. I don't understand why I am getting null value because while creating for the first time, I am getting values of submitButton from the submit button.
Thanks for any help!
For the solution, I need to change following classes:
My View Model:
// A new property "SaveButtonValue" added to my view model.
public class TermiViewModel : ViewModelBase
{
public long Id { get; set; }
public string Name { get; set; }
public string SaveButtonValue { get; set; }
}
My View:
// Added a hidden field for "SaveButtonValue" and passing this keyword in
// Javascript function for onclick of submit button.
#model TermiViewModel
#using (Html.BeginForm("MyActionMethod", "MyController", FormMethod.Post))
{
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.SaveButtonValue)
<div>
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
</div>
<button name="submitButton" value="Save" type="submit"
onclick="return JavaScriptFunction(this);">Save</button>
<button name="submitButton" value="Cancel" type="submit"
onclick="return JavaScriptFunction(this);">Cancel</button>
}
Javascript:
// Populating my property "SaveButtonValue" through javascript
<script language="javascript" type="text/javascript">
function JavaScriptFunction(submitButton)
{
if (objButton) {
$('#SaveButtonValue').val(submitButton.value);
}
return true;
}
</script>
My action method:
[HttpPost]
public ActionResult MyActionMethod(TermiViewModel termiViewModel)
{
try
{
voucherViewModel =_termiRepository.Save(termiViewModel);
switch (termiViewModel.SaveButtonValue)
{
case "Cancel":
return RedirectToAction("Edit",termiViewModel.Id);
default:
return RedirectToAction("Index");
}
}
catch (Exception exception)
{
}
return RedirectToAction("Index");
}
Hi I am working with mvc4
I have a razor view page for the action
public ActionResult DeliveryAddress(string userid,int productid)
{
....
return View(m);
}
that contain
<div >DELIVER HERE</div>
when clicking on this i am collecting somedata ifrom this page using jquery,
$(document).ready(function () {
$("#place-order").click(function () {
var userid = $('#selected-userId').html();
var productid = $('#selected-productId').html();
$.get("Products/PlaceOrder/"+ userid, function (data) { });
});
});
and i want to pen another view of action
[HttpGet]
public ActionResult PlaceOrder(int uid)
{
return View();
}
and paste the variable content,
but $.get("Products/PlaceOrder", function (data) { }); is not hitting this action..
please help me.
This is how you need to pass a data to a url in Jquery get method, note the same parameter name is used in the function
$.get('#Url.Action("PlaceOrder","Products")', { uid: userid }, function (data)
{
});
Make sure your URL is correct. Most probably use #Url.Action(). and also pass the parameter using new as shown below.
$.get('#Url.Action("PlaceOrder","Products",new { userid = #userid , productid = #productid })', function (data) {
});
While collecting the data make sure your parameter names are same for both while sending and while receiving.
[HttpGet]
public ActionResult PlaceOrder(int userid, int productid )
{
return View();
}
Just add HTTPGET attribute in your action method as below.
[HttpGet]
public ActionResult PlaceOrder()
{
return View();
}
java script
$("#place-order").click(function () {
var userid = $('#selected-userId').html(); // $('#selected-userId').val();
$.get('#Url.Action("PlaceOrder","Products", new { uid = userid })', function (data) { });
var productid = $('#selected-productId').html();
});
When I want my view code to be fetched like that, or even through the Html.Action() call, I use the PartialView and normally set my Controller Action as:
public ActionResult PlaceOrder(int uid)
{
return PartialView(new TestViewModel() { ID = uid });
}
as an example:
TestViewModel
public class TestViewModel
{
public int ID { get; set; }
}
PlaceOrder.cshtml
#model TestViewModel
<h2>Partial View</h2>
<p>
Partial View paragraph with the id <b>#Model.ID</b>
</p>
Index.html
<hr />
#Html.Action("PartialView", "Home", new { id = 44 })
<hr />
<div class="ap"></div>
<script>
var url = '#Url.Action("PartialView", "Home")';
$.get(url, { id: 54 }, function (data) {
$(".ap").append(data);
});
</script>
result:
I am implementing deletion functionality on web grid.
I have a column which has a link delete when it is clicked a JavaScript function is called which sends the id of that record to controller who calls a remove method to delete that record but when i debug the code list of vehicles are returned but when delete link is clicked
it gives a error A data source must be bound before this operation can be performed.
view:
#model IEnumerable<ParkOnMyDrive.Models.Vehicle>
#{
ViewBag.Title = "ViewVehicle"
}
<h2>ViewVehicle</h2>
#{
var grid = new WebGrid(source: Model,
defaultSort: "make",
rowsPerPage: 3);
}
<h2>Vehicle List</h2>
<div id="grid">
#grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column("vehicleType","Type"),
grid.Column("make", " Make"),
grid.Column("modelType", "Model"),
grid.Column("color", "Color"),
grid.Column("registartion", "Registartion"),
grid.Column(
header: "Action",
format: #<text>
<a href="#" id="Delete_#item.vehicleId" >Delete</a></text>)
)
)
Controller:
[HttpPost]
public ActionResult DeleteVehicle(string vehcKey)
{
//string key = "eb306a32-1be0-47ad-a0e8-756af97643b8";
Vehicle vehicleModel = new Vehicle();
string userName = "wasfa_anjum#yahoo.com";
if (ModelState.IsValid)
{
bool success = vehicleModel.RemoveVehicle(vehcKey,userName);
if (success)
{
ModelState.AddModelError("", "Vehicle deleted successfully");
}
else
{
ModelState.AddModelError("", "Vehicle not deleted");
}
}
else
{
}
return View();
}
Model
public bool RemoveVehicle(string vehicleKey,string userName)
{
bool success = false;
using (var session = MvcApplication.Store.OpenSession())
{
var removeVehicle = from vehc in session.Query<Vehicle>()
where vehc.vehicleId == vehicleId
where vehc.userId == userName
select vehc;
if (removeVehicle.Count() > 0)
{
var myVehicle = removeVehicle.FirstOrDefault();
Session.Delete(myVehicle);
Session.SaveChanges();
success = true;
}
}