Passing an array of values to Action using Ajax.ActionLink - asp.net-mvc

I would like to provide my Action with an array of integer values (based on selected checkbox values on a form). I am trying to use Ajax.ActionLink as follows...
<%= Ajax.ActionLink("Submit", "PrintPinLetters", "EPOC", new { selectedItemsToPrint }, new AjaxOptions { HttpMethod="POST", UpdateTargetId = "PrintConfirmation", LoadingElementId = "resultLoadingDiv", OnFailure="handleError"}, new { id = "btnPrintPinLetter" }) %>
but am not sure what to pass into the routeValue section. My Action in the controller is defined as...
[HttpPost]
public ActionResult PrintPinLetters(Int64[] selectedItemsToPrint)
{
Basically I am looking to pass an array (or comma separated list of ID values) in the 'selectedItemsToPrint'. This list would be build using the values defined by checkboxes (all named the same) in multiple rows of a table.
I have used Ajax.BeginForm but as this results in a nested form I was having unpredictable results when using older browsers (IE 7 and 8).

normally i would do the ajax myself with a jQuery call. You would set it up like this
instead of using Ajax.ActionLink(), use Html.ActionLink(.... {id = "myid"}). Dont forget to give your link an id
create an onready function
$(document).ready(function () {
$('#myid').click(function() {
var allElements = $('#container').find('input').serialize();
$.post(action, allElements, function (data) {
// add your code here to process the data returned from the post.
});
return false; // dont post the form
});
});
dont forget to set the name attribute of all of the input elements to selectedItemsToPrint so the binding will work correctly with your actionresult
The Html should look something like this
<div id="container">
<input type="checkbox" name="selectedItemsToPrint" value="somevalue0" />
<input type="checkbox" name="selectedItemsToPrint" value="somevalue1" />
<input type="checkbox" name="selectedItemsToPrint" value="somevalue2" />
<input type="checkbox" name="selectedItemsToPrint" value="somevalue3" />
<input type="checkbox" name="selectedItemsToPrint" value="somevalue4" />
<input type="checkbox" name="selectedItemsToPrint" value="somevalue5" />
</div>

Related

Passing route values to Html.BeginForm

I want the form to pass the values from the hidden inputs to the server and I also expected it to build the URL as
"localhost:9392/Ranking/Index/2?rankingType=SOMEVALUE&ageGroup=SOMEVALUE&week=SOMEVALUE"
but it shows like "localhost:9392/Ranking/Index/2?rankingType=rankingTypeID&ageGroup=ageGroupID&week=week"
#using (Html.BeginForm("Index", "Ranking", new { id = Model.CurrentRanking, rankingType = "rankingTypeID", ageGroup = "ageGroupID", week = "week"}, FormMethod.Post, new { id = "ageGroupForm" }))
{
<input id="ageGroupID" name="ageGroup" hidden />
<input id="rankingTypeID" name="rankingType" hidden />
<input id="week" name="week" hidden />
}
Why is that ? How do I pass the values and also have them show up as query string ?
Try this code:
#using (Html.BeginForm("Index", "Ranking"))
{
<input id="ageGroupID" name="ageGroup" hidden />
<input id="rankingTypeID" name="rankingType" hidden />
<input id="week" name="week" hidden />
}
and in your action method, decorate it like:
public ActionResult Index(string ageGroupID, string rankingTypeID, string week){}
but it shows like "localhost:9392/Ranking/Index/2?rankingType=rankingTypeID&ageGroup=ageGroupID&week=week"
That's because those are exactly the string values you're using:
new { id = Model.CurrentRanking, rankingType = "rankingTypeID", ageGroup = "ageGroupID", week = "week"}
It's not really clear why you're trying to set query string values for the exact form inputs you already have:
<input id="ageGroupID" name="ageGroup" hidden />
<input id="rankingTypeID" name="rankingType" hidden />
<input id="week" name="week" hidden />
If what you're trying to accomplish is to have those values be on the query string (as a GET request) instead of in the request body (as a POST request) then all you have to do is change your form method to a GET:
#using (Html.BeginForm("Index", "Ranking", new { id = Model.CurrentRanking }, FormMethod.Get, new { id = "ageGroupForm" }))
HTML form inputs are automatically added to the request, that's how forms work. You don't need to try to do it manually.
Though it's strange that you're doing this at all. Your inputs are hidden, which usually means you don't want to concern the user with them. But you're also showing them on the URL, which may be confusing to the user (or may even be suspicious to the user). You also aren't setting any values to those hidden inputs, unless you have something else not included here which does that?
Either way, your form will automatically include its inputs in the submitted request.

ASP.NET MVC - why ViewBag prop return "value" string instead of actual value?

I need to pass some flag into a view and get it back.
But requirements are:
this flag is not part of model
and it must not be stored in session or such.
I mean - flag visibility scope should be - current page for current user only.
I tried to put it into a ViewBag like this:
public ActionResult Product_Add()
{
ViewBag.IsNew = true;
ViewData["IsNew"] = ViewBag.IsNew;
ViewBag.RecordActionName = "Add";
return View("Product_Edit");
}
And then use this code in *.cshtml:
<input type="hidden" name="IsNew1" value="#ViewBag.IsNew" />
<input type="hidden" name="IsNew2" value='#ViewData["IsNew"]' />
But in resulting HTML I see this:
<input type="hidden" name="IsNew1" value="value" />
<input type="hidden" name="IsNew2" value='value' />
Then I tried this code in *.cshtml:
#{ string isNewRec = ViewBag.IsNew.ToString(); }
<input type="hidden" name="IsNew1" value="#isNewRec" />
And now it works:
<input type="hidden" name="IsNew1" value="True" />
Question is - why first attempt put "value" text instead of boolean value into HTML?
Also the strange thing - this code works fine:
<input type="hidden" name="ProductID" value="#ViewBag.ProductID" />
So, for integer values in ViewBug it works, returns an actual interger value, but for boolean it returns "value" text.
Another part of question.
Currently I use code like this:
[HttpPost]
public ActionResult Product_Commit(Product pProduct)
{
if (ModelState.IsValid)
{
AbcProducts ctx = new AbcProducts();
bool isNew = Convert.ToBoolean(Request.Form["IsNew"]);
if (isNew)
ctx.Products.Add(pProduct);
else
{
// [...]
}
ctx.SaveChanges();
}
return View();
}
Could you recommend something more correct from MVC point of view to pass non-model parameter into a view and get it back then with submited data?
But this parameter should not be stored anywhere where other pages can see it somehow.

Get Values of DropDownList which is inside webgrid and also each dropdown is an attribute of the model

I have a webgrid contains a dropdown which contains different items for each user(Items are grouped). I want to get the selected values to the controller . How can I do that. Heres my ;
Model :
public SelectList AvailableDevices { get; set; }
View :
...
var grid = new WebGrid(Model. ...
..
..
grid.Column(header: "AvailableDevices", format: #item => Html.DropDownList("value", (IEnumerable<SelectListItem>)item.AvailableDevices)),
And I have a Submit Button
#using (Html.BeginForm("AssignUserDevices", "Device"))
{
<input type="submit" value="setUserDevice" onchange="CheckSelectedDevices()" />
}
I want to set users device according to his user type. I know what his choices and send dropdown items according to his type. So each item in webgrid differs from each other.
And Also I dont know how to give indices to each item in webgrid.( I think we will need it.)
Im new at MVC so hope you will understand.
Thanks;
What I got from our requirement that you want the selected item and have that item value in form field before posting if yes then you can follow as given.
#Html.DropDownList("value", (IEnumerable<selectlistitem>)item.AvailableDevices), new {#class="deviceclass"} )
#using (Html.BeginForm("AssignUserDevices", "Device"))
{
<input type="hidden" value="" name="deviceId" id="deviceId" />
<input type="hidden" value="" name="userId" />
<input type="submit" value="setUserDevice" />
}
<script>
$(".deviceclass").on('change', function () {
var dropdownvalue = $(this).val();
$('#deviceId').val(dropdownvalue);
})
</script>
and you can define an action function in controller
public ActionResult Details(string deviceId, string userId)
{
// do as you need.
return View();
}

Why Ajax.BeginForm does not pass form values?

I'm trying to show a partial view via calling Ajax.BeginForm, but I can't receive the values of my form(I need to get the value of hidden input, bookId, in controller, e.g 5).
// View
#using (Ajax.BeginForm("Detail", "Books", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "ShowBookDiv" }))
{
<input type="hidden" id="bookId" value="5" />
<input type="submit" id="sBtn" value="Details" />
}
// Controller
[HttpGet]
public ActionResult Detail(string bookId)
{
if (Request.IsAjaxRequest())
{
var a = Request["bookId"].ToString();
// some code to get details
return PartialView("ShowBooks", details);
}
...
}
When I trace the code in Controller bookId is null!
I've added the "name" property to hidden field and it works !!! really strange!
<input type="hidden" name="bookId" id="bookId" value="5" />
Ajax.BeginForm is a pain, IMO.
I would Use $.ajax from JQuery Ajax API :
http://api.jquery.com/jQuery.ajax
here is a good example for you to see how it works :
http://www.tugberkugurlu.com/archive/working-with-jquery-ajax-api-on-asp-net-mvc-3-0-power-of-json-jquery-and-asp-net-mvc-partial-views
Posting the whole form requires a little bit of work (in terms of validation, etc.) but you will have complete control over the action if you are good with JavaScript.

object gets passed to action as string

I have a form that has a hidden field wich stores a object. This object is a RoutesValues (I want to store a reference because when I process the form I want to redirect to a route). The action that processes the form is:
public ActionResult Añadir(string userName, string codigoArticulo, string resultAction, string resultController, object resultRouteValues, int cantidad)
{
processForm(codigoArticulo, cantidad);
if (!ModelState.IsValid)
TempData["Error"] = #ErrorStrings.CantidadMayorQue0;
if (!string.IsNullOrWhiteSpace(resultAction) && !string.IsNullOrWhiteSpace(resultController))
return RedirectToAction(resultAction, resultController, resultRouteValues);
return RedirectToAction("Index", "Busqueda", new {Area = ""});
}
and my form is:
#using (Html.BeginForm("Añadir", "Carrito", FormMethod.Get, new { #class = "afegidorCarrito" }))
{
<fieldset>
<input type="hidden" name="codigoArticulo" value="#Model.CodiArticle" />
<input type="hidden" name="resultController" value="#Model.Controller" />
<input type="hidden" name="resultAction" value="#Model.Action" />
<input type="hidden" name="resultRouteValues" value="#Model.RouteValues" />
<input type="text" name="cantidad" value="1" class="anadirCantidad" />
<input type="submit" />
</fieldset>
}
the problem I have is that resultRouteValues gets passed as a string instead of an object. Is there any way to fix this?
Thanks.
No, there is no easy way if RouteValues is a complex object. You will have to serialize the object into some text representation into this hidden field and then deserialize it back in your controller action. You may take a look at MvcContrib's Html.Serialize helper.

Resources