passing dropdown's selected value from view to controller - asp.net

I have a dropdownlist in my asp.net MVC2 view like this:
<% using(Html.BeginForm("temp","Settings")){ %>
<%= Html.DropDownList("drpFields", new SelectList(Model.Fields, "FieldID", "NiceName", whiteout.FieldID))
}
%>
and I want to pass the dropdown selected value from view to controller action. How do I modify this:
<a class="icon-button-success" href='<%: Url.Action("EditWhiteOut", "Settings", new {FieldId = 1}) %>'>
<img src='<%: Url.Content("~/static/Images/update.png") %>' alt="Update" />
</a>
I want to pass dropdown's selected value to FieldId.

If you're willing to use Ajax, you can avoid the form if you want to use jQuery.ajax. You might want to give your anchor a value for its ID property (my example below only uses its class attribute)
But, since you want to do a regular postback, you'll want to use another overload of Html.BeginForm so you can specify an ID attribute for the form (I specified the parameter names in case you're unfamiliar with this overload)
Html.BeginForm(actionName: "temp", controllerName: "Settings",
method: FormMethod.POST, htmlAttributes: new { id = "MyForm" })
And the jQuery used to make your link submit the form will create a standard submit. So, as long as your select list has a name attribute, it's value will be included in the post's payload.
$(function () {
$('.icon-button-success').click(function (e) {
$('#MyForm').submit();
// you might not need preventDefault, but I can't remember if
// it will create a second post or not
e.preventDefault();
});
});
If you wanted to do a redirect anyway (using the $.ajax method), you could always do window.location.href='redirect/link'; inside the success function in the $.ajax call

and what about
this will trigger javascript submit of the form and provide button if js is not enabled
<% using (Html.BeginForm(youraction)) {%>
<select name='myfield' onchange='this.form.submit()'>
<option .... >
...
</select>
<noscript><input type="submit" value="Submit"></noscript>
<%}%>
or using your code:
use jquery to update the value of the submit the value in which case
javascript:
var link = Url.Action("EditWhiteOut", "Settings");
jquery
function toCallOnChange(){
var linkParameter = $("#id of object").val();
$("a.icon-button-success").attr("href", link+"\"+linkParameter ); //which will overwrite default value to current link
}
<a class="icon-button-success" href='#'>
<img src='<%: Url.Content("~/static/Images/update.png") %>' alt="Update" />
</a>

Related

ASP.NET MVC pass data from partial view

How can I pass data from partial view on submit form in ASP.NET MVC.
#using (Html.BeginForm("Edit", "BlogPost", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
................
#Html.Partial("PostImagesForPost",Model.PostImages)
}
PostImagesForPost - partial view:
#model IEnumerable<Blog.Models.PostImage>
<script type="text/javascript" src="~/Scripts/jquery.zoom.min.js"></script>
<div>
#{
List<Blog.Models.PostImage> images = Model.ToList();
<ul class="images">
#foreach (var img in images)
{
string parameterValue_small = "~/BlogPhotos/120/" + img.Photo.ToString();
string parameterValue_big = "~/BlogPhotos/600/" + img.Photo.ToString();
<li>
<div id="jquery-image-zoom-example">
<span data-postid="#img.ID" data-delete="true" class="deletespan"></span>
<a href="#Url.Content(parameterValue_big)">
<img src="#Url.Content(parameterValue_small)" data-postid="#img.ID" class="zm" onclick="$('.jquery-image-zoom img').click()" />
</a>
<input type="checkbox" checked="checked" name="selectedImagesForDelete" style="display:none;" data-postid="#img.ID" value="#img.ID" />
</div>
</li>
}
</ul>
}
On submit function the parameter selectedImagesForDelete is null.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Post post,string[] selectedImagesForDelete)
{...........}
This has nothing to do with the fact you're using a partial, and everything to do with how the modelbinder in MVC works. For iterable posted items, the model binder expects field names in the form of ListProperty[index].ModelProperty. The problem is that the Html.* family of helpers will not create this name properly unless they are passed an indexed value, which you can't achieve with foreach. The solution is to simply use for, instead:
#for (var i = 0; i < images.Count(); i++)
{
Html.EditorFor(m => image[i].SomeProperty)
}
By passing in a value that's indexed (images[i]), the helper recognizes that it needs to add the proper indexed html prefix to the name, so that the modelbinder will understand where to stuff the value when it's posted back.
Though, in your case, you seem to actually just be manually specifying the HTML for the fields, which is fine, but you're responsible at that point for getting the name values right.
I believe your name property needs to have indexes in the name:
Create a index variable called index and increment it after each iteration
<input type="checkbox" name="selectedImagesForDelete[index]" value="2">
Actually it was a problem with the javascript file. The checkboxes were never checked.
<input type="checkbox" name="selectedImagesForDelete" value="#img.ID" />
But I resolved that problem and now everything works like expected.
But thanks for trying to help me. I appreciate it.

ASP.NET MVC: on button click, call display multiple ActionResults in different windows

I have a form that has a drop-down list of values and a submit button.
Currently, when you click on the submit button, a stored procedure is called and then the application generates a url and then the ActionResult is a Redirect to a new window. The url is based on the currently selected value in the dropdown list.
Our client wants another button that when clicked, will basically do the same thing, but FOR ALL VALUES in the drop down list.
Basically, on click, multiple windows will be opened, whose urls each based on a value in the drop down list.
I just started working with MVC and research confused me even more. I'm hoping someone can point me in the right direction.
Should I handle this via some sort of loop in javascript? How? Can you give some examples, please?
ASPX Portion:
<div id="MyContainer" class="select-report">
<%
using (Html.BeginForm(MyManager.Query.Actions.GenerateReport(null), FormMethod.Post, new{target="_blank"}))
{%>
<select name="SearchText" class="my-values-select">
<% foreach (var cc in Model.MyCentresList)
{%>
<option value="<%=Html.Encode(cc.Name) %>">
<%=Html.Encode(cc.Name) %></option>
<% } %>
</select>
<input type="hidden" name="SearchType" value="MyCentre" />
<input type="submit" value="Generate" name="EntityName" />
<% } %>
</div>
Code-Behind:
public virtual ActionResult GenerateReport(GenerateReportOperation operation)
{
string entityName = operation.SearchText;
int entityType = (int)operation.SearchType;
string requestID1 = <code here that calls a stored procedure, a value is returned>;
string requestID2 = <code here that calls a stored procedure, a value is returned>;
string urlString = <code here that contructs the URL based on the values of entityName, entityType, requestID1, requestID2>;
return Redirect(urlString);
}
You would have to use JavaScript to open new windows for each individual HTTP request.

ajax in asp.net mvc 2

I am using the microsoft ajax and the ajax form looks like this
<% using (Ajax.BeginForm("UserListing", new AjaxOptions
{
UpdateTargetId = "results",
OnComplete = "getData"
}))
{%>
<input id="Submit1" type="submit" value="submit" />
<%} %>
Now, i get the getData() js function called upon completion of the ajax request. all i want is that i need to access the response data of this ajax request inside this function and prevent that data being directed to the div with id results.
Thats because i am returning json result from the controller's action method and i need to parse it and display in the div.
script function is :
<script type="text/javascript">
function getData() {
alert("Response is : ");
}
</script>
the div tag is :
<div id="results">
</div>
I do not want to use other than microsoft ajax. kindly suggest me accordingly.
You could try rendering the response of the ajax request in a partial view containing only hidden fields. Then in your js function you can access the hidden fields using jQuery selectors.
So your action would look something like
[HttpPost]
public ActionResult UserListing()
{
List<string> data = GetUserListing();
return PartialView(data);
}
Your partial view will then only contain hidden fields that you render something like:
<% for (int i = 0; i < Model.Count(); i++)
{ %>
<input id="<%: "User" + i.ToString() %>" type="hidden" value="<%: Model[i] %>" />
<% } %>
That will render as:
<input id="User0" type="hidden" value="PeterSmith" />
Then in your javaScript function you can access each of the fields by doing something like:
function getData() {
var user = $('#User0').val();
alert(user);
}
That will show you the first field rendered. But you can enhance it a bit by looping through all the injected input fields.
Corrected this problem by myself as explained above. need some json parsers, currently looking for those..

send id from view to controller

I have a view that receives a Model and displays info of that model.
I have a submit button and when it is clicked i want it to send the id to the method to process it and delete a row that has such id.
How can I do this? I want to use a button not an html link like
#Html.ActionLink("Delete", "Delete", new { id = Model.Id }) |
Thanks!
I tried input type hidden but hasn't worked =(
You can use a form to do this... I don't use razor, but an equivalent .aspx way to do this would be:
<%using (Html.BeginForm("Home", "myaction", new { Id = 1 }))
{ %>
<input type="submit" value="submit" />
<%} %>
This will post to ~/Home/myaction/1
Just call Html.BeginForm with the appropriate razor syntax.

Why can't I use an iteration variable in a LoginView?

I am building a .NET MVC app that has a page with a list of delete buttons, one for each item in a list. The problem I'm having is that the foreach variable "item" is not visible inside the LoginView, which results in the following error:
Compiler Error Message: CS0103: The name 'item' does not exist in the current context
Below is a simplified version of the view. The error occurs at the "new {id=item.Id}" in the LoggedInTemplate - the reference to "item" in the ActionLink works fine:
<% foreach (var item in Model) { %>
<%= Html.ActionLink("Item", "Details", new { id = item.Id })%>
<asp:LoginView runat="server">
<LoggedInTemplate>
<% using( Html.BeginForm( "Delete", "Items", new {id=item.Id}, FormMethod.Post))
{ %>
<input type="submit" value="Delete" runat="server" />
<% } %>
</LoggedInTemplate>
</asp:LoginView>
<% } %>
To clarify the problem is not that the Model has not been successfully passed to the View. The Model is visible from both inside and outside the LoginView. The foreach loop as no problem in iterating through the items in the Model (which is a List). The problem is that the iteration variable "item" is not accessible from within the LoginView - though the original Model is.
Is there any way to pass "item" through to the LoginView's templates? Or is building LoginViews within a foreach loops the wrong way of doing things?
Is there a scoping rule that prevents using local variables within controls - perhaps because the control is rendered at a different time to the main page?
With ASP.NET MVC you really shouldn't use user/custom controls, so if you omit the <asp:LoginView/> and write a line of code to check if the user is authenticated, you are good to go.
Instead of your current code:
<asp:LoginView runat="server">
<LoggedInTemplate>
<div>Show this to authenticated users only</div>
</LoggedInTemplate>
</asp:LoginView>
Just use an if-statement and the value of Request.IsAuthenticated:
<% if (Request.IsAuthenticated) { %>
<div>Show this to authenticated users only</div>
<% } %>
Are you passing the Model to the view and are you also inheriting from the model within that view?
So if this is a View then in your C# code you need to return the list of items like return View(listofitems);
If this is a partial view then <% Html.RenderPartial("MyPartial", listofitems) %>
And in the view you need to
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IQueryable<ListOfItems>>" %>
If all that is in place then it should work no probs.
<% foreach (var item in Model) { %>
<%= Html.ActionLink("Item", "Details", new { id = item.Id })%>
<%= if( Request.IsAuthenticated ) {
using( Html.BeginForm( "Delete", "Items", new {id=item.Id}, FormMethod.Post))
{ %>
<input type="submit" value="Delete" runat="server" />
}
} %>
<% } %>
There is no need to use the LoginView, its not really giving you anything. Use something like the above instead.
Alternatively, you can move the decision of whether to show the delete option for the specific item into the controller, so instead of doing if( Request.IsAuthenticated ) you would do if( item.ShowDelete ) ... assuming item's type is a view model. Another option is to use an extension method for the same, item.ShowDelete(). I prefer the earlier, because there might be logic associated to deciding whether to show delete for a given item, so its better to not have it in the controller or a related logic.

Resources