I have the view that contains the checkbox and Submit button as shown below.
#using (Html.BeginForm())
{
<fieldset>
<legend style="font-size: 100%; font-weight: normal">Delete</legend>
<p> Are you sure you want to delete?</p>
#foreach (string resource in resources)
{
if (resource != "")
{
<input type="checkbox" name="Resources" title="#resource" value="#resource" checked="checked"/>#resource
<br />
}
}
<br />
#Html.HiddenFor(m => m.AttendeeListString)
#Html.HiddenFor(m => m.ResourceListString)
<span class="desc-text">
<input type="submit" value="Yes" id="btnYes" />
</span>
<span class="desc-text">
<input type="submit" value="No" id="btnNo" />
</span>
</fieldset>
}
Below is the Controller code...
public ActionResult DeleteResource(RoomModel roomModel)
{
...
}
RoomModel contains some other data...
Now how can i access the checkbox value in controller?
Note : I have lot more information that need to be send to Controller when i clicked on submit button... Can anybody suggest some solution....
Answer :
I have added these two property to My model
public List<SelectListItem> Resources
{
get;
set;
}
public string[] **SelectedResource**
{
get;
set;
}
And My view check box i have updated as follows
#foreach (var item in Model.Resources)
{
<input type="checkbox" name="**SelectedResource**" title="#item.Text" value="#item.Value" checked="checked"/>#item.Text
<br /><br />
}
And in Controller ...
if (roomModel.SelectedResource != null)
{
foreach (string room in roomModel.**SelectedResource**)
{
resourceList.Add(room);
}
}
Note: The name of check box and Property in the model should be same. In my case it is SelectedResource
You have a few options. The easiest would be:
1) Parameter bind a view model with the Resources property. I recommend this way because it's the preferred MVC paradigm, and you can just add properties for any additional fields you need to capture (and can take advantage of validation easily by just adding attributes).
Define a new view model:
public class MyViewModel
{
public MyViewModel()
{
Resources = new List<string>();
}
public List<string> Resources { get; set; }
// add properties for any additional fields you want to display and capture
}
Create the action in your controller:
public ActionResult Submit(MyViewModel model)
{
if (ModelState.IsValid)
{
// model.Resources will contain selected values
}
return View();
}
2) Parameter bind a list of strings named resources directly in the action:
public ActionResult Submit(List<string> resources)
{
// resources will contain selected values
return View();
}
It's important to note that in the question, the view is creating checkboxes that will send the string value of all checked resources, not boolean values (as you might expect if you used the #Html.CheckBox helper) indicating if each item is checked or not. That's perfectly fine, I'm just pointing out why my answer differs.
In MVC action, have a parameter that corresponds to the name of the checkbox, something like:
bool resources
bool[] resources
use javascript or jquery to collect all the value and post to the controller
var valuesToSend='';
$('input:checked').each(function(){
valuesToSend+=$(this).val() + "$";//assuming you are passing number or replace with your logic.
});
and after submit call ajax function
$.ajax({
url:'yourController/Action',
data:valuesTosend,
dataType:'json',
success:function(data){//dosomething with returndata}
})
or else you can pass the model to controller. if you implemented Model -View-ViewModel pattern.
public class yourViewModel
{
public string Id { get; set; }
public bool Checked { get; set; }
}
Action methods
[HttpPost]
public ActionResult Index(IEnumerable<yourViewModel> items)
{
if(ModelState.IsValid)
{
//do with items. (model is passed to the action, when you submit)
}
}
I'm assuming that the resources variable is generated in the Controller or can be placed onto the ViewModel. If so, then this is how I would approach it:
Your view model would have a Resources dictionary added to it, and would look something like this:
public class RoomModel
{
public Dictionary<string,bool> Resources { get; set; }
// other values...
}
You populate the Resources Dictionary with the names of your resource items as the key (string) and set the "checked" value (bool) to a default state of false.
e.g. (in your [HttpGet] controller)
// assuming that `resource` is your original string list of resources
string [] resource = GetResources();
model.Resources = new Dictionary<string, bool>();
foreach(string resource in resources)
{
model.Resources.Add(resource, false);
}
To render in the view, do this:
#foreach (string key in Model.Resources.Keys)
{
<li>
#Html.CheckBoxFor(r => r.Resources[key])
#Html.LabelFor(r => r.Resources[key], key)
</li>
}
This will then enable the [HttpPost] controller to automatically populate the dictionary onto the Model when you post back:
public ActionResult DeleteResource(RoomModel roomModel)
{
// process checkbox values
foreach(var checkbox in roomModel.Resources)
{
// grab values
string resource = checkbox.Key;
bool isResourceChecked = checkbox.Value;
//process values...
if(isResourceChecked)
{
// delete the resource
}
// do other things...
}
}
I have added these two property to My model
public List<SelectListItem> Resources
{
get;
set;
}
public string[] **SelectedResource**
{
get;
set;
}
And My view check box i have updated as follows
#foreach (var item in Model.Resources)
{
<input type="checkbox" name="**SelectedResource**" title="#item.Text" value="#item.Value" checked="checked"/>#item.Text
<br /><br />
}
And in Controller ...
if (roomModel.SelectedResource != null)
{
foreach (string room in roomModel.**SelectedResource**)
{
resourceList.Add(room);
}
}
Note: The name of check box and Property in the model should be same. In my case it is SelectedResource
Related
I'm working on a Lexical Analyzer and I want to show all data on a table in MVC. But to simplify code I'll add an example to show what I want to achieve. I have a logic.cs class where the Lexical Analyzer will be receiving the string coming into, and I want to Add items to the List accordingly to the Lexical Analyzer method.
This is my code:
Controller
Repository repo = new Repository();
logic logica = new logic();
public ActionResult Index()
{
var getrepo = repo.GetData();
return View(getrepo.ToList());
}
[HttpPost]
public ActionResult Index(string str) {
logica.Logic_t(str); //I send str parameter to the logic class
var getrepo = repo.GetData();
return View(getrepo.ToList());
Model
Repository.cs
public class Repository
{
public List<data_table> data = new List<data_table>() { };
public List<data_table> GetData() {
return data;
}
}
data_table.cs
public int Line { get; set; }
public string Token { get; set; }
logic.cs
Repository repo = new Repository();
public void Logic_t(string s)
{
int Line = 1;
repo.data.Add(new data_table { Line =Line , Token = " NUMBER" });
}
View
#model IEnumerable<pruebaarray.Models.data_table>
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<textarea rows="10" cols="50" class="textarea" name="str">
</textarea>
<input type="submit" value="send-to-logic" class="btn btn-primary"/>
}
<table class="table-bordered">
<tr>
<th>Line</th>
<th>Token</th>
</tr>
#foreach (var item in Model) {
<tr>
<th>#item.Line</th>
<th>#item.Token</th>
</tr>
}
</table>
And this is my final view:
My code has no Errors, but when I click the submit button, nothing shows in the table. What am I missing? or what could be wrong?
PD: My Lexical Analyzer logic has recursive methods so It will be adding data constantly to the List.
UPDATE: I got this just by setting List to static
Currently, your form does not know which controller or action to target.
Html.BeginForm() has several overloads.
For example:
BeginForm(HtmlHelper, String, String, Object, FormMethod, Object)
Writes an opening tag to the response and sets the action tag
to the specified controller, action, and route values. The form uses
the specified HTTP method and includes the HTML attributes.
Check the overloads here
I have an a href link to a page which adds a parameter to the link for example:
tsw/register-your-interest?Course=979
What I am trying to do is to extract the value in Course i.e 979 and display it in the view. When attempting with the below code, I only return with 0 rather than the course value expected. ideally I'd like to avoid using routes.
Here is the view:
<div class="contact" data-component="components/checkout">
#using (Html.BeginUmbracoForm<CourseEnquiryPageSurfaceController>("PostCourseEnquiryForm", FormMethod.Post, new { id = "checkout__form" }))
{
//#Html.ValidationSummary(false)
#Model.Course;
}
And my controller:
public ActionResult CourseEnquiry(string Course)
{
var model = Mapper.Map<CourseEnquiryVM>(CurrentContent);
model.Course = Request.QueryString["Course"];
return model
}
This is the View Model:
public class CourseEnquiryVM : PageContentVM
{
public List<OfficeLocation> OfficeLocations { get; set; }
public string Test { get; set; }
public string Course { get; set; }
public List<Source> SourceTypes { get; set; }
}
SOLUTION:
After some research and comments I've adjusted the code to the below which now retrieves the value as expected
#Html.HiddenFor(m => m.Course, new { Value = #HttpContext.Current.Request.QueryString["Course"]});
Thanks all
Based on the form code you provided you need to use #Html.HiddenFor(m => m.Course) instead of just #Model.Course. #Model.Course just displays the value as text instead of building a input element that will be sent back to your controller.
If your problem is with a link prior to the view you referenced above, here's what I'd expect to work:
View with link:
#model CourseEnquiryVM
#Html.ActionLink("MyLink","CourseEnquiry","CourseController", new {course = #Model.Course}, null)
CourseController:
public ActionResult CourseEnquiry(string course)
{
// course should have a value at this point
}
In your view, you are only displaying the value of Course.. which isn't able to be submitted. You need to incorporate the value of course with a form input element (textbox, checkbox, textarea, hidden, etc.).
I would highly suggest using EditorFor or Textboxfor, but because your controller action is expecting just a string parameter you could just use Editor or TextBox.
#using (Html.BeginUmbracoForm<CourseEnquiryPageSurfaceController>("PostCourseEnquiryForm", FormMethod.Post, new { id = "checkout__form" }))
{
//#Html.ValidationSummary(false)
#Html.TextBox(Model.Course, null, new { #class = "form-control"});
<input type="submit" value="Submit" />
}
Then you should just be able to do this in your controller:
public ActionResult CourseEnquiry(string course) // parameter variables are camel-case
{
var model = Mapper.Map<CourseEnquiryVM>(CurrentContent);
if(!string.IsNullOrWhiteSpace(course))
model.Course = course;
return model;
}
Let me know if this helps.
I have a list of teams on my index page.
I'm trying to pass the text of an input(type text) from the index view back to the index controller, to reload the index page, this time only displaying items in my list which have matching text. eg - bob = bob
Index Controller
public ActionResult Index(string searchString)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
var listOfTeams = from T in db.Teams
select T;
if (!String.IsNullOrEmpty(searchString))
{
listOfTeams = listOfTeams.Where(T => T.TeamName.Contains(searchString));
}
return View(listOfTeams.ToList());
}
How i'm trying to pass the data in the Index view
I've tried
<input type="text" id="inputTeamSearch" name="searchString" class="form-control" style="width:225px;height:60px" onblur="IsTextEmpty()" oninput="CheckTeams()" placeholder="Search">
#Html.ActionLink("Search", "Index")
and
#using(Html.BeginForm("Index", "Team"))
{
<input type="text" id="inputTeamSearch" name="searchString" class="form-control" style="width:225px;height:60px" onblur="IsTextEmpty()" oninput="CheckTeams()" placeholder="Search">
<input type="submit" id="Index" value="Index" />
Html.EndForm();
}
I'm sure this is probably a duplicate of some sort, if so please just pass me in the appropriate direction. I've looked for answers, but they're either long-winded or go into more complex detail than this.
So to post data to a controller you need a seperate post action which is decorated with the HttpPost attribute. This method needs to take a model as it's parameter:
[HttpPost]
Public ActionResult Index(IndexVM model)
{
var searchTerm = model.SearchTerm;
}
The view model needs to contain the fields that you intend to post.
Public class IndexVM
{
Public String SearchTerm { get; set; }
//Other model examples
public Int32 PageNumber { get; set; }
public Int32 NumOfItemsPerPage { get; set; }
}
Then your html needs to contain a text box that has the same name as the string property in your view model.
#Html.TextBoxFor(m => m.SearchTerm)
//And at the top of your html page you will need to include the model
#model Domain.Models.IndexVM
OR
<input type="text" name="SearchTerm">
Should work.
If you are already using an entity model you can create a new View model which contains the old entity and whatever else you need. So:
public class IndexVM
{
public Team Team { get; set; }
public String SearchTerm { get; set; }
}
Then on your index GET method where you're passing your team to your view you would have:
var view = new IndexVM();
view.Team = //your team object
return View(view);
This is my html-
<td>
#{
IEnumerable<SelectListItem> Brands = ViewBag.GetBrands;
foreach (var item in Brands)
{
#Html.CheckBox(item.Text, false)
<label>#item.Text</label><br />
}
}
</td>
Im Posting this controller as JSON data (form collection). How can i get checkbox's text and value in form collection data in controller?
How can i get checkbox's text and value in form collection data in controller?
The correct approach is to use a view model instead of this IEnumerable<SelectListItem>. So basically your model could look like this:
public class BrandViewModel
{
public string Text { get; set; }
public bool Checked { get; set; }
}
and then add a property to your main view model (the one your view is strongly typed to) of type IList<BrandViewModel>:
public IList<BrandViewModel> Brands { get; set; }
and then it's pretty easy:
<td>
#for (var i = 0; i < Model.Brands.Count; i++)
{
#Html.CheckBoxFor(x => x.Brands[i].Checked)
#Html.LabelFor(x => x.Brands[i].Checked, Model.Brands[i].Text)
#Html.HiddenFor(x => x.Brands[i].Text)
}
</td>
and finally you can get rid of any weakly typed FormCollection from your controller action and simply take the view model:
[HttpPost]
public ActionResult SomeAction(IList<BrandViewModel> brands)
{
...
}
or if there are also other properties you need to pass your controller action may take the main view model:
[HttpPost]
public ActionResult SomeAction(MainViewModel model)
{
// the model.Brands collection will be automatically bound here
...
}
I managed to get ID by -
#Html.CheckBox(item.Text, false, new {item.Value})
First You have to perform post back to server.
#using (Html.BeginForm("actionname", "controller",
FormMethod.Post))
//your code
#{
IEnumerable<SelectListItem> Brands = ViewBag.GetBrands;
foreach (var item in Brands)
{
#Html.CheckBox(item.Text, false)
<label>#item.Text</label><br />
}
}
<input type="submit" class="k-button" value="Submit" id="btnSubmit" name="btnSubmit" />
}
Now in the controller you will get the values using form collection
[HttpPost]
public ActionResult actionName( FormCollection collection)
{
collection.keys["checkbox"].value ... your code
}
I have an MVC view
<%# Page Language="C#" MasterPageFile="PathToMaster" Inherits="System.Web.Mvc.ViewPage<ModelData>" %>
and I have a form with HTML markup for a set of checkboxes:
<label for="MyCheckbox">Your choice</label>
<input type="checkbox" id="Option1" class="checkbox" name="MyCheckbox" value="Option one" />
<label for="Option1">Option one</label><br />
<input type="checkbox" id="Option2" class="checkbox" name="MyCheckbox" value="Option two" />
<label for="Option2">Option two</label><br />
and I have a controller-action pair
class MyController : Controller {
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestStuff( ModelData data )
{
}
}
and that action is invoked when the form is submitted.
How do I map the checkboxes onto members of ModelData (and what members I have to add to ModelData) so that when the form is submitted data stores information on which checkboxes are checked?
OK, this one will be for MVC3, but - save for syntax changes - should work in MVC2 too. The approach is essentially the same.
First of all, you should prepare an appropriate (view)model
public class MyViewModel
{
[DisplayName("Option 1")]
public bool Option1 { get; set; }
[DisplayName("Option 2")]
public bool Option2 { get; set; }
}
Then you pass this model to the view you're showing (controller):
public ActionResult EditMyForm()
{
var viewModel = new MyViewModel()
return View(viewModel);
}
with the form:
#model MyViewModel
#using( Html.BeginForm())
{
#Html.Label("Your choice")
#Html.LabelFor(model => model.Option1) // here the 'LabelFor' will show you the name you set with DisplayName attribute
#Html.CheckBoxFor(model => model.Option1)
#Html.LabelFor(model => model.Option2)
#Html.CheckBoxFor(model => model.Option2)
<p>
<input type="submit" value="Submit"/>
</p>
}
Now here the HTML helpers (all the CheckBoxFor, LabelFor, EditorFor etc) allow to bind the data to the model properties.
Now mind you, an EditorFor when the property is of type bool will give you the check-box in the view, too. :)
And then, when you submit to the controller, it will auto-bind the values:
[HttpPost]
public ActionResult EditMyForm(MyViewModel viewModel)
{
//And here the view model's items will be set to true/false, depending what you checked.
}
First you define SelectList for Options. This will be used just to render checkboxes
public IList<SelectListItem> OptionsSelectList { get; set; }
Than, you define model that will hold value of single chosen option after post
public class ChooseOptionViewModel
{
public int OptionIdentifier { get; set; } //name or id
public bool HasBeenChosen { get; set; } //this is mapped to checkbox
}
Then IList of those options in ModelData
public IList<ChooseOptionViewModel> Options { get; set; }
And finally, the view
#for (int i = 0; i < Model.OptionsSelectList.Count(); i++)
{
<tr>
<td class="hidden">
#Html.Hidden("Options[" + i + "].OptionIdentifier", Model.OptionsSelectList[i].Value)
</td>
<td>
#Model.OptionsSelectList[i].Text
</td>
<td>
#Html.CheckBox("Options[" + i + "].HasBeenChosen", Model.Options != null && Model.Options.Any(x => x.OptionIdentifier.ToString().Equals(Model.OptionsSelectList[i].Value) && x.HasBeenChosen))
</td>
</tr>
}
After post, you just inspect Options.Where(x => x.HasBeenChosen)
This is full-functional, and it will allow you to redisplay view when validation errors occur, etc. This seems a bit complicated, but I haven't come up with any better solution than this.