Get table cell value and submit to a delete function - c#

I have a table which displays data from my database. I want to provide a button which will delete data from a table based on the row selected. Specifically based on the value of a specific cell of that table.
I've tried wrapping a button inside a form element as an extra element inside of each row, but this doesn't seem to work for 2 reasons. 1, it triggers the OnGet() function in my controller and 2 it doesn't seem to bind the cell data value to my 'SourceTable' property.
The following is my front-end table:
<table class="table">
<thead>
<tr>
<td>OrderIdentifier</td>
<td>Step Number</td>
<td>CreateDate</td>
<td>Step Status</td>
<td>Source Table</td>
</tr>
</thead>
#foreach (var order in Model.order.Steps)
{
<tr>
<td>#order.OrderIdenfitier</td>
<td>#order.Name</td>
<td>#order.CreateDate</td>
<td>#order.StepStatus</td>
<td>#order.SourceTable</td>
<td>
<a class="btn btn-dark"
asp-page="./OrderDetail"
asp-route-orderId="#order.OrderIdenfitier">
<i class="glyphicon glyphicon-zoom-in"></i>
Details
</a>
</td>
<td>
<form method="delete">
<input type="hidden" class="form-control" asp-for="SourceTable" />
<button type="submit" class="btn btn-dark">
<i class="glyphicon glyphicon-zoom-in"></i>
Delete
</button>
</form>
</td>
</tr>
}
And on the backend, I'd like to be passing in the SourceTable cell value of whatever row the button is clicked on into this function:
public IActionResult OnDelete(string SourceTable)
{
//Take SourceTable parameter, pass to data access layer, and delete from database.
return Page();
}
I would like to have the value of the SourceTable cell passed to my OnDelete function, but this doesn't occur. Additionally, my 'OnGet()' function is triggered when I click my delete button, not the 'OnDelete()' function. The I form I embedded the button in has action="delete", so I would think that it would go to the OnDelete() function, but that doesn't seem to be the case.

HTTP DELETE method is currently not supported by <form> element. That's why you hit OnGet() in your Razor page. You are still able to use OnPost() for that purpose with binding form values (e.g. hidden inputs) to action method parameters.
The second issue is with your asp-for input tag helper. By default it evaluates its expression against PageModel. You can use # to override that behaviour, especially when you're in a foreach loop. Your form then could look like this:
<form method="post">
<input type="hidden" asp-for="#order.SourceTable"/>
<input type="submit" vaue="Delete"/>
</form>
and action method:
public IActionResult OnPost(string SourceTable)
{
// delete record here
return RedirectToPage();
}
Maybe you don't like the idea to delete records in OnPost handler, which you would like to reserve for some other action.Then you can use named handler method like OnPostDelete(string SourceTable). All you have to do is to add attribute asp-page-handler="delete" to the <form> element:
<form asp-page-handler="delete" method="post">
<input type="hidden" asp-for="#order.SourceTable"/>
<input type="submit" value="Delete"/>
</form>
And maybe you don't like the idea of having a separate form for each row in the table. Then wrap the form around the table and use asp-route- prefix on each delete button to specify parameter binding:
<form method="post">
<table class="table">
<thead>
<!-- ... -->
</thead>
<tbody>
#foreach (var order in Model.order.Steps)
{
<tr>
<!-- ... -->
<td>
<input type="submit" value="delete" asp-page-handler="delete" asp-route-sourcetable="#order.SourceTable" />
</td>
</tr>
}
</tbody>
</table>
</form>
You can find more valuable information in artice Introduction to Razor Pages in ASP.NET Core.

Related

How to identify one out of multiple html input type="submit"

I need to call the show button via code but in page we have multiple show buttons without id. How to hit a particular "show" button suppose 3rd show?
Assuming there is no way of uniquely identifying each submit (far, far from ideal) - you can simply reference the index:
document.querySelectorAll('[type="submit"]')[2]
If you have jQuery on the page you may also write:
$('[type="submit"]')[2]
Again, to reiterate, this is not a great way of achieving this at all - but given restrictions you have over the mark-up, it answers the question you're asking.
As an aside, the documents themselves may not have id attributes, but try and see if there is something uniquely identifiable about one of the parent elements perhaps, and traverse from there.
You can use jquery selector $('input[type=submit]') to get all input which has type=submit. More over you need to get 3rd submit button then use :nth(2) like $('input[type=submit]:nth(2)'). :nth will return element based on starting index with 0.
Learn more about jquery selector here
You can check it below. You should be using submitButton.click() instead of submitButton.val(). I have used submitButton.val() for just display purpose.
function getThirdSubmitButton() {
var submitButton = $('input[type=submit]:nth(2)');
alert(submitButton.val())
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="submit" value="Show 1" />
</td>
</tr>
<tr>
<td>
<input type="submit" value="Show 2" />
</td>
</tr>
<tr>
<td>
<input type="submit" value="Show 3" />
</td>
</tr>
<tr>
<td>
<input type="submit" value="Show 4" />
</td>
</tr>
</table>
<input type="button" value="Get 3rd submit button" onclick="getThirdSubmitButton()" />

MVC Loading up a modal with dynamic model information on click

Still a little bit new to MVC but trying to setup a modal that receives dynamic data depending on where the table data is in the foreach loop.
We have a partial that we are using to generate our table code and are passing the viewmodel we need to this partial. Now within the partial we want the links on a certain column to display a modal corresponding to that row when you click on them. So basically hand off that row's model data and display the more detailed data in the modal. For example, here we are displaying the count of the companies effected but in the modal I want to be able to display the names of them. So I need to pass that on somehow.
Table Code :
#model IEnumerable<Tier2BugViewModel>
<table id="bug" class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th></th>
<th data-class="expand">Bug</th>
<th data-hide="phone">Companies Effected</th>
</tr>
</thead>
<tbody>
#{
foreach (var row in Model)
{
<tr>
<td>
<a href="#" class="btn btn-default" data-toggle="modal" data-target="#bugEditModal">
Edit
</a>
</td>
<td>#row.Bug.Bug</td>
<td>
<a href="#" data-toggle="modal" data-target="#companiesEffectedModal">
#row.CompaniesAffected.Count
</a>
</td>
</tr>
}
}
</tbody>
</table>
Modal Code :
<!-- Companies Effected Modal -->
<div class="modal fade" id="companiesEffectedModal" tabindex="-1" role="dialog" aria-labelledby="companiesEffectedModalLabel" aria-hidden="true">
#Html.Partial("_CompaniesEffectedModal")
</div><!-- /.modal -->
After some research it feels like we are going to need some sort of jQuery script to do this, but I can't put my finger on it or figure out if there is just an easier way to do this. I guess we will eventually be doing this for the Edit modal as well. Thanks in advance.

Ajax call returning Partial View with Kendo datepicker not refreshing properly

I am adding to a list of elements through an ajax call. The ajax call sends information to controller, controller adds everything to database, then grabs all the items for the list from the database, adds the items to a view model, then returns a partial view with the model. I clear the div container for the list then add the returning HTML.
$('#container').empty().html(result);
My problem is, in the HTML, I have Kendo Datepickers. The page loads fine, and if I do a refresh everything is fine. But right after the Ajax call, the Kendo Datepickers are not there. I debugged and got the result HTML from the ajax call and the following is what is showing for the datepickers:
jQuery(function(){jQuery("#dueDate0").kendoDatePicker({"format":"M/d/yyyy","min":new Date(1900,0,1,0,0,0,0),"max":new Date(2099,11,31,0,0,0,0)});});
the 'dueDate0' is obviously the ID of the element, but it should not be zero it should be an actual ID number ( ex. 12 ). When I look at the HTML after the AJAX call, the datepickers are just input elements with a date type.
Any suggestions on what to do?
Thanks
EDIT: Here is the HTML that gets return in the AJAX call.
<div id="accordion">
<div class="ItemList">
<table class="tblPriorityElement">
<tr>
<td class="tdPrioritySelect">
<div class='handle'><span class='ui-icon ui-icon-carat-2-n-s'></span></div>
</td>
<td class="tdPriorityName">fasdfasr4</td>
<td class="tblType" tabindex="0">
<span class="txtType">Project</span>
</td>
<td class="tdPriorityDate" tabindex="0">
<time>10/8/2013</time>
</td>
<td class="tdAllocation" tabindex="0">
<span class="txtAllocation">0 hrs</span>
</td>
<td class="tdDeletePriority">;
<img src="../../Images/redx.png"/>
</td>
</tr>
</table>
<div class="content">
<form class="editItem">
<input id="ItemID" name="ItemID" type="hidden" value="0" />
<label>Name:</label>
<input class="text-box single-line" id="Item_Name" name="Item.Name" type="text" value="fasdfasr4" />
<label>Type:</label>
<input class="text-box single-line" id="Item_Type" name="Item.Type" type="text" value="Project" />
<label>Due date:</label>
<input class="k-input" id="dueDate0" name="dueDate0" type="date" value="10/8/2013" />
jQuery(function(){jQuery("#dueDate0").kendoDatePicker({"format":"M/d/yyyy","min":new Date(1900,0,1,0,0,0,0),"max":new Date(2099,11,31,0,0,0,0)});});
<br/>
<label>End Date:</label>
<input class="k-input" id="endDate0" name="endDate0" type="date" />
jQuery(function(){jQuery("#endDate0").kendoDatePicker({"format":"M/d/yyyy","min":new Date(1900,0,1,0,0,0,0),"max":new Date(2099,11,31,0,0,0,0)});});
<label>Start Date:</label>
<input class="k-input" id="startDate0" name="startDate0" type="date" value="10/8/2013" />
jQuery(function(){jQuery("#startDate0").kendoDatePicker({"format":"M/d/yyyy","min":new Date(1900,0,1,0,0,0,0),"max":new Date(2099,11,31,0,0,0,0)});});
<br/>
<input type="submit" value="save"/>
</form>
</div>
</div>
</div>
When generating the partial view,just define some kind of random id for the datepicker - for example Guid.NewGuid() or something. are you using the MVC helpers to define the datepicker?

Can I call .cs file from form action?

There is a code in my site as follows(html page):
<form action="form.php" method="post">
<table>
<tr>
<td>
<input type="text" class="email1" name="name" maxlength="20" class="bg_in" />
</td>
</tr>
</table>
<input type="submit" name="posted" value="" class="bg_in2" />
</form>
I want to change it that instead of action="form.php" it will be action="form.cs". Is that possible? if so, what should be the method name that catches the action and how do I catch the inputs?
The form is always submitted to the page itself. If you specify an action attribute, it is ignored. If you omit the method attribute, it will be set to method="post" by default. Also, if you do not specify the name and id attributes, they are automatically assigned by ASP.NET
If you select view source in an .aspx page containing a form with no name, method, action, or id attribute specified, you will see that ASP.NET has added these attributes to the form. It looks something like this:

How can I add a new Table with a Button click event MVC?

I have a table with text box asking for Name and Address for reference. If need be, I would like the user to have the ability to add more and not be restricted to just one. How would I add a new table to a form by clicking on my "getMore" button?
<table style="width:50%;">
<tr>
<th colspan="2">Reference</th>
</tr>
<tr>
<td>Name</td>
<td><input id="txtRefName" type="text" /></td>
</tr>
<tr>
<td>Address</td>
<td><input id="txtRefAddress" type="text" /></td>
</tr>
<tr>
<td>City</td>
<td><input id="txtRefCity" type="text" /></td>
</tr>
<tr>
<td>State</td>
<td><input id="txtRefState" type="text" /></td>
</tr>
<tr>
<td>Zip</td>
<td><input id="txtRefZip" type="text" /></td>
</tr>
<tr>
<td>Phone</td>
<td>(H)<input id="txtOtherHPhone" type="text" /><br />
(W)<input id="txtOtherWPhone" type="text" />
</td>
</tr>
</table>
<br />
<asp:Label ID="Label1" runat="server" Width="30%"></asp:Label>
<input type="button" name="getPrev" value="Prev" onclick="history.back(-1)" />
<asp:Label ID="Label2" runat="server" Width="10%"></asp:Label>
<input type="submit" name="getMore" value="More..." />
<asp:Label ID="Label3" runat="server" Width="10%"></asp:Label>
Just check this article. You can bind to a list of references without any pain. All you need now is to modify your controller a bit and to add another table to html using javascript and update the identifier on a click on the button. And it's very easy to do using jQuery.
One way is to setup your action method to accept the posted controls, submit the data to the database, and recreate the view with the added table (similar to postbacks in web forms). The postback can be wrapped in an AJAXForm to help make it a rich ui.
You can also create the table programmatically with javascript by using the DOM to create a table, row, cell, and control elements.
Lastly, JQuery can stream a partial view to the client via AJAX. You could setup the table as a partial view, stream it to the client when the link is clicked.
Any of these options appeal to you? I can give you more details then.
EDIT: To use JQUery, you can add an action method to a controller like:
public class TestController {
public ActionResult GetAsync()
{
return PartialView("MyView");
}
}
In the view, using jquery, you can do this:
$.get("/Test/GetAsync", function(data) {
//Data is html so we just need to clear the previous result (if needed)
//And add the new data
$("#paneltoshow").html(data);
//or use an alternate approach like:
$("<div/>").html(data).appendTo("#paneltoappendto");
});
Check out JQuery.com, documentation tab for more information (manipulation tab, don't have the link handy, sorry).

Categories