I have a dropdownlist that is being populated by a sql server, I am using Visual Studio 2010, cshtml, with razor as well as using the MVC pattern to create this project. What I am trying to do is when someone selects a value from the dropdown list on change it will update the page with information about that book.
I need help with the three things below:
user selects a book from the dropdownlist how to get the Book Name back to the controller
The server (retrieve the information from the server about the book) and
Back to view to be displayed.
I started with getting the dropdown poplulated.
My View looks like this
BookName: #Html.DropDownList("BookName", ViewData["BookName"] as IEnumerable<SelectListItem>, new { id = "UserSelectedValue" })
My Controller:
public ActionResult Index()
{
ViewData["BookName"] = new SelectList(_context.BookName.Select(a => a.Book_Name).Distinct());
return View();
}
A dropdown list can't cause the page to post back to your controller on its own. You need to do one of two things:
Add a submit button so that the user changes the dropdown and then clicks a button to view the results.
Use javascript to submit the form on the element's change event.
Either way, you will need to wrap the dropdown/submit button in a form.
Option 1
<form>
BookName: #Html.DropDownList("BookName", ViewData["BookName"] as IEnumerable<SelectListItem>, new { id = "UserSelectedValue" })
<input type="submit" value="Show results" />
</form>
Option 2
<script type="text/javascript">
// assuming you're using jQuery
$(function() {
$('#UserSelectedValue').change(function() {
$(this).parent('form').submit();
});
});
</script>
<form>
BookName: #Html.DropDownList("BookName", ViewData["BookName"] as IEnumerable<SelectListItem>, new { id = "UserSelectedValue" })
<input type="submit" value="Show results" />
</form>
Your controller code would then become something like:
public ActionResult Index(string bookName)
{
ViewData["BookName"] = new SelectList(_context.BookName.Select(a => a.Book_Name).Distinct());
if (!string.IsNullOrWhiteSpace(bookName))
{
ViewData["Books"] = _context.BookName.Where(b => b.Book_Name == bookName).ToList();
}
return View();
}
Related
I have created a dropdownlist using html helper.
It's able to get the value and bind to dropdown.
How can i pass the selected dropdown value to controller?
My View:
#Html.DropDownList("Language", new SelectList(ViewBag.LangList, "Text", "Value"))
<input type="button" class="btn" title="Filter By Language"
value="Filter By Language" onclick="location.href='#Url.Action("SURV_Answer_Result", "SURV_Answer",
new { Survey_ID = Model[0].Survey_ID, Language = ViewBag.LangList })'" />
My Controller to get Language and bind into dropdown:
public ActionResult SURV_GetLanguage(int Survey_ID)
{
var getlanguagelist = from r in db.SURV_Question_Ext_Model
join s in db.SURV_Question_Model on r.Qext_Question_ID equals s.Question_ID
where s.Question_Survey_ID == Survey_ID
group new { r, s } by r.Qext_Language into grp
select grp.FirstOrDefault();
foreach (var item in getlanguagelist.ToList())
{
List<SelectListItem> langResult = new List<SelectListItem>();
foreach (var item2 in getlanguagelist)
{
SelectListItem temp = new SelectListItem();
temp.Text = item2.r.Qext_Language;
temp.Value = item2.r.Qext_Language;
langResult.Add(temp);
}
ViewBag.LangList = langResult;
}
return View(ViewBag.Langlist) ;
}
And i want pass the Language to the controller below:
public ActionResult SURV_Answer_Result(int Survey_ID, string Language)
{
List<AnswerQuestionViewModel> viewmodel = new List<AnswerQuestionViewModel>();
SURV_GetLanguage(Survey_ID);
// do whatever i want...
}
Your button in the view istype="button" and you have attached a onclick event which will just redirect to the SURV_Answer_Result passing the original ViewBag property back to the method (which will not bind to string Language because its List<SelectListItem>.
You need a form with FormMethod.Get
#using (Html.BeginForm("SURV_GetLanguage", "ControllerName", new { Survey_ID = Model[0].Survey_ID }, FormMethod.Get))
{
#Html.DropDownList("Language", (Enumerable<SelectListItem>)ViewBag.LangList)
<input type="submit" ... />
}
Notes:
The Survey_ID has been added to the form as a route value
ViewBag.LangList is Enumerable<SelectListItem> which is all that
is required by the DropDownList() helper so there is no point in
the extra overhead of creating another SelectList from it
(SelectList IS Enumerable<SelectListItem>)
The code you have used would work if you change the method signature on the controller to public ActionResult SURV_GetLanguage(int Survey_ID, string Language = null). You could then test for nulls and process as necessary.
However it would be better to wrap the dropdownlist inside a form, and use a POST request. Something like:
#using (Html.BeginForm("SURV_GetLanguage","ControllerName",FormMethod.Post))
{
#Html.DropDownList("Language", new SelectList(ViewBag.LangList, "Text", "Value"))
<input type="submit" class="btn" />
}
Then in the controller you could have a new method:
[HttpPost]
public ActionResult SURV_GetLanguage(string Language)
{
//Do whatever you want with language.
}
There are two ways,
1) You can put your dropdown and submit button into a form containing action parameter. On button press, your form will be submitted to its action. Your action must contain a parameter with name 'Languages'. It will give you selected value.
All the parameters of action, if matching to 'name' property of controls, will contain their values on form submit.
2) You can get selected value from dropdown by using jquery and then use either window.location or build url for form's action and call submit.
I have a main view with a textbox and dropdown list:
#using (Ajax.BeginForm("GetResults", "SomeController", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "PartialDiv" }))
<select name ="dropdown1" onchange="$(this.form).submit();" >
<option></option>
#foreach (var recordrow in ...)
{
<option value="#recordrow.Value" >#recordrow.Text</option>
}
</select>
<select name ="dropdown2" >
<option></option>
#foreach (var recordrow in ...)
{
<option value="#recordrow.Value" >#recordrow.Text</option>
}
</select>
#Html.TextBox("textbox1", null, new { size = 10 })
<div id="PartialDiv" class="GroupBoxForeground" >
#Html.Partial("PartialView")
</div>
The main view automatically renders a partial view once certain controls on the main view have been filled with values. Inside the Partial View, there is a submit button which calls an ActionResult.
Part of the Partial View:
#using (Ajax.BeginForm("Function1", "SomeController", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "someDiv" }))
...
<input type="submit" name="btn_submit" value="Process" style="width:80px" />
My ActionResult looks like this:
[HttpPost]
public ActionResult Function1(FormCollection formdata, MasterModel MstModel)
{
...
}
I am able to successfully bind the values in my Partial View to MasterModel. However, I am unable to get the values of the controls in the Main View while calling the ActionResult. I cannot find the key in the FormCollection and have tried the same method I used in the partial view for model binding.
Both Views are strongly-typed with the MasterModel.
Since the values in the Main View can be changed after the Partial View is rendered, I need to get the values once more when the submit button is clicked in the partial view. Is there a way to access those control values in the Main View inside ActionResult of the Partial View?
Edit:
To explain the situation more clearly as suggested in the comments, My main view is basically a search screen with a textbox and one of the dropdown lists which will be used by the partial view for processing later.
My partial view (in a separate form) shows the results of the search along with a submit button inside to process certain tasks based on the results. However, this processing also requires the 2nd dropdown list's value and the textbox's value in the main view. Those 2 controls in the main view can be changed even after the partial view is loaded. Therefore, I am hoping to find some way to get those values in the main view when the submit button is pressed.
so you mean, you have two separate forms. On posting second form, you also want to post values of the controls, that are in first form. For that purpose, you can take help of jquery, as values outside the form are not posted on submit.
You can create hidden fields in your second form (partial view form), as:
#Html.Hidden("dropdown1value", "", new { #id = "ddl1val" })
#Html.Hidden("dropdown2value", "", new { #id = "ddl2val" })
and then on change event of your dropdown1, you can do like:
//assuming 'dropdown1' is the `id` of your dropdown1
$("#dropdown1").change(function () {
$("#ddl1val").val($("#dropdown1").val());
});
same way for the second dropdown.
Hope you have got the idea.
I am developing an ASP .Net MVC 3 application using C# and SQL Server 2005.
I am using also Entity Framework and Code First Method.
In a view Index, I have a DropDownList Gamme. I define its item selected in my view, like this :
public string SelectedProfile_Ga { get; set; }
In this view, I have a button Appliquerthat took me to another view Application.
<input type="button" value="Appliquer" id="appliquer" onclick="window.location = 'ProfileGa/Application'"/>
In the view Application, I have a button submit Appliquer.
<input type="submit" value="Appliquer" id="appl" />
When I click on Appliquer, I want save the value selected in my DropDownList Gamme in my base.
The problem is that this value is passed NULL when i change the view (exit page Index and open Application).
I find that with Debugging.
The Controller action :
[HttpPost]
public ActionResult app(FlowViewModel model)
{
Famille fam = new Famille();
fam.ID_Gamme = model.SelectedProfile_Ga;
db.Familles.Add(fam);
db.SaveChanges();
return RedirectToAction("Application");
}
Note :
I didn't forget this in the Application:
<% using (Html.BeginForm("app", "ProfileGa")) { %>
ProfileGa is the name of my controller.
For starters, your dropdown is in the Index view, and the selection is happening there. Then you're redirecting to ProfileGa/Application and leaving this information behind.
I would change this button:
<input type="button" value="Appliquer" .. etc
to a <submit>, and wrap the code with the dropdown in one of these:
using (Html.BeginForm("Application", "ProfileGa")) {
and add a Post version of Application
[HttpPost]
public ActionResult Application(FlowViewModel model)
{
// Do whatever
return View(model);
}
Then when you get to the Application view, it should still have the same information as it left Index with.
To check this is working, put a breakpoint at return View(model); and look at the model's contents.
However, posting null from the view probably means that something is wrong inside your <% using (Html.BeginForm("app", "ProfileGa")) { %> statement, so if the above doesn't do anything, post the code from your `Application' view.
I have created a C# ASP.NET MVC application. In the Index view, i have added 3 buttons, when each button is clicked i want to execute 3 different functions from the Index controller.
Index View that resides in the Home folder
#using (Html.BeginForm()) {
<input type="submit" value="b1" />
<input type="submit" value="b2" />
<input type="submit" value="b3" />
}
Home Controller
public ActionResult Button1Click()
{
return View();
}
public ActionResult Button3Click()
{
return View();
}
public ActionResult Button2Click()
{
return View();
}
When each button is clicked how can i write code to execute the correct controller method ?
If you are posting then you can put each button in a separate form:
#using (Html.BeginForm("Button1Click","Index")) {
<input type="submit" value="b1" />
}
#using (Html.BeginForm("Button2Click","Index")) {
<input type="submit" value="b2" />
}
#using (Html.BeginForm("Button3Click","Index")) {
<input type="submit" value="b3" />
}
If there is no data to post, as shown in your method, and you still want to have all buttons in the same form then you can do an ajax post (this does not make sense though but hey I'm basing it on the code you gave in your question), with this though you may want to change your buttons from a submit into a button (input type="button").
$("#b1").click(function(){
$.post('/index/button1click', function() {
});
});
$("#b2").click(function(){
$.post('/index/button2click', function() {
});
});
$("#b3").click(function(){
$.post('/index/button3click', function() {
});
});
If you want to do a GET instead of a post then just replace .post with .get.
In MVC you need to remove the (Asp.Net) idea of linking button clicks to actions. ASP.Net is event driven MVC uses the classic HTTP REST approach.
So the buttons aren't actions, the buttons submit actions. The action that is submitted is controlled by your form. So your form POSTs data to the controller, using a HTTP post.
Now it's not clear what your trying to achieve here. You appear to be returning different views from each action. So using the REST idea, you should be a GETing not a POSTing (your getting HTML). So the simplest idea is to turn your input(submit) into Anchor tag, i.e. a HTTP GET:
#Html.ActionLink("Button1Click")
etc.
MVC doesn't work like Webforms where you have a ButtonClick event.
Do you want to post any values to the controller?
If not, you can use a link that you can style like a button. Use the buildin Html extensions.
//For links
#Html.ActionLink("Button1Text","Button1Click")
#Html.ActionLink("Button2Text","Button2Click")
#Html.ActionLink("Button3Text","Button3Click")
//If you need more styling options
Button1
Button2
Button3
That way you don't need any javascript or multiple forms in your view. You'll have to add some styling in your CSS files.
One easy way to execute different actions on different button within the same form is to distinguish button click by their name:
Example code is:
View:
#using (Html.BeginForm("MyMethod","Controller"))
{
<input type="submit" value="b1" name="b1" />
<input type="submit" value="b2" name="b2" />
<input type="submit" value="b3" name="b3" />
}
Controller:
[HttpPost]
public ActionResult MyMethod(string b1, string b2, string b3)
{
if (b1 != null)
{
return Button1Click();
}
else if (b2 != null)
{
return Button2Click();
}
else
{
return Button3Click();
}
}
public ActionResult Button1Click()
{
return RedirectToAction("Index");
}
public ActionResult Button3Click()
{
return RedirectToAction("Index");
}
public ActionResult Button2Click()
{
return RedirectToAction("Index");
}
i want to change grid date when the user change drop down values with ajax.
this is my C# code:
public ActionResult Index(string name)
{
ViewBag.Drop = db.Students.Select(r => r.Fname);
var model = from r in db.Students
where r.Fname == name
select r;
return View(model);
}
and this is cshtml file:
#using (Ajax.BeginForm("Index", new AjaxOptions
{
UpdateTargetId = "grid",
HttpMethod = "GET"
}
))
{
#Html.DropDownList("name", new SelectList(ViewBag.Drop));
<input type = "submit" value = "submit" />
}
<div id= "grid">
</div>
my problem is that when i change drop down values all of views are shown again. i don't want to see new view , just want to change grid data. how can i do that?
Do you have an action method which returns only the Grid data ? if not, create one
public ActionResult GridData(string name)
{
var gridItems=repo.GetCustomers(name).ToList();
//the above method can be replaced by your
// actual method which returns the data for grid
return View(model);
}
I am simply assumuing you have a Customer model with properties called FirstName and LastName and you want to show a list of Customers in the Grid. You may replace those with your actual class names and properties.
Make sure you have a view called GridData.cshtml which will render the HTML markup for your Grid
#model IEnumerable<YourNameSpace.Customer>
#{
Layout=null;
}
<table>
#foreach(var item in Model)
{
<tr><td>item.FirstName</td><td>item.LastName</td></td>
}
I would write simple (and clean) code like below instead of using Ajax.BeginForm
#Html.DropDownList("name", new SelectList(ViewBag.Drop));
<div id= "grid"></grid>
<script type="text/javascript">
$(function(){
$("select[name='name']").change(function(){
var url="#Url.Action("GridData","YourControllerName")"+"?name="+$(this).val();
$("#grid").load(url);
});
});
</script>