BeginForm() take complex input value into routing - c#

I have a little problem with binding <input> value into routing of the beginForm GET action when submitting.
Firstly, the relevant code :
[Route("Company/{companyID:int}/MarketOffers/{PagingParam.PageNumber=1}")]
public ActionResult MarketOffers(int companyID, PagingParam pagingParam)
* This is declaration of action that I am dealing with. PagingParam have property PageNumber of int type.
#using (Html.BeginForm(RouteDataHelper.ActionName, RouteDataHelper.ControllerName, FormMethod.Get, new { companyID = Model.Info.CompanyID }))
* In the BeginForm I am only using companyID because PageNumber will vary depending on what the user clicks on the website and because of that it's not supplied here.
<input id="PagingParam.PageNumber" name="PagingParam.PageNumber" type="hidden" value="1">
* This is input which value should be appended to URL. It's inside the form which generation code you see above. The value changes by javascript just before submitting the form.
When I input link like :
http://localhost:38120/Company/2037/MarketOffers/3
* Everything is ok. PagingParam.PageNumber sets its value to 3. This is desired behaviour.
But when I submit the form with PagingParam.PageNumber input field then my URL looks like :
http://localhost:38120/Company/2037/MarketOffers?PagingParam.PageNumber=2
Instead of
http://localhost:38120/Company/2037/MarketOffers/2
I exactly know that I could deal with that and change form action value using javascript+JQuery but I have a feeling that there is a way to do this automatically in MVC without writing JavaScript.
So the question is : Can I do something to automatically generate desired link when I am passing form which action is (for example) "/Company/2037/MarketOffers" and append PagingParam.PageNumber to generated URL without writing JavaScript?

All inputs inside a form that make a GET have their values added as query string parameters because a browser has no knowledge of the routes on your server.
Its not possible to generate ../Company/2037/MarketOffers/3 without using javascript to modify the action attribute of the form

Related

Get data-id value of textbox on form submit

I have a textbox set-up, like so:
#Html.TextBoxFor(m => m.NewVehCode, new {data_id = "" })
When a user selects a vehicle, the description of the vehicle becomes the value of the textbox and the vehicle code (which is what I want to send to DB) becomes the data-id (not full code but I set the values like this):
$("#NewVehCode").val(vehDescription);
$("#NewVehCode").attr("data-id", vehCode);
This all works fine, except for the fact that when I submit, MVC grabs the value of the textbox.
Is there a way I can on submit, get the data-id of that textbox instead of the value?
Note that I'm not using .js to gather the data. Form calls a controller action that sends the model directly to the controller.
There is no way to submit values of "data" properties. I am not sure why you wanted to use data property (is that a requirement or not, not sure). But you can have a hidden property in the form so, when user selects a vehicle, along with data property of text box , update this hidden value. This hidden value will be submitted back to form.
Stephen Muecke's comment helped me trigger this solution:
I've added a hidden textbox to use for the vehicle code, and made the textbox that shows the description a standard textbox with no data binding.
<input id="newVehInput" readonly="readonly" class="longInput" type="text">
#Html.TextBoxFor(m => m.NewVehCode, new { style = "display: none"})
This way I can use the value with no issues:
$("#newVehInput").val(vehDescription);
$("#NewVehCode").val(vehCode);
(Will mark as answer in 2 days)
Add a hidden textbox to your html which you post back on submit
In your model:
public string Id {get;set;}
Render it in the view with a hidden class
And with js.
$("#vehicleList").on("change",function(){
$("#Id").val($vehCode)
})
When you submit the value of id should be set in your model
You can have a hidden field hold the Updated value.
HTML:
<input type="hidden" id="HiddenVehCode" name="HiddenVehCode" Value="0"/>
JS
$("#HiddenVehCode").val(vehDescription);
Note: you should have the model set up so that HiddenVehCode will reach the actionMethod on Form Submit.Something Like,
public int HiddenVehCode {get;set;}

C# MVC routing in FormMethod.Get: How to use route from route table

I have a FormMethod.Get that takes two parameters from a mostly read only form. These two parameters are the only query parameters needed to display all the other values on the read only form so they are text boxes (most of the values are DisplayFor() or disabled). Normally I can navigate to my read only form by typing .../Home/Edit/S6/B043. However, because this is a form submission it shows a URL like this .../Home/Edit?Location=S6&Facility=B043. How do I get it to show my route of .../Home/Edit/S6/B043 when I submit the form to get the rest of the data? Or do I have to go back to my original plan of using javascript with window.location.href =.
Thank you.
#using (#Html.BeginForm("Edit", "Home", routevalues, FormMethod.Get, new { id = "get-card" }))
{
// code here
}
Is there any special reason why you want to display your URL different? Whenever you submit(GET) the form the URL will have all the values and parameters you are sending back to your controller, if you are worried because some one will access the site using a URL like .../Home/Edit/S6/B043 then you can add that custom URL to your RoutConfig file like this.
routes.MapRoute("mycustomUrl", "Edit/{param1}/{param2}",
new { controller = "controllerName", action = "Edit",
param1 = UrlParameter.Optional,
param2 =UrlParameter.Optional });
After that you can call your view with .../Home/Edit/S6/B043 and will work.
If you want to have a friendly URL you can use POST that way you will not see all the parameters on the URL but everything depends on what you want to accomplish.
You could always hand write the form tags and use the UrlHelper to create the URL. It will then be created server side and show appropriately as you want it.
<form id="get-card" method="get" action="#Url.Action("Edit", "Home", routevalues)">
<!-- code here -->
</form>

Pass Value from View to Controller - MVC

i have a list of thumbnails for the user can select one of the image.
onclick on the thumbnail open a larger image into a form.
What im trying to do now is send the id of the image selected to my controller.
Note: im using MVC 4.
how can i do that?
someone can help with this pls?
Thanks in advance:
Here is my code:
#foreach (var p in ViewBag.Images)
{
<li>
<a href="~/Files/#p.Name" onclick="swap(this); return false;">
<img src="~/Files/#p.Name"/>
</a>
</li>
}
when selected is going this img tag in my form:
<img id="main" src="" >
using this javascript for this event:
function swap(image) {
document.getElementById("main").src = image.href;
}
what i have to do now?
i trying with <input type="hidden" name="Img_Id" value="Viewbag.??????"/>
to pass this value to my controller??
First, some terminology help: You can't pass a value from the view to the controller action, the view is rendered after the controller action completes.
What you want to do is pass data from the client (web browser) to a controller action, using form fields.
In your javascript swap method, you could set the value of the Img_Id field to be the value for the selected image. When the form is submitted, the Img_Id will be posted as form data, and can be accepted as a parameter in the action.
You can use JQuery (or something else) to perform the client side actions.
Here's an example (not tested though!):
First add the ID as a data attribute on the element:
<a href="~/Files/#p.Name" data-id="#p.ID" onclick="swap(this); return false;">
Then some javascript to save that to form (using jquery here):
function swap(image) {
document.getElementById("main").src = image.href;
$("input[name='Img_Id']").val($(image).data("id"));
}
To pass a value back to your controller, you either need to submit a form, or else make an AJAX request to your controller.
In the first case, you'd need to update the value of your hidden field with javascript, and then either wait for the user to submit the form, or trigger a submit through javascript depending on what your needs are.
If you want to do an ajax request, it would be more or less the same thing, but you don't need a hidden field to store the value.
You could use jQuery in your swap function. See here for the official documentation.
If you chose to use this approach, and assuming you place your JavaScript in a separate file, then make sure you get the path for the action and controller and pass that in too.
var url = #Url.Action("Index","Home");
Therefore you may call: onclick="swap(this.id, url)"

How to get the value from a custom attribute of a button in ASP.NET MVC

say for instance I have the following button in a form in asp.net mvc 3 app:
<input type="submit" name="command" value="Click me" data-custom="D" />
I know how to get the value from the button.. however do I get the data-custom attr value in an action method? Thank you very much!!
Edit:
I should note that I'm not allowed to use javascript at all since this is a mobile version of the site for devices that do not support javascript..
however do I get the data-custom attr value in an action method?
No you don't. There is nothing in the HTML specification that indicates that data-* attributes should be sent to the server when submitting a form. So if you want to get that value you will need to use javascript. One technique consists in subscribing to the submit event of the form and then automatically injecting a hidden field into that form which will be populated from the data-* attribute of the submit button. This way the value will be sent to the server.
But since I suspect that what you are trying to achieve here is that you have multiple submit buttons and you want to know which button was clicked in your controller action. In this case you could use the following:
<button type="submit" name="btn" value="S">Save</button>
<button type="submit" name="btn" value="D">Delete</button>
...
and then have your controller action take an argument called btn.
But personally I prefer to use separate actions otherwise it makes the controller action very ugly since it will contain lots of if statements. Here's a nice blog post I would invite you to checkout.
A custom attribute is not passed through get or post; only values do.
You can grab the custom attribute value from client side (for example using jQuery .attr() function) and add it to your form data before submitting it.
as far as I know you can't get data directly from data-... . you can write javascript to get this value.
Only the value and the name of the form element are posted within a form and any data-* cannot be passed.
You can consider a workaround using JavaScript. The idea is to so somehow merge the data-custom value to your value attribute.
$("input[type=textbox][data-custom]").each(function(index, value) {
$(value).attr("value", $(value).attr("value") + "$$$" + $(value).attr("data-custom"));
});
And from your action method, use data.split("$$$")[1] to get data-custom.
Hope this helps

Put current route values/url in form post

In my master page, I have a language dropdown menu. When the user selects a language from the dropdown, a submit sends the currently selected language to the "Translate" method in my controller. After which it should redirect to the url it was before the translation submit so it can show the exact same page, but now in the newly selected language.
How would I best go about this? Should I send the current url somehow in a hidden field? Or can I maybe send the current routevaluedictionary, so my translate method can redirectToRoute directly?
Or maybe there is an entirely better way?
--EDIT--
Because I want my bookmarks to include the site language too, all my exposed actions have a siteLanguage parameter too. If I could somehow efficiently show the user a bunch of regular (GET) links where the siteLanguage parameter is filled in with the relevant value, that would be even better. But as far as I know, there is no way to put links in a dropdown except with java maybe.
I have a similar situation, and I solved it slightly differently.
Because my master page had functionality in it, I created a new base controller class (that inherits from Controller) and all my real controllers inherit from my custom class.
Then, I implement OnActionExecuting in the base class to do some common work.
Then, in your masterpage, if you have a form like this, it will submit to the current URL with a GET request and add the language as a querystring parameter:
<form id="language" method="get" >
<select name="language">
<option value="en">English</option>
<option value="es">Spanish</option>
...
</select>
</form>
Use jQuery to wire it up to autosubmit, etc.
You could look for a language parameter in the querystring in your base controller class and set the flag that tells the real controller method which language to use. In the model, you directly go to the real controller to regenerate the page and avoid a redirect.
Note, this only works universally, if you are not already using querystring parameters.
If this doesn't work for you, you could also use your current method, but include the URL to be redirected to in a hidden field like this:
<%= Html.Hidden("redirect", Request.Url %>
public ActionResult Translate(string _lang){
switch(_lang){
case "English":
return View("English");
case: "French":
return View("French");
default:
return View("English");
}
I would personally do it like this
I would put the return url in the querystring, just like forms authentication does when it redirects to the login page.
Include the returnUrl in the routeValues when you do your Translate request.

Categories

Resources