How to do MVC form with very simple lookup? - asp.net-mvc

We have a very simple MVC form with a dropdownlist which gets the user's selected city.
We have a list of cities and we know the average temperature (say) for each city.
Almost as a decoration (it's not a core function) for the form it would be nice to show the temperature for the selected city as the user changes it. Something like this:
This has to happen client side, I guess. Or is it AJAX?
At the moment our form is mostly out-of-the-box MVC4 EF auto built with scaffolding.
We populate the dropdownlist like so:
In the Controller:
ViewData("Cities") = GetCitySelectList()
and in the View:
#Html.DropDownListFor(Function(model) model.City, TryCast(ViewData("Cities"), SelectList))
... so pretty simple stuff.
There are plenty of tutorials for doing cascading dropdowns which are probably overkill for what we're trying to do here. Also if you google "javascript lookup mvc form" or similar a lot of the results tie you to using a framework (knockout? barebone?) which, again, I'm not familiar with and I don't know if I need for such a simple task.
In fact we're so geared to keeping it simple, and our city list is so short, it's almost worth doing it as a giant if then else in javascript (but, I know, yuk).
What's the simplest way to do this?

You can do it as follows:
Make an Ajax call on change on dropdown and then place the result in the corresponding div.
Html for result:
Temperature:<div id="temp"></div>
Ajax call :
$("#dropdownId").change(function () {
$.ajax({
type: "GET",
url: "Home/GetTemperature", // your url
contentType: "application/json; charset=utf-8",
data : {City : " + $(this).val() +"}
dataType: "json",
success: function (result) {
$("#temp").html(result); // place result in div
},
error: function () {
alert("Error.");
}
});
});
Your Action (C#):
[HttpGet]
public JsonResult GetTemperature(string City)
{
int temp = 30; // Get temp from your db..
return Json(temp,JsonRequestBehavior.AllowGet);
}
Your Action (VB):
<HttpGet>
Public Function GetTemperature(City As String) As JsonResult
Dim temp As integer = 30
Return Json(temp, JsonRequestBehavior.AllowGet)
End Function

You should use AJAX call to the server for the temperature. That's probably the "cleanest" way to achieve what you would like to have on your form.

Option 1: Using jQuery and make ajax call to fetch a temprature for the cityId passed and set the html of the temprature div or span container
Option 2: Eager Load on page as Javascript object
You could have eager load the cities and temprature into the JSON object and store it.
Here is the controller action code using JSON.Net for json serialization
public ActionResult myAction()
{
MyViewModel model=new MyViewModel();
List<City> cities=new List<City>();//fill the city id, temp
MyViewModel.CityJSON=JsonConvert.SerializeObject(List<City>);
return View(model)
}
View
#model MyViewModel
// other controls
#Html.HiddenFor(m=>m.CityJSON, new{#id='hdn-city-json'})
JavaScript
var cityList=JSON.parse($('#hdn-city-json')); // returns array of city obj
//do your stuff

If you are trying to avoid unneccesary requests to server, yes, you could eager load the whole collection. You can keep the data in a hidden <ul/> tag that you build on your View. Then, you can use jQuery to fire when the dropdown selection changes. But instead of making an AJAX call, you can lookup the temperature in the list instead and set the content of the target div to the return value of the lookup function.

Related

How can I accept JSON requests from a Kendo UI data source in my MVC4 application?

I am using the Kendo UI grid in my MVC3 application and am quite pleased with it. I am using a Telerik provided example, excerpt below, to format the data posted by the grid's DataSource ally, and all is good. However, I don't want to have to rely on code like this. I would like to get Kendo and MVC talking without the 'translator', i.e. this code:
parameterMap: function(data, operation) {
var result = { };
for (var i = 0; i < data.models.length; i++) {
var model = data.models[i];
for (var member in model) {
result["models[" + i + "]." + member] = model[member];
}
}
return result;
}
This function is a 'hook' that allows me to manipulated data before Kendo ajaxes it out. By default, the Kendo DataSource sends content-type form-encoded, but not quite right for the MVC model binder. Without this, I can still use a FormCollection and do my own binding, but that is not on.
When I configure the DataSource to send JSON, and change my mapping function to look like this
parameterMap: function(data, operation) {
return JSON.stringify(data);
}
I get the following data being send in the request, but now I have no idea how to get MVC to bind to this. Right now my only hope is to grab Request.Params[0] in the action method, and deserialize this JSON myself.
I don't think I should have to write any code to get two HTTP endpoints to communicate properly using JSON in this day and age. What am I doing wrong, or, what should I be looking at on my side, i.e. the receiver of the requests. I would really prefer to minimize my intervention on the client side to maybe just the stringify call.
No idea if this is still a problem or not since this is a rather old question, but I had a scenario where I was shipping up json data to my controller and I had to give it a "hint" on what the name was so that model binding would work correctly:
public JsonResult GetDatByIds([Bind(Prefix="idList[]")]List<Guid> idList)
In my scenario, kendo was serializing my data and giving it a name of idList[] in the form post rather than just idList. Once I gave it the model binding hint, it worked like a charm. This might be the same for your scenario.

In MVC3 how do I have a dropdown that shows/hides fields based on the selected value?

I have a dropdown of countries, and an address form. Depending on the country selected, I want to hide/show certain fields. I'm quite new to MVC and MVC3, what is the best way to do this?
I have on the page a 'DropDownListFor' that populates correctly. When this changes, I imagine I need to ask the server which fields to show/hide. I could perhaps put some JQuery into a change event that calls a method, and it returns some json saying visible:true for each field, but I don't know if that's ideal or even how to implement it (possibly $.ajax or something).
Any ideas?
Edit: I should add the hard part of this is asking the server what fields to show for each country as there are many countries and the possibilities are all stored in the database. I am accustomed to webforms not MVC so I would ordinarily postback and have serverside logic, but this isn't an option with MVC afaik...
I have deleted my first answer as it was irrelevant.
With MVC3 you can send an AJAX request to any method.
In HomeController.cs:
public List<string> GetFieldsToShow(string id)
{
// if you routing is left to default, the parameter passed in will be called 'id'
// Do what you gotta do...
List<string> listOfFieldsToShowBasedOnCountry = GetList(id);
return listOfFieldsToShowBasedOnCountry;
}
And in the AJAX call, something like...
$.ajax({
type: 'POST',
url: '/Home/GetFieldsToShow/' + valueOfSelectedDropDownItem,
/*etc...*/
success: function(data){
$(data).each(function(){
$('#' + this).show();
}
}
});

Assign values to ViewData from client using MVC

I inherited an MVC app and am a true novice at it coming from an ASP.NET environment. My problem is I can't manage to move variable data between my partial views and controllers. In ASP.NET this was pretty straight forward, not the case in MVC. So the following code fires when a Tab is selected from the client but I need to capture the selectedTabIndex value from the client and pass it to the controller.
function onTabSelect(e) {
var selectedTabIndex = 0;
selectedTabIndex = $(e.item).index();
alert(selectedTabIndex);
}
I considered using the ViewData object but there doesn't appear to be a way to make perform this task of assignment from within the function. So the following code would seem to be a ridiculous task and it fails anyway. (Remember, I am an extreme novice at this)
function onTabSelect(e) {
var selectedTabIndex = 0;
<% =ViewData["selectedTabIndex"]%> = selectedTabIndex;
}
I also considered using cookies but that doesn't seem to be a practical method either. In ASP.NET I could access the client controls using the .find method but this is a steep learning curve for me.
What are my alternatives?
If different tabs can be selected by the user between Save operations, you might need to consider binding some kind of click function (using jQuery) to set the selectedTabIndex javascript variable. Alternatively, you could set a hidden input's value to the selected tab index.
In either case, if you need the value in your controller (to set ViewData, ViewBag, some model data, etc) when a Save operation is submitted, you could submit the data via $.ajax and return some JSON from your controller
$('#SaveButton').click(function() {
$.ajax({
url: '/Controller/Save',
type: 'POST',
// you might need to serialize additional data you want to save here
// but you could create any JSON object before calling $.ajax
data: {"selectedTabIndex": selectedTabIndex}, // data to POST
dataType: 'json', // this indicates the type of data returned from controller
success: function(data) {
// you didn't really describe how to programatically set a tab,
// so "setToTab" is a guess
$('#tabID').setToTab(data.selectedTabIndex);
}
});
}
And your controller might look something like
public ActionResult Save(int selectedTabIndex)
{
// again, you might need different parameters to complete your Save
return JsonResult(new { selectedTabIndex: selectedTabIndex });
}
Data is sent to a controller via a HTTP POST. Create a hidden input <input type="hidden" name="selectedTabIndex"/> and set the value with javascript prior to POST. The controller can extract this value from the Form parameters, or it can be autopopulated in the Action method if the method contains a parameter matching the input name.
This is a non-ajax alternative to the answer provided by David.

Best practice for using web services (ASP.MVC)

Basically what I have is web services returning data in xml format. Once I do a call to a webservice to retrive data from web service function (GetUserList) i want to take that data and then dymaically display (no postback) the resulting information. I know several ways of doing this:
webservice sends data back to javascript, javascript then parses, replaces strings or text inside a div or child, or take the information retrieved and then put it into html table format through javascript.
Those are some of the idea's i've came up with, does anyone know the best practice to do this?
Using ASP.MVC (.Net)
It depends entirely on your application. I've both had the action return pure data (usually JSON, not XML) and handled the display in the client and had the action return a partial view. For most complex display scenarios, I think the partial view route is easiest. Essentially, you are returning just the portion of the page (HTML) that is going to be updated. You use javascript in the AJAX callback handler to replace the appropriate element(s) on the page with the HTML you get back from the server. Note that you need to be careful with event handler binding when you do this -- it's almost always the right thing to do to use live handlers in jQuery 1.4+ and rebind all but click handlers in jQuery 1.3.
Example: Assumes that you are calling an MVC action method that returns a partial view. This will call the show action on the foo controller every 5 seconds and update the containerToUpdate (presumably a DIV), with the html returned.
setInterval(
function() {
$.get( '<%= Url.Action( "show", "foo", new { id = Model.ID } ) %>',
function(html) {
$('#containerToUpdate').html( html );
});
}, 5000
);
Server side:
[AcceptVerbs( HttpVerbs.Get )]
public ActionResult Show( int id )
{
var model = ...
if (this.Request.IsAjaxRequest())
{
return PartialView( model );
}
else
{
return View( model );
}
}
The full view (for non-AJAX) may not be necessary -- you may want to just display an error if the user shouldn't be accessing this except through AJAX. If you do support both, just render the partial inside the full view where it's needed so that you reuse the partial view code.

ASP.NET MVC - Build Search Results into a Div

I'm new to ASP.NET MVC, but I need to perform a search for articles that match a selected category. The results of this query need to be written into a "search results" div overlay with DHTML- jquery, probably.
So, I need the results of an Action, but not to render a view. I was thinking I could use Json and then iterate over the resulting records, somehow.
Or is it easier to use RenderPartial... but how would I use this in this DHTML scenario?
Thanks.
I like the way Steve Sanderson describes in his ASP.NET MVC book. It dosnt work with JSON, but returns a partial. This makes it easier to have both: An Ajax and a non-Ajax version.
The cotroller returns a View or Partial depending on the type of request:
public ActionResult GetArticles(string category)
{
...
if(Request.IsAjaxRequest())
{
return PartialView("ArticleListPartial",articleModel)
}
else
{
return View("ArticleListPage",articleModel)
}
}
The search by default submits the from with with a Non-Ajax post:
<form id="articleSearch" method ="post" action="/Article/GetArticles" >
...
<input type="submit" value="Get the articles!" />
<form>
Then there is a Jquery snippet that kicks in when Javascript is available and submits the request via Ajax
<script language="javascript" >
$(function() {
$("#articleSearch").submit(function() {
$.post($(this).attr("action"), $(this).serialize(), function(modelResponse) {
("#articleResultContainer").html(modelResponse);
});
return false;
});
});
</script>
Hmmm, sounds like you are trying to do a filter?
If this is the case I think it's a bad idea trying to search within your html. I think a better approach would be to post back using jQuery, get your result set from whatever database you are using, and return that back to the view as apartial view.
When you are searching your database you should apply the filter at that point using sql, Linq2Sql or whatever you're using.
If you are still Hell bent on searching the HTML then I'd give each relevant div a class name of say class="DivSearchable". Then in jQuery you can do something like;
$('.DivSearchable").each(function() {
var text = $(this).val();
"Now test text for contents of your seach string"
if (BoolIfFound == true)
$(this).addClass("highlightClassName");
});
highlightClassName would set the background-color to something so you can see which divs contains the search string.
make sense?

Resources