Reputation: 349
I have a view that contains a Google map with a default zoom level and position set on a country. The default position to show on the map comes from DB and what I do is that I have a [HttpGet]Index action that fetches this information, sends it to the view and then in the view I use JS to draw the map (just usual google map stuff to draw a simple map).
Then just above the map div, I show a textbox and a search button. So the user types in an address and presses the search button, I post the value of textbox to a [HttpPost]Index action. Now I want to pass this value to [HttpGet]Index action so that it goes and fetches data from DB for that address, send it to the Index view so that the map is redrawn with that particular address set as the center of the map and showing the address in the textbox as well.
Any suggestions on how can I do this?
The way I have tried (and it didn't work) is to call the Get version of Index action and pass the address to it by using TempData dictionary. But all i see is an empty/blank page.
Here is how my HttpGet Index action looks:
[HttpGet]
public async Task<ActionResult> Index()
{
// I fetch the info from DB here put it inside ViewBag and call the view
return View();
}
This loads the info correctly and the map is drawn as it should when the URL controller/Index is hit first time in the browser.
The markup for the textbox and search button is:
<form class="form" id="searchForm" action="@Url.Action("Index", "Default")" method="post">
<div class="form-group">
<div class="row">
<div class="col-xs-9 col-sm-9 col-md-10">
<label for="address" class="sr-only">Search for address</label>
<input type="text" class="form-control" id="address" placeholder="Search for address" name="address">
</div>
<div class="col-xs-3 col-sm-3 col-md-2">
<input type="submit" class="btn btn-block btn-success" value="Search" />
</div>
</div>
</div>
</form>
and finally here is the HttpPost Index action:
[HttpPost]
public void Index(String address)
{
TempData["address"] = address;
Index();
}
So when I submit the form, I want that it gets posted to the HttpPost Index action and then it passes the value to the HttpGet version of it which will eventually get data from DB and get the view with updated map. But all I see is a blank page.
Any help?
Upvotes: 7
Views: 54594
Reputation: 1946
that mechanism I told u about ...
if I have an Address entity
public class Address
{
public int Id { get; set; }
public string Street { get; set; }
public string House { get; set; }
public int Floor { get; set; }
}
and this is the controller actions AddressController
[HttpGet]
public ActionResult Index()
{
var model = new SearchAddressesViewModel();
// you can here also fetch all the addresses in your db ...
//but this is not a good approach also, but if you need to do that it's easy
// fetch data base and get all addresses
//model.AddressesFound = db.Addresses.Select(a => new AddressModel
//{
// Street = a.Street,
// House = a.House,
// Floor = a.Floor
//}).ToList();
return View(model);
}
[HttpPost]
public ActionResult Index(SearchAddressesViewModel model)
{
if (!ModelState.IsValid)
return View(model);
// fetch data base and get addresses based on the search criteria in
//model.SearchCriteria
// for example:
//var addresses = db.Addresses.Where(a => a.Street == model.SearchCriteria);
//add found addresses to model
//model.AddressesFound = addresses.Select(a => new AddressModel
//{
// Street = a.Street,
// House = a.House,
// Floor = a.Floor
//}).ToList();
return View(model);
}
and here is my View Index.cshtml
@model SearchAddressesViewModel
@using (Html.BeginForm("Index", "Address", FormMethod.Post))
{
@Html.LabelFor(m => m.SearchCriteria);
@Html.TextBoxFor(x=>x.SearchCriteria);
@Html.ValidationMessageFor(m => m.SearchCriteria, "");
<br />
<input type="submit" class="btn btn-block btn-success" value="Search" />
}
@if (Model.AddressesFound != null)
{
<table>
<thead>
<tr>
<th>Street</th>
<th>House</th>
<th>Floor</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.AddressesFound)
{
<tr>
<td>@item.Street</td>
<td>@item.House</td>
<td>@item.Floor</td>
</tr>
}
</tbody>
</table>
}
and here it the view model I used SearchAddressesViewModel
and AddressModel
public class SearchAddressesViewModel
{
[Required]
[Display(Name = "Search for address")]
public string SearchCriteria { get; set; }
public IList<AddressModel> AddressesFound { get; set; }
}
public class AddressModel
{
public string Street { get; set; }
public string House { get; set; }
public int Floor { get; set; }
}
also you can use partial view for AddressModel
in the view based on your case.
I hope that you got my point... thank you
Upvotes: 2
Reputation: 1946
like that
[HttpPost]
public void Index(String address)
{
TempData["address"] = address;
RedirectToAction("Index");
}
you see it blank because you are redirecting RedirectToAction("Index");
and storing data in TempData and u r not using it in the index Get method
[HttpGet]
public async Task<ActionResult> Index()
{
// I fetch the info from DB here put it inside ViewBag and call the view
// you must check for the temp data
if (!string.IsNullOrWhiteSpace(TempData["address"].ToString()))
{
ViewBag["result"] = TempData["address"];
//and use you viewbag data in the view
}
return View();
}
Upvotes: 13