mvc Html.BeginForm different URL schema - c#

I'm creating a form for a DropDown like this:
#{
Html.BeginForm("View", "Stations", FormMethod.Get);
}
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"), new { onchange = "this.form.submit();" })
#{
Html.EndForm();
}
If I choose a value from my dropdown I get redirected to the correct controller but the URL is not as I would like to have it:
/Stations/View?id=f2cecc62-7c8c-498d-b6b6-60d48a862c1c
What I want is:
/Stations/View/f2cecc62-7c8c-498d-b6b6-60d48a862c1c
So how do I get the id= querystring parameter replaced by the more simple URL Scheme I want?

A form with FormMethod.Get will always post back the values of its form controls as query string values. A browser cannot generate a url based on your route configurations because they are server side code.
If you really wanted to generate /Stations/View/f2cecc62-7c8c-498d-b6b6-60d48a862c1c, then you could use javascript/jquery to build your own url and redirect
#using (Html.BeginForm("View", "Stations", FormMethod.Get))
{
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"))
}
var baseUrl = '#Url.Action("View", "Stations")';
$('#id').change(function() {
location.href = baseUrl + '/' $(this).val();
});
Side note: Submitting on the .change() event is not expected behavior and is confusing to a user. Recommend you add a button to let the user make their selection, check it and then submit the form (handle the button's .click() event rather that the dropdownlist's .change() event)

Remove "id"
from
#Html.DropDownList("id", new SelectList(ViewBag.Stations, "Id", "Name"), new { onchange = "this.form.submit();" })

Related

Routing without query string

I have added the following route before the default route
routes.MapRoute(
name: "RecordDefault",
url: "{controller}/{action}/{name}",
defaults: new { controller = "Person", action = "Record" }
);
I can hit the page I want using: sitename/Person/Record/John
But I have an global search in the navigation with the following code
#using (Html.BeginForm("Record", "Person", FormMethod.Get, new { #class = "navbar-form navbar-left" }))
{
#Html.TextBox("name", "", new { #class = "form-control", placeholder = "Search Name" })
}
When I submit the form the following URL is displayed: sitename/Person/Record?name=John
What do I have to do to ensure the URL is formatted without the query string parameter?
Thanks
Not the same as the posted duplicate, that marked answer does not resolve my problem and according to the comments it also didnt work for others.
Your form generates ../Person/Record?name=John because a browser has no knowledge of your routes (which is c# code running on your server). And the HTML standards require that the value of successful form controls be added as query string values when the method is GET.
In order to generate your preferred url (../Person/Record/John), you need javascript to intercept and cancel the default submit, and build a url to navigate to. Using jQuery:
$('form').submit(function() {
var baseUrl = $(this).attr('action');
// or var baseUrl = '#Url.Action("Record", "Person")';
var url = baseUrl + '/' + $('#name').val();
location.href = url; // redirect
return false; // cancel the default submit
});
Use form post FormMethod.Post instead of Get. So the value will be not appeared in querystring.
#using (Html.BeginForm("Record", "Person", FormMethod.Post, new { #class = "navbar-form navbar-left" }))
{
#Html.TextBox("name", "", new { #class = "form-control", placeholder = "Search Name" })
}
In your Controller add the following -
[HttpPost]
public ActionResult Record(string name)
{
//code for what needs to be performed.
return View();
}
In your view add the following code replacing your existing and check -
#using (Html.BeginForm("Record", "Person", FormMethod.Post))
{
#Html.TextBox("name")
<input type="submit" />
}

ASP.NET MVC 4.5 OnBlur event TextBox

I have a C# ASP.net MVC 4.5 solution. I want to create a form with automated address validation.
If you enter a zipcode and housenumber the streetname en city is looked up using an external REST API.
After filling in the housenumber there must be a call to a function in a controller (using AJAX) to look up the address, update the model data and show the result in the form. I can't figure out how to do this.
I was thinking about doing a form post (using AJAX) fired when the onBlur from the housenumber is called. But is this the best way ? Is it really the best way is posting back the whole form ?
Example so far:
<div class="col-md-7">
#Html.TextBoxFor(model => model.HouseNumber, new { #class = "form-control", #placeholder = "HouseNumber" })
#Html.ValidationMessageFor(model => model.HouseNumber, null, new { #class = "text-danger" })
</div>
When the TextBox HouseNumber lost focus I want to call the function 'ValidateAddress' in my controller 'AddressBook'. The function will lookup the streetname and city and will fill the model.Streetname and model.City fields.
Well, you could change your controller action to return the model as JSON:
public ActionResult ValidateAddress(YourModel model){
// Do your validation
return Json(model);
}
and then add an AJAX call to this action and fill your form in the callback:
$( "#HouseNumber" ).blur( function() {
$.ajax({
url: "/yourActionUrl",
type: "POST",
data: $("#yourForm").serialize(),
dataType: "json"
}).done(function( model ) {
$("#Streetname").val(model.Streetname);
$("#City").val(model.City);
});
});
You can have blur event on HouseNumber textbox
try this
#Html.TextBoxFor(model => model.HouseNumber, new { #class = "form-control", #placeholder = "HouseNumber" onblur = "alert('call some javascript function')"})
or
better use jquery function
updated:
$("#HouseNumber").blur(function () {
$.get("ControllerName/ActionMethod",{parameterName:value},function(data){
// extract values from data object and assign ut to your controls
});
});
make your get Mathod on controller with same model parameter
public ActionResult Login(LoginData model)
{
if (model == null)
{
model = new LoginData();
}
return View(model);
}
after filling hoseno Call your function if you want you can use ajax and redirect to your getmethod and pass your model
for validation use script validation so that you can remove or add according to your conditions.

Hook javascript to dropdownlist change

¡Hola!
My current task is to have a page where, with a dropdownlist, a user can select a deck title. Once a title is selected, the page should postback with details on that deck.
Here's what I've got at the moment:
#model IEnumerable<SCATChartsMVC.Models.Charts_DeckList>
#{
ViewBag.Title = "Index";
if (IsPost) { ViewBag.Title = "We posted back!"; }
}
<h2>Index</h2>
#{ var list = ViewData.Model.Select(cl => new SelectListItem
{
Value = cl.RecNum.ToString(),
Text = cl.DeckTitle.ToString()
});
}
#using (Html.BeginForm("Details", "Charts_DeckList", FormMethod.Post))
{
#Html.DropDownList("deckTitles", list, "---------select---------")
<input type="submit" name="submit" value="Submit" />
#Html.ActionLink("Details", "Details", "Charts_DeckList", new { id = list.ElementAt(4).Text }, "")
}
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script>
$("deckTitles").change(function () {
if ($("#deckTitles").val() != "") {
var test = {};
test.url = "/Charts_DeckList/Details";
test.type = "POST";
test.data = JSON.stringify($('#deckTitles').val());
test.datatype = "json";
test.contentType = "application/json";
test.success = true;
test.error = function () { alert("Error!"); };
$.ajax(test);
}
})
</script>
The input tag and ActionLink under Html.BeginForm were for my own testing purposes; the ActionLink works correctly if I specify the element. I'm hoping to be able to pass something similar back whenever a user clicks a selection, as opposed to whenever they hit the "details" button.
The submit input tag does not work. It does route properly to Charts_DeckList/Details, but the parameter in the action is always null.
I'm just getting into the whole MVC/Web rigamarole, so there's a lot I don't know that I'm not even aware I don't know. While I've seen a number of different resources on the internet suggesting different things, much of the web development jargon is lost on me at this point in time, and much of the way these things work under the hood is lost on me since VS seems to put together so much of it automagically.
Any pointers would be appreciated. Thank you.
barrick's suggestion below is correct!
I also had to move the script tags up into the BeginForm brackets, heads up.
You're not setting the ID of the DropDownList there, the first argument sets the name attribute of the dropdown (used to identify the value in the POST variable collection on server postback) - you'll need to add another argument to set the ID:
#Html.DropDownList("deckTitles", list, "---------select---------", new { #id = "deckTitles" });
You can then pick up the selected value in the jQuery as follows:
$("#deckTitles option:selected").val();

Routing Issue on asp.net mvc 5 GET

I am trying to get my product search URL to look like "Products/Search/{search term here}".
I am using attribute based routing and my controller action looks like this:
[HttpGet]
[Route("Products/Search/{searchTerm?}", Name="ProductSearch")]
public ActionResult Search(string searchTerm = "")
{
return View();
}
I have tried using the HTML Helper for BeginForm and BeginRouteForm (shown below) but have not had luck with either. The right action is being called, but my URL looks like "Products/Search?searchTerm"
BeginRouteForm
#using (Html.BeginRouteForm("ProductSearch", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
BeginForm
#using (Html.BeginForm("Search", "Products", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
I have gone through debugging and the right route is selected, the URL is just not displaying how I wanted it to. What am I missing?
Here is the solution I suggest -
You have the following controller Action -
[HttpGet]
public ActionResult Search(string searchTerm = "")
{
return View();
}
Let the view be -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click').click(function (e) {
var name = $("#search").val();
var url = '#Url.Action("Search", "Action")' + '/' + name;
window.location.href = url;
});
});
</script>
<input type="text" name="searchText" id="search"/>
<input type="button" value="click" id="click"/>
And when you click the button -
Do not forget to have proper route to be added on to the route configuration -
routes.MapRoute(
name: "searchaction",
url: "{controller}/{action}/{searchTerm}",
defaults: new { controller = "Action", action = "Search" }
);
The problem you think you are experiencing isn't because of anything about ASP.Net MVC. All Html Forms that use the method GET will translate all input elements into QueryString parameters. This is just a W3C standard.
If you want this to work, you'll have to write jQuery to throw an event before the form is submitted, take the text value from the input store it temporarily, empty the input box, and then update the action by appending the temporary value.
I don't think that BeginRouteForm works the way that you're expecting it to. According to the documentation, all that the method does is insert a <form> using the arguments provided. If you had provided something other than an empty string for the route value such as , new { searchTerm = "somesearchterm" }, you would see that show up in the Url as "/product/search/somesearchterm". As it is now, however, the form will be processed as normal, putting the search term on the Url as a normal query parameter.

Dropdownlist box in asp.mvc 2 and jquery [duplicate]

I have a code block in my MVC view as follows:
<%using (Ajax.BeginForm("MyAction", new { action = "MyAction", controller = "Home", id = ViewData["selected"].ToString() }, new AjaxOptions { UpdateTargetId = "Div1" }))
{ %>
<%=Html.DropDownList("ddl", ViewData["MyList"] as SelectList, new { onchange = "this.form.submit()" })%>
<%} %>
I want to set the value of ViewData["selected"] so that i can send it to the desired action.
Can anyone please suggest how can i do this?
thanks!
Instead of using a form, why not use a jQuery onChange event on your drop down?
$(document).ready(function() {
$("#ddl").change(function() {
var strSelected = "";
$("#ddl option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Home/MyAction/" + strSelected;
$.post(url, function(data) {
// do something if necessary
});
});
});
ViewData is not the place to pass data back to the server side. Values of html input controls within form tag are conveniently available in action method. You can get these values either from various types of action method arguments (model, formcollection etc).
Here is a link to free asp.net mvc ebook tutorial. Is a good resource for asp.net mvc.
Found solution at this post it is just small chnge
Yes, that’s right – only change is replacing:
onchange = “this.form.submit();”
with:
onchange = “$(this.form).submit();”

Categories

Resources