Passing the selected value of the radiobutton to action link - asp.net-mvc

I am very new to MVC, I have to display the value coming from the database in a table format and show the radio buttons in front of each display so that user can select whatever option they want to choose, I need to post that option to the controller. Below is what I am doing.
#model IList<CertificateModel>
#{
ViewBag.Title = "RefreshCertificates";
}
<h2>
RefreshCertificates</h2>
#using (Html.BeginForm())
{
<table cellpadding="1" style="text-align: center; border: 5 px">
<tr>
<td>
</td>
<td>
Name
</td>
<td>
Issuer
</td>
</tr>
#for (var i = 0; i <= Model.Count - 1; i++) {
#Html.HiddenFor(x=>x[i].Subject)
<tr>
<td>
#Html.RadioButtonFor(x => x[i].Subject, true, new { #name = "optionsRadios", #id = "rbtrue" })
</td>
<td>
#Html.DisplayFor(x => x[i].Subject)
</td>
<td>
#Html.DisplayFor(x => x[i].Issuer)
</td>
</tr>
}
</table>
}
<table>
<tbody>
<tr>
<td>
#Html.ActionLink("STANDARD", "SelectCertOk", "LogIn", new { Type = "STANDARD", }, new { #class = "button" })
</td>
<td>
</td>
</tr>
</tbody>
</table>
Below is my model
public class CertificateModel
{
public string Subject
{
get { return cert.Subject; }
}
public string Issuer
{
get { return cert.Issuer; }
}
public bool validCert { get; set; }
}
My Controller that is putting the data on the screen code is below:
public ActionResult RefreshCertificates()
{
certificates = new List<CertificateModel>();
// some code here to fill up the list
return View(certificates );
}
The output that is displayed on the page is like this(RB is a radio button)
Subject Issuer
RB Coffee Test1
RB Tea Test2
From the current database only two are output on the screen. the user is only supposed to select only one of the radio button and then hit the actionLink button.
My problem is that right now both the buttons are selected, i want only one of the radio button to be selected and also, I also want the value of that radio button to be posted to the controller.
so for e.g if the user selects Coffee and Test1 radio button then I want to pass
#Html.ActionLink("STANDARD", "SelectCertOk", "LogIn", new { Type = "STANDARD", }, new { #class = "button" })
Type=STANDARD and SubjectIssue Coffee,Test1 to the controller. My controller signature is like this
public void SelectCertOk(string Type, string SubjectIssue)
{
}
any help will be greatly appreciated.

You are doing the right thing, but unfortunately we can't override the name attribute like the id.
Update your view to include multiple radiobuttons with same 'name'.
#Html.RadioButton('Subject', x[i].Subject)
STANDARD
<script>
function SelectCertOk(){
var subject = $("input:radio[name=Subject]")
$.post("#Url.Content("~/ControllerName/SelectCertOk")", { SubjectIssue : subject}, function (data) {}
});
}
</script>
But it won't solve your purpose.
So i would prefer to use javascript to check/uncheck radiobuttons.

Related

.NET MVC JQuery function is not getting fired in table row click event

I have table data in UI. I want to display data in a div in the same page when I click the Details link in the row. The JQuery function is not getting fired in when I click on details link in any row.
Below is my code:
Model view class:
public class ItemViewModel
{
public Item item { get; set; }
public IEnumerable<Item> items { get; set; }
}
UI Code:
#model Medhub.Models.ItemViewModel
#{
ViewBag.Title = "View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>View</h2>
<p>
#Html.ActionLink("Create New", "CreateEdit", new { controller = "Item" }, new { #class = "btn btn-primary" })
</p>
<table align="center" height="10%" width="90%">
<tr>
<td>
<div id="Items">
<table style="vertical-align:top; height:200px" width="100%">
<tr style="height:20px">
<th>
#Html.DisplayName("Name")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th>
#Html.DisplayName("Item Type")
</th>
</tr>
#if (Model != null)
{
foreach (var item in Model.items)
{
<tr style="height:15px">
<td>
#Html.HiddenFor(model => item.ItemId)
#Html.DisplayFor(model => item.Name)
</td>
<td>
#Html.DisplayFor(model => item.Description)
</td>
<td>
#Html.DisplayFor(model => item.Type)
</td>
<td>
#Html.ActionLink("Edit", "CreateEdit", new { id = item.ItemId }) |
#Html.ActionLink("Details", "Item", new { id = item.ItemId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ItemId })
</td>
</tr>
}
}
</table>
</div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="ItemDetails">
#if (Model.item != null)
{
Html.RenderPartial("Details", Model.item);
}
</div>
</td>
</tr>
</table>
<script type="text/javascript">
$(function () {
$("div.Items a").click(function (e) {
//e.preventDefault();
var url = this.ref;
$("#ItemDetails").load(url);
});
});
</script>
Controller code:
List<Item> items = new List<Item>();
// GET: Item
public ActionResult Item(int id = 0)
{
ItemViewModel itemVM = new ItemViewModel();
itemVM.items = GetItems();
if (id > 0)
itemVM.item = itemVM.items.FirstOrDefault(u => u.ItemId == id);
return View(itemVM);
}
Any clues?
First of all, you are waiting for clicks on a class called Items. This is the reason the jquery code is not being fired. You should have
$("div#Items a").click(function (e) {
Secondly, you need to check the attribut href, not ref. Also, prevent default needs to be there, otherwise you just reload your page
e.preventDefault();
var url = this.href;
You don't need the renderpartial in the page, just leave it empty:
<div id="ItemDetails">
</div>
While your logic kind of works, the way the url is loaded causes the entire page to be loaded into the ItemDetails section. I'd suggest that in your controller, you'd create a separate method for the details:
public ActionResult Details(int id) {
Item item = GetItem(id);
return View(item);
}
private Item GetItem(int id) {
return new Item() { Details = "details here" };
}

using the same partial view with different buttons

I have the following partial view, which lists users in a table. Each row has an Enroll button, which enrolls the user to the selected course.
I need almost the same view for another task. However, I need to add users to Discussions (instead of enrolling them to a course). I know I can create another view and change the Enroll buttons to Add buttons.
However, I wonder if there is a more effective way of doing this. My approach does not seem to be easy to maintain.
#model IEnumerable<ApplicationUser>
<h4>Search results:</h4>
<table class="table-condensed" style="font-size:smaller">
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
<input class="btn_Enroll" data-userid="#item.Id" value="Enroll" type="button" />
</td>
</tr>
}
</table>
<script>
$(".btn_Enroll").click(function () {
//code for enrolling
var course_id = $("#hdn_SelectedCourseId").val();
})
</script>
One way to do it is by setting an attribute of your calling action method that will render this view
<table class="table-condensed" style="font-size:smaller" data-module="#ViewData["module"]"></table>
and then use it in your JS code
<script>
$(".btn_Enroll").click(function () {
//code for enrolling
var course_id = $("#hdn_SelectedCourseId").val();
var moduleType = $(this).closest("table").attr("data-module");
if (moduleType === "enroll")
{
//Do enrollment
}
else if (moduleType === "discussion")
{
//discuss here
}
})
For example on home page you have links like
#Html.ActionLink("enrollment", "Index", new { module = "enroll" })
#Html.ActionLink("Discussion", "Index", new { module = "discussion" })
and your ApplicationUserController has index action like this
public ActionResult Index(string module)
{
ViewData["module"] = module;
return View();
}
However if scope of project or requirements can change for enrollment and/or discussion then better to keep then separate to avoid complexity of code in single page as well as in single JS code.

Getting Data of Specific year from database to show in gridview - MVC

I have a gridview in MVC project which display all records from a table but I want to display just current year's records and on clicking backward or forward arrow the records changes to the previous or next year accordingly.
I just have a ActionResult Index to which returns a list how do I implement a query here?
here is the code in my contrller
public ActionResult Index()
{
return View(db.tbl_HolidayList.ToList());
}
and here is my view code
#foreach (var item in Model) {
<tr>
#* <td>
#Html.TextBoxFor(modelItem => item.Holiday_Id, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_Id)
</div>
</td>*#
<td>
#Html.TextBoxFor(modelItem => item.Holiday_Name, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_Name)
</div>
</td>
<td>
#Html.TextBoxFor(modelItem => item.Holiday_Description, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_Description)
</div>
</td>
<td>
#Html.TextBoxFor(modelItem => item.Holiday_date, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
#Html.DisplayFor(modelItem => item.Holiday_date)
</div>
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Holiday_Id }, new { #class = "lnkEdit" }) |
#* #Html.ActionLink("Details", "Details", new { id = item.Holiday_Id}, new { #class = "lnkDetail" }) |*#
#Html.ActionLink("Delete", "Delete", new { id = item.Holiday_Id![enter image description here][1] }, new { #class = "lnkDelete" })
Have the index method return values for the current year and a separate method that returns values for a specific year as a partial view
Controller (assume HolidaysController)
public ActionResult Index()
{
return View();
}
public ActionResult Details(int year)
{
var model = db.tbl_HolidayList.Where(h => h.Holiday_date.Year == year);
return PartialView(model);
}
Index.cshtml
#{
int year = DateTime.Today.Year;
}
<button type="button" id="previous">Previous</button>
<div id="year">#year</div>
<button type="button" id="next">Next</button>
<div id="details">
#Html.Action("Details", "Holidays", new { id = year })
</div>
<script>
var year = '#year';
var url = '#Url.Action("Details", "Holidays")'; // Assumes the controller is HolidayController
var updateHolidays = function() {
$('#year').text(year);
$('#details').load(url, { id: year });
}
$('#previous').click(function() {
year--;
updateHolidays();
}
$('#next').click(function() {
year++;
updateHolidays;
}
Details.cshtml (partial)
#model IEnumerable<tbl_HolidayList>
<table>
....
<thead>
#foreach (var item in Model)
{
<tr>
<td>
#Html.TextBoxFor(m => item.Holiday_Id, new { #class = "control", id = "" })
....
</td>
....
</tr>
}
</thead>
</table>
css
.control { // could be just input[type="text"] {
display:none;
height:15px;
width: 100%; // style the column widths!
}
Note: use a class name for styling the textboxes (not inline styles) and use id = "" to remove the id attribute from the textbox (otherwise your creating duplicate id's which is invalid html)
I would :
Update your Controller to take an (int year) parameter and only return the appropriate data (no need to retrieve everything)
Create a partial view with your table in it
When clicking on Previous/Next, I would do a jQuery ajax request to retrieve the data (return a PartialViewResult for example)
In this scenario we do not know how many rows will be there for a year. So better to handle "previous" and "next" button click event and fire a AJAX call which calls an Action method to get data and then refresh the content of WebGrid.
While making AJAX call read current year value and add +1 or -1 based on which button is clicked. Then send it to an Action method as parameter (Action method will be a POST type)...Now Action method will filter data for given year and return it to view. Hope following articles may help to implement this scenario:
https://web.archive.org/web/20210927202530/http://www.4guysfromrolla.com/articles/121510-1.aspx
http://www.binaryintellect.net/articles/59b91531-3fb2-4504-84a4-9f52e2d65c20.aspx
Thanks.

Get Selected Value of Dropdownlist in ActionLink (MVC 5)

I am trying to get the selected value of a dropdownlist in #Html.ActionLink but no luck so far. Requirement is to dynamically retrieve a table and have a dropdown list for actions that can be taken against the row. I need to select an action and then on hitting submit button, row ID and selected action value should be posted to the controller. Here is the piece of code I have in place.
#foreach (AdsViewModel ad in Model)
{
<tbody>
<tr>
<td>#ad.Row_Id</td>
<td class=" "> #ad.Description </td>
<td class=" "> #ad.Valid_To.ToShortDateString() </td>
<td><span class="label label-sm label-success label-mini"> #ad.Status </span></td>
<td>#Html.DropDownList("actions", ad.Actions) </td>
<td>#Html.ActionLink("Submit", "AdAction", new {adId = ad.Row_Id, action = ad.Actions.SelectedValue}) </td>
</tr>
</tbody>
}
On clicking the Submit ActionLink, I am getting the adId but no action is returned from the dropdownlist.
Your help is much appreciated.
Edit: Here is the AdsViewModel
public class AdsViewModel
{
public string Row_Id { get; set; } //Transaction Number
public string Description { get; set; } //Trasaction Description
public DateTime Valid_To { get; set; } //Expiry
public string Status { get; set; } //Object Status Code
public SelectList Actions { get; set; }
}
This is how the Select list is filled in Controller
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem() { Text = "View", Value = "001" });
items.Add(new SelectListItem(){Text = "Modify", Value = "002"});
model.Actions = items;
This line
<td>#Html.ActionLink("Submit", "AdAction", new {adId = ad.Row_Id, action = ad.Actions.SelectedValue}) </td>
is setting the route value action to the selected value at the time the view is created on the server and before its sent to the browser (the user hasn't selected anything yet so its null). If you are wanting to set the value to "001" or "002" (the values of the dropdowns), then you need to use javascript update the href attribute of the link when the dropdown changes. An easier and more conventional solution would be to delete the dropdown and use 2 action links, one for Viewand one for Edit. Since they are 2 different actions, there should also be 2 seperate ActionResult methods in your controller. For example
#Html.ActionLink("View", "View", new { id = ad.Row_Id }) // calls the View method
#Html.ActionLink("Modify", "Modify", new { id = ad.Row_Id }) // calls the Modify method
Edit
To do this using javascript, delete the #Html.ActionLink and replace with a <button type="button"> or other element and handle its click event
var url = '#Url.Action("AdAction")';
$('button').click(function() {
var row = $(this).closest('tr');
var rowID = row.children('td').eq(0).text();
var actionID = row.find('select').val();
window.location.href = url + '?adId=' + rowID + '&action=' + actionID;
});
Note: You are creating invalid html with the #Html.DropDownList() method (all <selects> will have id="action")
This should fix it...
#for (int i = 0; i < Model.Count(); i++)
{
var ad = Model[i];
<tbody>
<tr>
<td>#ad.Row_Id</td>
<td class=" "> #ad.Description </td>
<td class=" "> #ad.Valid_To.ToShortDateString() </td>
<td><span class="label label-sm label-success label-mini"> #ad.Status </span></td>
<td>#Html.DropDownListFor("actions", m => m[i].Actions) </td>
<td>#Html.ActionLink("Submit", "AdAction", new {adId = ad.Row_Id, action = ad.Actions.SelectedValue}) </td>
</tr>
</tbody>
}
Thank you Everyone, I solved it by writing a Javascript function and calling that function on the onClink Event of the button.
<script type="text/javascript" language="javascript">
function ShowEditData() {
var url = '#Url.Action("AdAction")';
var rows = document.getElementById("mytable").rows;
for (var i = 0, ceiling = rows.length; i < ceiling; i++) {
rows[i].onclick = function () {
debugger;
var Row_Id = this.cells[0].innerHTML;
var actionID = this.cells[4].childNodes[0].value;
window.location.href = url + '?row_id=' + Row_Id + '&action_id=' + actionID;
}
}
}
</script>

Model is not populated during form post ASP.NET MVC

I am learning ASP.NET MVC. I am trying to catch model data on form post, but model is showing as null.
Here is my Model
public class SampleModel
{
public int ID { get; set; }
public string Name { get; set; }
public string CRUDOperation { get; set; }
}
Here is my view
#model IEnumerable<SampleModel>
#using (Html.BeginForm("SubmitUpdateGridRow", "GridView", FormMethod.Post, new {value = "form" }))
{
#Html.AntiForgeryToken()
<table class="table table-bordered">
<tr>
<th>
#Html.Label("CRUD Actions")
</th>
<th>
#Html.DisplayNameFor(model => model.ID)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
</tr>
#foreach (SampleModel Row in Model)
{
<tr>
#if (Row.CRUDOperation == "Select")
{
<td>
#Html.ActionLink("Update", "UpdateGridRow", "GridView", Row, new { #title = "U: Update Operation of CRUD" }) |
#Html.ActionLink("Edit", "EditGridRow", "GridView", new { id = Row.BGID }, new { #title = "U: Update Operation of CRUD" }) |
#Html.ActionLink("Delete", "DeleteGridRow", "GridView", new { id = Row.BGID }, new { #title = "D: Delete Operation of CRUD" }) |
#Html.ActionLink("Details", "DetailsGridRow", "GridView", new { id = Row.BGID }, new { #title = "Form level view for details" })
</td>
<td>
#Row.ID
</td>
<td>
#Row.Name
</td>
}
else if (Row.CRUDOperation == "Edit")
{
<td>
#Html.HiddenFor(ID => Row.ID)
#Html.HiddenFor(CRUDOperation => Row.CRUDOperation)
#Row.BGID
</td>
<td>
#Html.EditorFor(Name => Row.Name)
</td>
<td>
<input type="submit" value="Update" id="UpdateSubmit" />
#Html.ActionLink("Edit", "EditGridRow", "GridView", new { id = Row.ID }, new { #title = "U: Update Operation of CRUD" }) |
#Html.ActionLink("Reset", "ResetGridRow", "GridView", new { id = Row.ID }, new { #title = "R: Reset Operation of CRUD" })
</td>
}
</tr>
#*<tr>
#if (Row.CRUDOperation == "Edit")
{
EditRow(Row);
}
else
{
DisplayRow(Row);
}
</tr>*#
//Row.CRUDOperation.Equals("Edit") ? EditRow(Row) : DisplayRow(Row);
}
</table>
}
Here is my controller
public class GridViewController : Controller
{
[HttpPost]
public ActionResult SubmitUpdateGridRow(FormCollection FC, SampleModel VM)
{
string str = (string)FC.GetValue("Row.Name").AttemptedValue;
......
}
}
I was able to get the values from form collection, but my model is coming as null.
Thanks in advance.
PS: i would like to find the solution only with server side scripting, dont want to use javascript, JQuery
In your view you are posting a collection of SampleModel however your controller only takes in a single SampleModel parameter.
First you need to change your controller to take in IEnumerable<SampleModel>.
Then in your view, you need to pass the index to the html helpers to generate the correct html for list model binding to work out of the box.
For example:
#model IList<SampleModel>
#for(var i = 0; i < Model.Count; i++)
{
#Html.HiddenFor(m => Model[i].Id)
}
Check this useful article for more on model binding lists
Put Antiforgery attribute on top of the controller action as your HTML form has Antiforgery tag.

Resources