How to bind the multiple radio button values to controller action - c#

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>

Related

RowIndex returning null when trying to find

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.

Row to send a List<Object> from Razor page to Update?

I need to send a List back to my controller and update the values on my repository.
But after load the view with the values, update it and click the submit button, I don't know how to get the list with the update values and call the update method from the repository.
I'm using .Net 4.7.2.
HomeController:
[HttpGet]
public ActionResult Nota(string Concurso)
{
List<InscricoesModel> model = new List<InscricoesModel>();
InscricoesRepository repository = new InscricoesRepository();
model = repository.GetAprovadosPrimeiraFase(new Guid(Concurso));
return View("Nota",model);
}
[HttpPost]
public void UdateNotas(List<InscricoesModel> model)
{
InscricoesRepository repository = new InscricoesRepository();
foreach(InscricoesModel item in model)
{
repository.Update(item);
}
}
Nota.cshtml:
#model List<ConcursoBolsaSegundaFase.Model.InscricoesModel>
<h1>Classificados 2ª Fase</h1>
<hr />
<p>Exportado em #DateTime.Now</p>
<div style="margin-top:15px">
#* TABELA RESULTADO *#
<div id="notasAprovadosSegundaFase" style="margin-top:10px">
#using (Html.BeginForm("UdateNotas", "Home", Model, FormMethod.Post))
{
<table class="table table-bordered" id="tblNotaAprovadosSegundaFase">
<thead>
<tr>
<th>Inscrição</th>
<th>Nome</th>
<th>Nota Primeira Fase</th>
<th>Fez Carta</th>
<th>Nota Segunda Fase</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
foreach (var linha in Model)
{
<tr>
<td>#linha.Inscricao</td>
<td>#linha.Nome</td>
<td>#linha.NotaPrimeiraFase</td>
<td>
<select>
<option value="false">Não</option>
<option value="true">Sim</option>
</select>
</td>
<td><input type="text" value="#linha.NotaSegundaFase"></td>
</tr>
}
}
</tbody>
</table>
<button type="submit" class="btn btn-success">Salvar</button>
}
</div>
</div>
The UpdateNotas method in my controller never recive a value, i don't know how to send the list from the view to my controller.
In MVC, the name of the input will be binded to the variable in the controller. In your case, your input has no name. I suggest you look at the html helpers.
This would bind your values properly.
for (int i = 0;i<Model.Count;i++)
{
Html.TextBoxFor(model => Model[i].NotaSegundaFase)
}
In this case, only NotaSegundaFase would be sent back to the controller.
You can use #Html.HiddenFor() to hold the data on the view and bind to controller on Post.
#using (Html.BeginForm("UdateNotas", "Home", Model, FormMethod.Post))
{
<table class="table table-striped table-bordered table-sm table-responsive">
<thead>
<tr>
<th>Inscrição</th>
<th>Nome</th>
<th>Nota Primeira Fase</th>
<th>Fez Carta</th>
<th>Nota Segunda Fase</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count; i++)
{
#Html.HiddenFor(model => Model[i].Inscrição)
#Html.HiddenFor(model => Model[i].Nome)
#Html.HiddenFor(model => Model[i].NotaPrimeiraFase)
<tr>
<td>#Model[i].Inscrição</td>
<td>#Model[i].Nome</td>
<td>#Model[i].NotaPrimeiraFase</td>
#*do this similary for other property *#
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-success">Salvar</button>
}
As far as I understood,you want to post DropDownList value only.
if you decide to update other fields just add the Html.Editor into the loop like following.
#Html.Editor("[" + i + "].Inscricao")
#Html.Editor("[" + i + "].Nome")
I hope this will help.
#using (Html.BeginForm("UdateNotas", "Home", Model, FormMethod.Post))
{
<table class="table table-bordered" id="tblNotaAprovadosSegundaFase">
<thead>
<tr>
<th>Inscrição</th>
<th>Nome</th>
<th>Nota Primeira Fase</th>
<th>Fez Carta</th>
<th>Nota Segunda Fase</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Model[i].Inscrição</td>
<td>#Model[i].Nome</td>
<td>#Model[i].NotaPrimeiraFase</td>
<td>
<select name="[#i].NotaSegundaFase">
<option value="false">Não</option>
<option value="true">Sim</option>
</select>
</td>
<td><input type="text" value="#linha.NotaSegundaFase"></td>
</tr>
}
}
</tbody>
</table>
<button type="submit" class="btn btn-success">Salvar</button>
}
Note : don't change anything in the controller. model binder should resolve everything from the request.

Passing model with list of checkboxes from view to controller

I am trying to pass model from View back to controller. I am passing NaborViewModel to View. It is a list of objects and every object has 4 checkboxes (some of them randomly checked).
Model:
public class NaborViewModel
{
public List<WowClass> WowClasses { get; set; }
}
Actions:
[HttpGet]
public ActionResult Nabor()
{
NaborViewModel viewModel = new NaborViewModel();
DatabaseDataContext context = new DatabaseDataContext();
viewModel.WowClasses = context.WowClasses.ToList();
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Nabor(NaborViewModel model)
{
//DB actions
return RedirectToAction(Consts.ActionNabor);
}
In view i have 2 forms each with different approach. The first one is the one i have created with thought it might work.
The second form is approach i found online.
The first one is displaying passed data correctly (filled checkboxes). The second one is even displaying every checboxes unchecked.
When forms are submitted, they both returns null back to controller action.
View:
#using (Html.BeginForm(Consts.ActionNabor, Consts.ControllerAdmin, FormMethod.Post))
{
#Html.AntiForgeryToken()
<table class="admin-table">
<thead>
<tr>
<th>Class</th>
<th>Status</th>
<th colspan="3">Požadované talenty</th>
</tr>
</thead>
<tbody>
#foreach (var cls in Model.WowClasses)
{
<tr>
#Html.HiddenFor(x => cls.Id)
<td>#cls.ClassName</td>
<td>#Html.CheckBoxFor(x => cls.Open)</td>
<td style="text-align: left">#Html.CheckBoxFor(x => cls.NeedTalents1) <span>#cls.Talents1</span></td>
<td style="text-align: left">#Html.CheckBoxFor(x => cls.NeedTalents2) <span>#cls.Talents2</span></td>
<td style="text-align: left">#Html.CheckBoxFor(x => cls.NeedTalents3) <span>#cls.Talents3</span></td>
</tr>
}
</tbody>
</table>
<input type="submit" value="#Consts.Submit" />
}
<div class="horizontal-line-both"></div>
#using (Html.BeginForm(Consts.ActionNabor, Consts.ControllerAdmin, FormMethod.Post))
{
#Html.AntiForgeryToken()
<table class="admin-table">
<thead>
<tr>
<th>Class</th>
<th>Status</th>
<th colspan="3">Požadované talenty</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.WowClasses.Count; i++)
{
<tr>
<td>
<input type="text" value="#Model.WowClasses[i].ClassName" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].Open" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].NeedTalents1" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].NeedTalents2" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].NeedTalents3" name="Expense[#i].Id">
</td>
<td>
<input type="hidden" value="#i" name="Expense[#i].Id">
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="#Consts.Submit" />
}
I got this to work with a combination of your two approaches. See the following:
#for (int i = 0; i < Model.WowClasses.Count; i++)
{
...
<tr>
#Html.EditorFor(model => model.WowClasses[i].Open)
</tr>
...
}
Accessing each item in your List via its index is key. If you look at the HTML generated using this method, each item's name includes its index (in the example above, the generated input's name is this: name="WowClasses[0].Open"). This is how your controller action can distinguish between list items.
For your second form, you can modifying every input field like this,
for check box,
<input type="checkbox" id="WowClasses_#(i)_Open" name="WowClasses[#i].Open" value="true" />
for input filed,
<input type="checkbox" id="WowClasses_#(i)_ClassName" name="WowClasses[#i].ClassName" value="true" />
you just changes your every input filed by your class property.hopefully this your help

C# how to remove a current row from the table by button click

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");
}

Searching - from index view and result to another view

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));
}

Categories