ASP.Net MVC 3 Drop Down List - ajax

I am developing an ASP.Net MVC 3 Web Application. One of my Razor Views contains a few Textboxes and a Drop Down List. When the User selects an option from the Drop Down List, I need a Partial View, or something like this, to appear below the Drop Down List preferable without a post back.
The thing is, it isn't as easy as a simply JQuery Hide and Show for the Partial View, when the User selects an option from the Drop Down List, I need their option to be sent to a method in the Controller, perform some logic based on this option, and then return some data to the Partial View.
I haven't really got much experience with AJAX, but I get the feeling this is the technology I need to use in order to fulfil my problem.
Has anyone ever had to code anything similar to what I have described above? And if so, is AJAX what I need to use?
Also, if anyone knows of any tutorials or code snipets I could look at to help, that would be greatly appreciated.
Thanks.
UPDATE
I have followed Ryan's answer, but unfortunately I am still having some problems. I have created the following JavaScript file which is then referenced in my View
$(document).ready(function () {
$("#myDDL").change(ChangeEventOfDDL);
function ChangeEventOfDDL(){
var dropDownValue = $('#myDDL').val();
//alert(dropDownValue);
$.ajax({ type: "GET",
url: '#Url.Action("SomePartialView","testAjax")',
data: {
id: dropDownValue
},
success: function(data) {
$('#someDivToLoadContentTo').html(data);
}
});
}
});
View
<select id="myDDL">
<option></option>
<option value="1">F1</option>
<option value="2">F2</option>
<option value="3">ST1</option>
<option value="4">ST2</option>
</select>
<div id="someDivToLoadContentTo">
</div>
My Controller then looks like this
public class testAjaxController : Controller
{
//
// GET: /testAjax/
LocumEntities context = new LocumEntities();
public ActionResult SomePartialView(int id)
{
var test = "Hello World";
return View(test);
}
}
However, my method 'SomePartialView' never gets hit. Does anyone know why?
Thanks.

Yes Ajax would be the easiest thing to use here. There are plenty of good Ajax tutorials around, just remember that what Ajax does is effectively a background POST, so you can do everything you would normally do with MVC, except within an existing page.
The way I would get this to work would be to have your code something like this:
public class SomeController{
public ActionResult SomePartialView(){
// Do some logic
return View("SomePartial");
}
}
Your Ajax would be something like:
function ChangeEventOfDDL(){
$.ajax({
url: '#Url.Action("SomePartialView","Some")',
success: function(data) {
$('#someDivToLoadContentTo').html(data);
}
});
}
I hope that helps at least a little bit.
Crucially with Ajax, you can add a data object to the function, which is passed as a querystring. This means you can send values from your page quite easily with ajax. Working with the above example, the Javascript would be:
function ChangeEventOfDDL(){
var dropDownValue = $('#ddl').val();
$.ajax({
url: '#Url.Action("SomePartialView","Some")',
data: {
id: dropDownValue
}
success: function(data) {
$('#someDivToLoadContentTo').html(data);
}
});
}
The Id value is linked with the parameters of the method in your MVC class:
public class SomeController{
public ActionResult SomePartialView(int id){
// Do some logic
var model = MakeModelWithSupplierId(id);
return View("SomePartial",model);
}
}
And there you have an interactive partial view that has been populated with the value from your drop down.

Since a controller can also return a partial view, you can do the following:
$('#idofyourdropdown').change(function () {
var theValue = $(this).val();
$.post('#Url.Action("Action","Controller")', {nameOfParameter: theValue, function(data) {
$('#divWhereYouWantToAttachData').html(data);
});
});
On the change event of your dropdown, send the selected value to your desired controller action, which will pass it to the partial view and return the rendered html. The html is received in the data var and can be attached to the dom, wherever you want it (see jQuery documentation for this).

This is a common use case.
What you need to do is
create a controller method that can take the parameters you need (read about MVC model binding before you do so)
write javascript that will harvest the data you want from your form and make a call to your new controller method and render the results below
In jQuery it goes something like this:
$("#yourDIV").load('/area/controller/method', { property1: 'asasd', property2: 'asdasdadfa'})
The second parameter of this call should be prepared based on the data you harvest from your form. (if you don't know how, then learn javascript)

Related

Accessing model data, from MVC3 partial view, in controller without passing it explicitly in the view

I have a MVC3 partial view that is called with a model.
#model SomeModel
The model have an Id parameter.
In the view I call #Html.Action("SomeMethod", "SomeController")
Is there any way to access the Id parameter in the SomeMethod ActionResult without passing it explicitly like this:
#Html.Action("SomeMethod", "SomeController", new {"Id" = Model.Id})
The problem is that I can not change the source code of the partial view. And I need the Id value. The Id is not used in the partial view so I can not access it via JavaScript.
Is the model passed to the HttpContext and is there any way to pass it?
EDIT: The thing is that I am developing a plugin for nopCommerce, like the ones that are offered by nop-templates. nopCommerce is an open source software and I can change the code, but the plugin will be shipped separately, so it is not recommended to make changes in nopCommerce views and the view that I am referring to is such.
When you can't change the sourcecode of the partial view, there is no way of getting to the id value in your controller. Its completely decoupled as thats one major point of the MVC pattern.
You have to explicitely pass it as a parameter to your action.
A dirty workaround might be to store that id somewhere in the Session.
In my project i fill my state drop down list by country id like this
in my view
i pass country id to my controller ActionResult like this
<script type="text/javascript">
function cascadingdropdown() {
var countryID = $('#countryID').val();
$.ajax({
url: "#Url.Content("~/City/State")",
dataType: 'json',
data: { countryId: countryID },
success: function (data) {
alert(data);
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
$.each(data, function (index, optiondata) {
alert(optiondata.StateName);
$("#stateID").append("<option value='" + optiondata.ID + "'>" + optiondata.StateName + "</option>");
});
},
error: function () {
alert('Faild To Retrieve states.');
}
});
}
</script>
in my controller i have action
public JsonResult State(int countryId)
{
var stateList = CityRepository.GetList(countryId);
return Json(stateList, JsonRequestBehavior.AllowGet);
}
i think this will help you ....

How do I do an ajax call using jQuery to an MVC3 controller using the following

I have an input
<input type="button" id="test" value="test" />
My action on the 'Home' controller:
public ActionResult DataUsage(DateTime startDate, DateTime endDate, string userName)
{
var data = FetchDataFromDB(startDate, endDate, uName);
return PartialView("DataUsageChartViewPartial", data);
}
The div I want to load the result form DataUsage in
<div id="myChart"></div>
jQuery code
$(function() {
$("#test").click(function () {
$.ajax({
url: '/Home/DataUsage',
type: 'POST',
data: { startDate: $('#startDate').val(), endDate: $('#endDate').val(), userName: $('#userName').val() },
success: function (result) {
alert("success " +result);
},
error: function (err) {
alert("error "+err);
}
});
return false;
});
}
);
When I click the button I want the div(myChart) to be populated with the result from the action in the controller.
I'm not sure if my jQuery is correct as I keep getting an error and the breakpoint in my controller/action is never hit.
Can someone please tell me what I'm doing wrong and how to correct it
Make sure that the format of the date you entered in the textbox is correct and matches your server side culture settings. For example depending on the culture your application is configured to, 12/15/2012 and 15/12/2012 might indicate the same date to the user depending on where he comes from and yet the default model binder will use the current culture settings.
Also to debug those kind of problems please use a javascript debugging tools such as FireBug and inspect the AJAX request. If you had done that you would have seen the exact error message sent from the server which in your case should be something long the lines of: 15/12/2012 is not a valid DateTime.
Dude the issue in your code for the starters is that you have specified Post method for the Ajax to call the controller , whereas as per your code which you have put shows that the method is available in get method .
Simplest way out is put [HttpPost] annotation on the controller action method.
i.e the method in your controller looks like :
[HttpPost]
public ActionResult DataUsage(DateTime startDate, DateTime endDate, string userName)
{
var data = FetchDataFromDB(startDate, endDate, uName);
return PartialView("DataUsageChartViewPartial", data);
}
So this will solve the problem of the breakpoint not getting called.
Other thing suggested is always user Url.Action(...) Method when you want to give urls to be called from ajax or wherever . Else it may create problems when deployed etc.
Maurice,
I think it could well be a very simple case of not having the correct url being called. You should try using the helpers in mvc:
url: '#Url.Action("DataUsage", "Home")'
Also, you might want to decorate your action with HttpPost to ensure that it's in step with your ajax type, i.e:
[HttpPost]
public ActionResult DataUsage(...)
this should take you one step closer, if not solve the issue completely.
The final step is to ensure that you have a div called 'myChart' inside your 'calling' view, then populate it as thus:
<div id='myChart'></div>
success: function (result) {
$('#myChart').html(result);
}
hope this helps

ASP.NET MVC 3 - How to execute code after leaving a View?

I'm in some trouble here. I have a view in which a company can thumbs up or down users of our site. The users are listed in a table and a column has the little hand images for the company to vote for or against the user. I had programmed an ActionLink there, however, I don't want a postback to happen every time a company vote on a user.
I decided to fill a list with the user IDs the company votes on and then, when leaving the page, a filter would intercept the request, get the list and process the votes. In this post I was taught how to initialize Filter parameters when calling the Action, but as you can see, I need a way for the Filter to get the Lists when the user exits the View, not in an Action.
I wouldn't want to use code-behind because, paired with MVC, it is not a best practice, but postbacks are not an option either.
Here's what I have so far:
public ActionResult ListUsers()
{
// Create a List with user models and send it to a View,
// which generates a WebGrid
return View(userList);
}
public class PromoteUsersFilter : ActionFilterAttribute
{
public int[] UsersToPromote { get; set; }
public int[] UsersToScrewWith { get; set; }
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
//insert promoting logic here
}
}
I believe there is a simple way of doing it, since most websites have this funcionality. Can anyone guide me with this?
Why not use AJAX that calls into your controller methods? If you set up your json properly, it will still be deserialized into an object, too.
This is OK even in the MVC mindset as far as I know. If you need to persist your data, but not update the entire page it is the only way that I know. You can even swap out entire partial views using AJAX.
I think the common misconception here is that the View portion (of MVC) is not just one page, but actually made up of a number of views smashed into the one page. So, updating one of those views separately does not really break the pattern.
Definitely go for the AJAX solution:
It could look like this in your view:
<div>
<span class="cssUpvote" id="upvote"><span>
<span class="cssDownvote" id="downvote"></span>
</div>
with some Jquery
<script>
$(document).on('click', 'upvote', function (event) {
$.ajax({
type: 'POST',
url: '/Votes/Upvote',
data: { id: companyId }
});
});
$(document).on('click', 'downvote', function (event) {
$.ajax({
type: 'POST',
url: '/Votes/Downvote',
data: { id: companyId }
});
});
</script>
And then your actions on the Controller
[HttpPost]
public ActionResult Upvote(int id)
{
//Do something with the (company)id
return Json();
}
[HttpPost]
public ActionResult Downvote(int id)
{
//Do something with the (company)id
return Json();
}

MVC: Best way for a hyperlink to post back to an ActionResult

I'm using a Html.BeginForm but I need a hyperlink to trigger a postback to a ActionResult (similar functionality to a LinkButton). I don't think that I can use an ActionLink because i'm not routing to a view with the same name as the ActionResult (or have I misunderstood :S).
Any help would be appreciated.
Thanks
I think you have two options (though the first isn't as flexible and can get messy)
1) style your submit button like a hyperlink (easy, but you'll probably end up using Html.BeginAjax or something like that)
2) Style a div, ActionLink, or some other element and serialize the form data on posting back using jQuery
If you can better describe the data being returned, we can better customize the dataType and success parameters below.
$(function () {
$('#myButton').click(function (e) {
e.preventDefault();
$.ajax({
url: '/MyController/MySuperAction',
type: 'POST',
data: $('#formId').serialize(),
dataType: 'json',
success: function (xhr_data) {
// in this particular example, you'll
// parse your JSON returned.
}
});
});
});
Edit
So, you're controller could look like
public ActionResult MySuperAction(FormCollection form) {
// I don't recommend using FormCollection
// You should stick to the view model pattern
// process your form
return Json(new { MyValue = "Textbox value" });
}
And you'd need to modify the success function above to something like
success: function(xhr_data) {
$('#MyTextBoxID').val(xhr_data.MyValue);
}

Multiple Renderactions in View MVC3

I have multiple renderactions in a MVC3 view.
I'd like to get a partial View and then the results as the parialviews get in.
(like some placeholders on the page and then the page gets filed up with the renderaction results as the partialviews poor in).
I now have several Html.RenderAction("Action", "controller"); in with different actions on the Main view returning some partial views to be rendered. How do I get them async in return instead of waiting with the render until the last one pops in?
Do I need some ajax or is this done using the AsyncController?
I always prefere to use jQuery ajax. You can simply return PartialView as a ajax action result and then in the jQuery (on the browser side) replace content of specipic part of you page with just returned PartialView.
Quick and easy and no page reload!
Take look a this:
$.ajax({
type: "POST",
data: { "supporterId": supporterId },
url: '#Url.Action("ShowDetails")',
success: function (result) {
$("#popupDetails").html(result); - here you are replaceing content of you page with partial view returned by the action
},
error: function (error) {
alert("error");
}
});
And here is the action:
public ActionResult ShowDetails(int supporterId)
{
Supporter supporter = ... //get supporter object from the database
return PartialView("Details", supporter);
}

Resources