How can I send a list in BeginForm()? - asp.net

Can someone please help me with this problem? At the bottom of my view just before the page loads I create an array of checkboxes like this:
foreach (var course in courses.Select((x, i) => new { Data = x, Index = i }))
{
int currentIndex = course.Index;
String selectedday = "";
String selectedteacher = "";
if (cnt++ % 4 == 0)
{
#: </tr> <tr>
}
#: <td >
<br /><br /><br />
<input type="checkbox" id="checkbox"
name="selectedCourses"
value="#course.Data.CourseID"
#(Html.Raw(course.Data.Assigned ? "checked=\"checked\"" : ""))
/>
I use the same loop to add the assigned state to a list like this:
bool theNewString=course.Data.Assigned ;
String a=theNewString.ToString();
assignedCourses.Add(a);
I defined a list variable at the top of the page so that it can be accessed by the form-wide like this:
#{List<String> assignedCourses =new List<String>(); }
Now I want to send that variable to the controller and this is where things get muddy. If I send a string like this it works fine:
Razor markup
String postedData = "literalString";
#using (Html.BeginForm("Action", "Controller", new { assigned = # postedData }))
Action
[HttpPost]
public ActionResult Edit(int id,List<String> assigned){}
Now if I try this:
#{List<String> assignedCourses =new List<String>(); }
#using (Html.BeginForm("Action", "Controller", new { assigned = #assignedCourses }))
And nothing comes through to the controller. It’s like the list is emptied just before posting. How can send my list to the controller?

I think the way you are trying to create the query string/postback url for the form using the list is wrong and will not produce a properly formatted string.
Maybe try something like this:
#{
List<string> ExampleList = new List<string>();
ExampleList.Add("True");
ExampleList.Add("False");
string param = string.Join("&", ExampleList.ToArray());
}
#using (Html.BeginForm("index", "home", new { #someparam = (new HtmlString(param)) })) { }
This would require you to split the single string up into an array when the action method receives it.
alternatively you can try using RouteValueDictionary instead of list, but this does not support duplicate keys.
Also for checkbox creation try using #Html.CheckBox() as this will automatically create a second hidden input set to false. HTML Forms don't post back checkbox values when they are unchecked, so the second hidden input with the same name will be posted back and you will know it has been unchecked or not checked. MVC will interpret values of "True, False" for the same form key/input name as True and False when just the hidden input with the "False" value is posted back.

Related

asp.net - Update db from input and button inside a table

I know this seems stupid but I can't find a way to make it work...
I generate a table from a db with this loop (simplified)
#foreach (var item in Model.Approvals)
{
<tr>
<td>#item.ApprovalReviewer</td>
.
.
.
.
<td>
<button asp-action="Approve" asp-route-id="#item.Key" asp-controller="Dashboard">Approve
</button>
</td>
<td><input asp-for="Approval.ChangeReviewer" value="#item.ChangeReviewer"/></td>
}
it looks like this, I can add a row and delete one, no issue there everything is working
so basically you enter a name in the reviewer input and when you press approve then that name is updated for the correct key. The issue I have is that I can't find a way to bind that input to the button.
[HttpPost]
public IActionResult Approve(int? key, Global obj)
{
var objToApprove = _db.ApprovalTable.Find(key);
objToApprove.ChangeApproved = true;
objToApprove.ChangeApprovalDate = DateTime.Now;
objToApprove.ChangeReviewer = obj.Approval.ChangeReviewer;
objToApprove.ChangeSigned = obj.Approval.ChangeReviewer;
_db.ApprovalTable.Update(objToApprove);
_db.SaveChanges();
return Redirect(Url.Action("ECR", new { id = obj.Approval.ECRNumber }) + "#2"); //TAB #2 FORM APPROVAL
}
what I need is the value of the input on the same row as the button... sounds easy...I guess not for me..
I don't know if this is the right way of doing it but I was able to solve my problem like this:
I replaced the Foreach loop to a regular loop so that each control would have its own index. Then I passed to the controller the index i so I could get the correct value in the controller.
So it looks like this:
#for (int i = 0; i < Model.Approvals.Count() - 1; i++)
{
The button where I pass the index i to the controller
<button class="---" asp-action="Approve" asp-route-key="#Model.Approvals[i].Key" asp-route-index="#i" asp-route-ecr="#Model.Approvals[i].ECRNumber" asp-controller="Dashboard">Approve</button>
and finally the controller where I can retrieve the variable
[HttpPost]
public IActionResult Approve(int? key, Global obj, int? ecr, int index)
{
var objToApprove = _db.ApprovalTable.Find(key);
objToApprove.ChangeApproved = true;
objToApprove.ChangeApprovalDate = DateTime.Now;
objToApprove.ChangeReviewer = obj.Approvals[index].ChangeReviewer;
objToApprove.ChangeSigned = obj.Approvals[index].ChangeReviewer;
_db.ApprovalTable.Update(objToApprove);
_db.SaveChanges();
return Redirect(Url.Action("ECR", new { id = ecr }) + "#2");
}
I have 2 weeks of experience in asp.net so it is hard to know if there is a much better and elegant way of doing this but it works. So it seems that after all I was not there for a "code writing service"...

get the select element in .NET using AJAX

I have ajax function like this to run on HTML select list
$.ajax({
type: "POST",
url: urlemp,
success: function (returndata) {
if (returndata.ok) {
// var data = eval("" + returndata.data + "");
select.empty();
select.append($('<option>' + "" + '</option>'));
$.each(returndata.data, function (rec) {
select.append($('<option>' + returndata.data[rec].Name + '</option>'));
});
select.show('slow');
select.change();
}
else {
window.alert(' error : ' + returndata.message);
}
}
}
);
and this is the HTML element
<select id="cmbDept"></select>
How can i get the value of the selected item in the controller using MVC 3 ?
you have 4 ways to do that
1. the you can bind ti the change event of the select $(select).change(function(){}) and send an ajax request again wrapping the selected value which you will be able to get in the controller
2. you can keep a hidden input in your view binded to a property in the view's model now bind to the change of the select and fill the input with the value this way whenever your form is posted back it will have the values properly binded to the model
3. #Don saved me from writing the third way so read his ans.
4. if you have a model that this view is binded to then simple keep a property in the model with the name cmbDept and selected value would be automatically posted back
Us FormCollection as parameter in your controller. And assign name to the select
<select id="cmbDept" name="cmbDept"></select>
Now the FormCollection has this posted value.
public ActionResult Index(FormCollection form)
{
string val = "";
foreach (var key in form.AllKeys)
{
if (key.Contains("cmbDept"))
{
val = form.Get(key);
}
}
--your code here with the posted values
return View();
}
To get the value of the select element on the client, just use $("#cmbDept").val().
To get the value of the element once it's submitted to the server, add a name="cmbDept" to your select and simply create a parameter named cmbDept in the controller action your $.ajax call is is posting to.

How can I populate the pull down menu using data from a database?

I keep on getting this error message.InvalidCastException was unhandled by the user, Unable to cast object of type 'System.Int32' to type 'System.String'.
I've been told the view data value for bloodtype is not correct. Just trying to figure out how to determine the value.
I'm new to asp.net therefore don't understand too much at the moment.
<select name="bloodtype">
<% List<Hospital.bloodtype> bloodtypeList = (List <Hospital.bloodtype>) ViewData["bloodtypeList"];
foreach (Hospital.bloodtype st in bloodtypeList)
{
%>
<option value="="<%= st.bloodcode%>"><% *if (st.bloodcode==(String) ViewData["bloodtype"])* Response.Write("Selected"); %><% Response.Write(st.meaning);%>></option>
<% } %>
<option value="0" <% if ((Int32) ViewData["bloodtype"]==0) Response.Write("Selected");%>>
</option>
public void HospitalInit()
{
hospitalSQLEntities db = new hospitalSQLEntities();
ViewData["bloodtypeList"] = db.bloodtypes.ToList();
ViewData["patientid"] = "";
ViewData["patientname"] = "";
ViewData["bloodtype"] = 0;
ViewData["junk"] = "";
ViewData["spam"] = "";
ViewData["comments"] = "";
ViewData["formmessage"] = "";
}
public ObjectSet<bloodtype> bloodtypes
{
get
{
if ((_bloodtypes == null))
{
_bloodtypes = base.CreateObjectSet<bloodtype>("bloodtypes");
}
return _bloodtypes;
}
}
The best way to do this is to define a list of bloodtypes in your code behind like:
private List<bloodtype> _bloodtypes = new list<bloodtype>();
Next, you can use an ASP.NET combobox control that you place on your page and to which you databind the specified list (also in the code behind), like so:
public void PageLoad(){
_bloodtypes = GetBloodTypes();
myCombobox.DataSource = _bloodtypes;
myCombobox.DataBind();
}
private IList<bloodtype> GetBloodTypes(){
// Get some bloodtypes
return new List<bloodtype>();
}
Of course, before databinding, you need to fill the list (as seen above).
Instead of casting use convert
Convert.ToInt32(ViewData["bloodtype"])

Using Html.DropDownListFor() with a SelectList

What is the correct way to populate a SelectList when using the Html.DropDownListFor helper in ASP.Net MVC 3?
I basically have a "Create" form which I want to specify the entry values on for a particular field. For example, it is a movie database and I want the ability to enter a Genre, but I don't want users to be able to enter what they like, so I assume a SelectList to be the best answer?
A way that works is to create a new class with a static method to return the SelectList:
public class Genres
{
public static List<string> GetGenres()
{
List<string> myGenres = new List<string>();
myGenres.Add("Comedy");
myGenres.Add("Romantic Comedy");
myGenres.Add("Sci-Fi");
myGenres.Add("Horror");
return myGenres;
}
}
Which can then be used like this:
<div class="editor-field">
#Html.DropDownListFor(model => model.Genre, new SelectList(OLL.Models.Genres.GetGenres()))
</div>
It just doesn't seem like the right/easiest way to do it? I think I'm missing something obvious here...
Thanks for any assistance you can provide.
This is a simple selectList style I use for drop downs all the time, hopefully you find this helpeful.
ViewBag.AlbumListDD = from c in db.Query<DatabaseEntities.VenuePhotoAlbum>("WHERE VenueId = #0", VenueId)
select new SelectListItem
{
Text = c.Name,
Value = c.Id.ToString()
};
Inside my view:
#Html.DropDownList("AlbumId", (IEnumerable<SelectListItem>)ViewBag.AlbumListDD, new { id = "ChangeAlbum" })
Hopefully you can find this useful as this is a database route to go. I typically like to have all of that sort of information in a database and that way users can dynamically add/remove and change these dropdown items at will. There is a bit of SQL work behind the scenes required when removing a type but it has proven to be very successful and fast for me at this point.
var og = (from s in DB.Products
select new SelectListItem
{
Text = s.ProductName,
Value = s.ProductID.ToString()
});
ViewBag.lstProducts = new SelectList(getproductname, "ProductID", "ProductName");
<p>
#Html.DropDownList("AlbumId", (IEnumerable<SelectListItem>)ViewBag.lstProducts, new { #id = "drp" });
</p>

enable html dropdown through controller in mvc

i have an scenario where i have to perform some action according to selection of the
dropdown .
for basic refrence you can use the example of country,state,city.
i am able to populate the country list at that time i have set the other two drop downs to
disable.
after the countries are populated i want to select the state.it is getting populated .
two problems
1) how to retain the state of country ddl as it is coming back to its orisnal state.
2) how to enable the drop down through my controller.
myview code
Country
<p>
<label>
State</label>
<%=Html.DropDownList("ddlState", ViewData["ddlState"] as SelectList, "--not selected--",new { onchange = "document.forms[0].submit()", disabled = "disabled" })%>
</p>
<p>
<label>
City</label>
<%=Html.DropDownList("ddlCities", ViewData["ddlCities"] as SelectList, "--not selected--", new { onchange = "document.forms[0].submit()", disabled = "disabled" })%>
</p>
my controller code
public ActionResult InsertData()
{
var customers = from c in objDetailEntity.Country
select new
{
c.Cid,
c.Cname
};
SelectList countriesList = new SelectList(customers.Take(100), "Cid", "Cname");
ViewData["ddlCountries"] = countriesList;
SelectList EmptyState = new SelectList(customers);
ViewData["ddlState"] = EmptyState;
ViewData["ddlCities"] = EmptyState;
Session["ddlSesCountry"] = countriesList;
return View();
}
//
// POST: /RegisTest/Create
[HttpPost]
public ActionResult InsertData(FormCollection collection)
{
try
{
CountryId = Convert.ToInt16(Request.Form["ddlCountries"]);
stateid = Convert.ToInt16(Request.Form["ddlState"]);
if (CountryId > 0 && stateid <= 0)
{
var stateslist = from c in objDetailEntity.State
where c.Country.Cid == CountryId
select new
{
c.Sid,
c.Sname
};
SelectList stateList = new SelectList(stateslist.Take(100), "Sid", "Sname");
ViewData["ddlState"] = stateList;
Session["StateList"] = stateList;
ViewData["ddlCities"] = stateList;
}
if (stateid > 0)
{
var citieslist = from c in objDetailEntity.City
where c.State.Sid == stateid
select new
{
c.Ctid,
c.Cityname
};
SelectList cityList = new SelectList(citieslist.Take(100), "Ctid", "Cityname");
ViewData["ddlCities"] = cityList;
ViewData["ddlState"] = Session["StateList"];
}
ViewData["ddlCountries"] = Session["ddlSesCountry"];
return View();
}
catch
{
return View();
}
}
My choice would be not to post back the form at all. I would write an action in the controller that takes a CountryID and returns a JsonResult holding a list of states. The onchange event could call a jQuery function that uses AJAX to call this action, loads the new list, and enables the second drop-down list.
However, if you stick with the postback, here's why it's not working:
The Country list isn't retaining its selected value because the view is being reloaded from scratch each time and you're setting it to "not selected." The SelectList constructor has an overload that takes a "SelectedItem" object as the fourth parameter. When you initialize your SelectList, you should pass the appropriate value to this parameter, and not force it in the View.
You need to write an "if" clause in your View to choose whether or not to enable the list based on some criteria. You could bind to a ViewModel that has a Boolean property like "EnableStates," or you could use something like the count of values in the StateList - if the count is greater than zero, enable it, for example.
A tricky thing to get used to when you move from Web Forms to MVC is that you don't have ViewState anymore - your application is stateless. There's nothing that "remembers" what value is selected in a drop-down for you, you have to set it each time you load the page.
I recommend using JSON & jQuery - like this posted answer.

Resources