I'm trying to find the rowIndex of the row that had the delete button that was clicked. However when the delete button is clicked it doesn't find the ID instead it returns null and errors out.
I have tried this:
$("#delete").on("click", function (e) {
var row = $(this).closest("tr");
row.remove();
return false;
});
but this solution doesn't post. Then I have also tried this:
<td><input type="submit" formaction="/LansingMileage/DeleteEntry/#item.RowIndex" value="Delete" name="Deletebtn" id="delete" /></td>
which is causing my null issue.
My Controller:
[HttpPost]
public ActionResult DeleteEntry(string rowIndex)
{
// try
{
//rowIndex = Request.Form["Deletebtn"];
using (db)
{
LansingMileage lansing = db.LansingMileages.Find(rowIndex);
db.LansingMileages.Remove(lansing);
db.SaveChanges();
LansingMileageViewModel model = new LansingMileageViewModel();
model.Records = db.LansingMileages.OrderBy(
//will need to change to a select all
//I'm not following the Take command
m => m.RowIndex).ToList();
model.SelectedLansingMileage = null;
model.DisplayMode = "";
return View("Index", model);
}
}
// catch(Exception e)
{
///Debug.WriteLine(e);
}
}
My Index.cshtml:
<table id="LansingData" class="table">
<thead>
<tr>
<th>Action</th>
<th>Row ID</th>
<th>Expense Month/Yr</th>
<th>Travel Date</th>
<th>Travel Type</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Records)
{
if(Model.SelectedLansingMileage != null)
{
if(item.RowIndex == Model.SelectedLansingMileage.RowIndex)
{
#:<tr class="SelectedLansingMileage">
}
else
{
#:<tr>
}
}
else
{
#:<tr>
}
<td><input type="submit" formaction="/LansingMileage/DeleteEntry/#item.RowIndex" value="Delete" name="Deletebtn" id="delete" /></td>
<td>#item.RowIndex</td>
<td>#item.ExpMonthYr</td>
<td>#item.TravelDate</td>
<td>#item.TripType</td>
#:</tr>
#*<tr id="#item.RowIndex">
<td><a class="Delete" href="javascript:;">Delete</a></td>
<td>#item.ExpMonthYr</td>
<td>#item.TravelDate</td>
<td>#item.TripType</td>
<!--Here is where I will create a table to display my data from the above section-->
</tr>*#
}
</tbody>
</table>
The desired result is that when the user clicks on the delete button it removes the row and post to the database.
You can use the Select overload, something like:
#foreach (var item in Model.Select((item,index)=>new{item,index})
{
<tr>
<td>
<input type="submit" formaction="/LansingMileage/DeleteEntry/#item.index" value="Delete" name="Deletebtn" id="delete" />
</td>
</tr>
}
Or do it manually like this:
#{int RowNo = 0;}
#foreach (var item in Model) {
<tr>
<td><input type="submit" formaction="/LansingMileage/DeleteEntry/#RowNo" value="Delete" name="Deletebtn" id="delete" /></td>
</tr>
Note: Why not use the #id for the row? If it's possible that rows are added while one is being deleted, bad things can happen.
Related
I have a table in my project which works perfectly. I want to retreive the values of the whole row based on the user selected radio button for that particular row. So that I can POST it into my DB table.
For example I have this HTML Table:
Radio button ID Company Name
0 123 Company1
0 343 Company2
Based on the radiobutton selection I need a parameter which holds the whole row value , which i can pass to controller function. If user selects first row then the SaveValue stores ID = 123, CompanyName = Company1. Hope I am clear with my question. As can't paste the whole code I just edited and quickly added some snippets. Please let me know if any additional input required.
Here are some code snippets for better understanding:
<EditForm Model="#SearchFilter" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Company Name</th>
</tr>
</thead>
<tbody>
#if (lstResult != null)
{
#foreach (Models.TP Result in lstResult.tp)
{
<tr>
<td>
<input value="1" id="type_radio_1" name="type_radio" type="radio"/>
</td>
<td>#Result .id</td>
<td>#Result .companyName</td>
</tr>
}
}
#else
{
<tr>
<td><div>No record Found</div></td>
</tr>
}
</tbody>
</table>
<div class="form-row">
<div class="text-left col-6">
<button type="submit" class="btn btn-primary mr-1 btn-success">Save</button>
</div>
</div>
</EditForm>
protected async void HandleValidSubmit()
{
await Http.PostAsJsonAsync($"api/company/add", SaveValue);
toastService.ShowSuccess("Company saved successfully!");
}
Here is a simple demo you could follow:
Model:
public class Result
{
public List<TP> tp { get; set; }
}
public class TP
{
public int id { get; set; }
public string companyName { get; set; }
}
Index.razor:
<EditForm Model="#lstResult" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Company Name</th>
</tr>
</thead>
<tbody>
#if (lstResult != null)
{
#foreach (TP Result in lstResult.tp)
{
<tr>
<td> //add here!!!!
<input value="1" id="type_radio_1" name="type_radio"
type="radio" #onclick="(() => Add(Result))" />
</td>
<td>#Result.id</td>
<td>#Result.companyName</td>
</tr>
}
}
else
{
<tr>
<td><div>No record Found</div></td>
</tr>
}
</tbody>
</table>
<div class="form-row">
<div class="text-left col-6">
<button type="submit" class="btn btn-primary mr-1 btn-success">Save</button>
</div>
</div>
</EditForm>
#code{
//for easy testing, hard coded the data...
Result lstResult = new Result()
{
tp = new List<TP>()
{
new TP(){id=1,companyName="aa"},
new TP(){id=2,companyName="bb"},
new TP(){id=3,companyName="cc"}
}
};
//create a variable...
TP SaveValue = new TP();
//add this method to get the selected model...
protected async Task Add(TP tp)
{
SaveValue = tp;
}
protected async void HandleValidSubmit()
{
//do your stuff....
await Http.PostAsJsonAsync($"api/company/add", SaveValue);
}
}
I am trying to remove a table row from the table:
<tbody>
#foreach (var task in Model)
{
<tr>
<td>
#task.time
</td>
<td>
#task.descripiton
</td>
<td>
#task.duedo
</td>
<td>
<form action="#Url.Action("Remove")" method="POST"><input type="submit" value="Delete" /></form>
</td>
</tr>
}
</tbody>
How could I send the index of the row to the controller?
public ActionResult Remove()
{
Task.RemoveAt();
return RedirectToAction("Index");
}
The row where I pressed the button would get removed.
Change view code to:
<tbody>
#{
var idx = 0;
foreach (var task in Model)
{
<tr>
<td>
#task.time
</td>
<td>
#task.descripiton
</td>
<td>
#task.duedo
</td>
<td>
<form action="#Url.Action("Remove", "YourControllerName", new { id = idx++ })" method="POST">
<input type="submit" value="Delete" />
</form>
</td>
</tr>
}
}
</tbody>
Then, change Remove method to:
public ActionResult Remove(int id)
{
Task.RemoveAt(id);
return RedirectToAction("Index");
}
i'm creating a search function in mvc5
my program works like this:
Index view have search box and button
and the result of that also displays in index view
so my problem is that how do i display the result in another view - say like searchresult.cshtml and not in index view?
here's my controller:
public ActionResult Index(string searching)
{
return View(db.TblId.Where(x => x.IdNumber.Contains(searching) || searching == null));
}
my index view (i just removed the other text contents, only included the search result)
#model IEnumerable<MVC5_Search.Models.TblId>
#using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
#Html.TextBox("searching")<input type="submit" value="Search" />
}
<table>
<thead>
<tr>
<td>Id Number</td>
<td>First Name</td>
<td>Middle Name</td>
<td>Last Name</td>
</tr>
</thead>
<tbody>
#if (Model.Count() == 0)
{
<tr>
<td colspan="3" style="color: red">
No Result!
</td>
</tr>
}
else
{
foreach (var item in Model)
{
<tr>
<td>#item.IdNumber</td>
<td>#item.Firstname</td>
<td>#item.Middlename</td>
<td>#item.Lastname</td>
</tr>
}
}
</tbody>
</table>
i'm using this together with entity framework
EDIT:(trying to solve)
here's what i've done so far,
i created another controller (SearchingController) to avoid conflict with the main controller,
[HttpGet]
public ViewResult SearchResult(string searching)
{
return View("SearchResult", db.TblId.Where(x => x.TId.Contains(searching) || searching == null));
}
and then the view SearchResult.cshtml
#model IEnumerable<TblId.Models.TId>
#{
ViewBag.Title = "searchresult";
}
<table>
<thead>
<tr>
<td>IdNumber</td>
<td>First Name</td>
<td>Middle Name</td>
<td>Last Name</td>
</tr>
</thead>
<tbody>
#if (Model.Count() == 0)
{
<tr>
<td colspan="3" style="color: red">
No Result!
</td>
</tr>
}
else
{
foreach (var item in Model)
{
<tr>
<td>#item.IdNumber</td>
<td>#item.Firstname</td>
<td>#item.Middlename</td>
<td>#item.Lastname</td>
</tr>
}
}
</tbody>
</table>
and in my index view,
#using (Html.BeginForm("SearchResult", "Searching", FormMethod.Get))
{
#*#Html.TextBox("searching")*#
<input type="text" id="searching" name="searching" />
<button type="submit" name="searching" id="searching "class="btn btn-secondary">
Verify
<br>
</button>
}
still not working as expected
when i clicked search button, it just change the url to something like this
/Index?searching=T101&searching=
T101 - is the Id i'm searching
Follow these steps:
-> Create a new view searchresult.cshtml with below contents
#model IEnumerable<MVC5_Search.Models.TblId>
<table>
<thead>
<tr>
<td>Id Number</td>
<td>First Name</td>
<td>Middle Name</td>
<td>Last Name</td>
</tr>
</thead>
<tbody>
#if (Model.Count() == 0)
{
<tr>
<td colspan="3" style="color: red">
No Result!
</td>
</tr>
}
else
{
foreach (var item in Model)
{
<tr>
<td>#item.IdNumber</td>
<td>#item.Firstname</td>
<td>#item.Middlename</td>
<td>#item.Lastname</td>
</tr>
}
}
</tbody>
</table>
-> Modify your index post action to
[HttpPost]
public ViewResult Index(string searching)
{
return View("searchresult",db.TblId.Where(x => x.IdNumber.Contains(searching) || searching == null));
}
following is my view code, I pass list from controller to view and here I am iterating that list through foreach I want to pass the same view-model list to the action when I submit the form
#model IEnumerable<AskQuestionViewModel>
.
.
.
<table class="table table-bordered">
<thead>
<tr>
<td>Question</td>
<td>Yes</td>
<td>No</td>
</tr>
</thead>
<tbody>
#foreach (var q in Model)
{
<tr>
<td>#q.Question</td>
#if (q.Answer == true)
{
<td><input type="radio" name="#q.QuestionID" value="true" checked />/td>
}
else
{
<td><input type="radio" name=#q.QuestionID value="true" required /></td>
}
#if (q.Answer == false)
{
<td><input type="radio" name=#q.QuestionID value="false" checked /></td>
}
else
{
<td><input type="radio" name=#q.QuestionID value="false" required /></td>
}
</tr>
}
The following is action code
[HttpPost]
public ActionResult AskQuestions(List<AskQuestionViewModel> askQVM)
{
...
}
I'm getting null in askQVM
This is what you need for postback.
<table class="table table-bordered">
<thead>
<tr>
<td>Question</td>
<td>Yes</td>
<td>No</td>
</tr>
</thead>
<tbody>
#using (Html.BeginForm("AskQuestions", "Questions", FormMethod.Post))
{
for (int i = 0; i < Model.Count; i++)
{
var yesOptions = Model[i].Answer ? new { #checked = "checked" } : null;
var noOptions = Model[i].Answer ? null : new { #checked = "checked" };
<tr>
<td>
#Model[i].Question
#Html.HiddenFor(model=>Model[i].QuestionID)
#Html.HiddenFor(model=>Model[i].Question)
</td>
<td>#Html.RadioButtonFor(model => Model[i].Answer, true, yesOptions)</td>
<td>#Html.RadioButtonFor(model => Model[i].Answer, false, noOptions)</td>
</tr>
}
<button type="submit">Submit</button>
}
</tbody>
</table>
This is the script I am working with.
$(document).ready(function () {
$('#selectall').click(function () {
$('.selectedId').prop('checked', isChecked('selectall'));
});
});
function isChecked(checkboxId) {
var id = '#' + checkboxId;
return $(id).is(":checked");
}
function resetSelectAll() {
// if all checkbox are selected, check the selectall checkbox
// and viceversa
if ($(".selectedId").length === $(".selectedId:checked").length) {
$("#selectall").attr("checked", "checked");
} else {
$("#selectall").removeAttr("checked");
}
if ($(".selectedId:checked").length > 0) {
$('#edit').attr("disabled", false);
} else {
$('#edit').attr("disabled", true);
}
}
And this is the cshtml view.
<table id="notificationsTableId">
<thead>
<tr role="row">
<th rowspan="1" colspan="1">
<input type="checkbox" id="selectall" />
</th>
</tr>
</thead>
<tbody>
<tr class="results-table-row odd">
<td>
<input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll();"/>
</td>
</tr>
<tr class="results-table-row even">
<td>
<input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll();"/>
</td>
</tr>
<tr class="results-table-row even odd">
<td>
<input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll();" />
</td>
</tr>
</tbody>
</table>
Right now the select button will work like it should, if i check it it will check all the dates inside that table.
But what I want to do is I want that button to select all the Check-boxes on the page.
But if I give a checkbox the same ID inside my foreach loop like this:
#foreach (var date in group)
{
var isoDate = date.ToString("yyMMdd");
var day = date.ToString("ddd", new CultureInfo("sv-SE")).Substring(0, 2);
<label style="padding-left: 10px">
<input type="checkbox" id="selectedId" name="isoDate" value="#isoDate"/>#day-#isoDate
</label>
}
It doesn't work, it will still only select those 3 check-boxes on the top of the page. I would assume it would check all the check-boxes correct?
It ends up like this:
You are using selectedId as id instead of class like other checkboxes. Use it as class attribute as shown below
#foreach (var date in group)
{
var isoDate = date.ToString("yyMMdd");
var day = date.ToString("ddd", new CultureInfo("sv-SE")).Substring(0, 2);
<label style="padding-left: 10px">
<input type="checkbox" class="selectedId" name="isoDate" value="#isoDate"/>#day-#isoDate
</label>
}