Can i access masterpage dropdown value in controller action in asp.net mvc - asp.net-mvc-2

I have a masterpage on which i displays groups that user can access now i want to gets its selected value in many controllers for saving with the records. I want to know if it is possible in asp.net mvc 2 and if not then what is the way around for it

What you are trying is possible and there are different techniques to achieve it. The best approach would depend on how you are invoking your controller actions. Whether you are using normal hyperlinks, submitting standard <form> or using AJAX. So if you are using standard action links you could add some javascript which binds to the onclick event of each link and adds the selected value of the group. Example:
$(function() {
$('a').click(function() {
// everytime a link is clicked
// add the value of the selected group to the url
var selectedGroup = $('#IdOfYourDdl').val();
if (this.href.indexOf('?') > 0) {
window.location = this.href + '&selectedGroup=' + selectedGroup;
} else {
window.location = this.href + '?selectedGroup=' + selectedGroup;
}
// cancel the default action as it doesn't contain the selectedGroup
// parameter in the request
return false;
});
});
and in your controller action you could have this additional parameter:
public ActionResult Foo(string selectedGroup)
{
...
}
Another example is if you use AJAX you could setup a default data in the master page which will ensure that the value of the dropdown will be sent along each AJAX request you are performing:
$.ajaxSetup({
data: { selectedGroup: $('#IdOfYourDdl').val() }
});
Now whenever you send an AJAX request to your server:
$.get('/foo', { someParam: 'someValue' }, function(result) {
});
the following request will be sent: /foo?someParam=someValue&selectedGroup=123 so you will be able to fetch the value of the selected group back in the controller action.

I hope I understand your question since no code-example is supplied.
You can do this using a viewmodel on the page which contains your display groups. Another option is to get the value from the FormCollection when the page is posted.
For example:
public ActionResult MyAction(MyViewmodel viewModel)
{
//value from your viewmodel, strongtype
var value = viewModel.group;
}
OR
public ActionResult MyAction(FormCollection collection)
{
//value as a string
var value = collection.getValue("MyKey").AttemptedValue;
}
If this answer doesn't statisfy you then please be more clear in your question and i'll try to help you further.

As long as your drop down list is a descendant of the <form> that is submitted, it will be subjected to standard model binding, which means you can include it as a parameter on your action. Ensure the name attribute of the drop down list matches the name of the action parameter.
Final rendered HTML:
<form action="http://.../MyAction" method="post">
<select name="dropDownList">
<option value="a">Option A</option>
<option value="b">Option B</option>
...
</select>
...
</form>
Controller:
[HttpPost]
public ActionResult MyAction(string dropDownList, MyActionModel model)
{
// dropDownList = value attribute of selected <option>
...
}

Related

MVC form not submitting to correct action

I have a simple partial with a form inside which is used as a search bar.
#using (Html.BeginForm("Details", "Projects", FormMethod.Get))
{
<div class="row" style="margin-bottom: 20px;">
<div class="col-lg-3 pull-right">
<input type="search" class="form-control" placeholder="Search Code" id="projectSearch" name="code" />
</div>
</div>
}
This should post to my Projects Controller Details Action, however this isn't happening, and I believe this because of the [Route] attribute that is applied to the action, as when I comment this out, the form posts correctly. However I want to use the [Route] attribute.
The action looks like this:
[HttpGet]
[Route("{code}/Details")]
public ActionResult Details(string code)
{
if (code == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
...
return View(viewModel);
}
When the attribute is in use the form will post to this url:
/Projects/Details?code=PP61
which doesn't map to the correct action. Instead I get a resource cannot be found error.
The expected/desired url should look like
/Projects/PP61/Details
This works fine if I create a Url.Action or browse to the URL, so I know this action works, however it doesn't work with a form post. Any ideas why?
Thanks.
Change [HttpGet] to [HttpPost] on the controller and FormMethod.Get to FormMethod.Post in the view.
I have one solution to the problem, it doesn't however answer why this wasn't working in the first place. I have created a separate action which is for the search bar to POST to, this action then redirects to the GET action which I was trying to reach in the first place.
[HttpPost]
public ActionResult ProjectSearch(string code)
{
if (code != "")
{
return RedirectToAction("Details", new { code });
}
else
{
return RedirectToAction("Index");
}
}
This now works correctly, but I would still love to know why this didn't work to begin with if any body has any ideas. Cheers.

jquery / ajax form not passing button data

I thought the HTML spec stated that buttons click in a form pass their value, and button "not clicked" did not get passed. Like check boxes... I always check for the button value and sometimes I'll do different processing depending on which button was used to submit..
I have started using AJAX (specifically jquery) to submit my form data - but the button data is NEVER passed - is there something I'm missing? is there soemthing I can do to pass that data?
simple code might look like this
<form id="frmPost" method="post" action="page.php" class="bbForm" >
<input type="text" name="heading" id="heading" />
<input type="submit" name="btnA" value="Process It!" />
<input type="submit" name="btnB" value="Re-rout it somewhere Else!" />
</form>
<script>
$( function() { //once the doc has loaded
//handle the forms
$( '.bbForm' ).live( 'submit', function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: $( this ).serialize(), // get the form data
type: $( this ).attr( 'method' ), // GET or POST
url: $( this ).attr( 'action' ), // the file to call
success: function( response ) { // on success..
$('#ui-tabs-1').html( response );
}
});
return false; // cancel original event to prevent form submitting
});
});
</script>
On the processing page - ONLY the "heading" field appears, neither the btnA or btnB regardless of whichever is clicked...
if it can't be 'fixed' can someone explain why the Ajax call doesn't follow "standard" form behavior?
thx
I found this to be an interesting issue so I figured I would do a bit of digging into the jquery source code and api documentation.
My findings:
Your issue has nothing to do with an ajax call and everything to do with the $.serialize() function. It simply is not coded to return <input type="submit"> or even <button type="submit"> I tried both. There is a regex expression that is run against the set of elements in the form to be serialized and it arbitrarily excludes the submit button unfortunately.
jQuery source code (I modified for debugging purposes but everything is still semantically intact):
serialize: function() {
var data = jQuery.param( this.serializeArray() );
return data;
},
serializeArray: function() {
var elementMap = this.map(function(){
return this.elements ? jQuery.makeArray( this.elements ) : this;
});
var filtered = elementMap.filter(function(){
var regexTest1= rselectTextarea.test( this.nodeName );
var regexTest2 = rinput.test( this.type ); //input submit will fail here thus never serialized as part of the form
var output = this.name && !this.disabled &&
( this.checked || regexTest2|| regexTest2);
return output;
});
var output = filtered.map(function( i, elem ){
var val = jQuery( this ).val();
return val == null ?
null :
jQuery.isArray( val ) ?
jQuery.map( val, function( val, i ){
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
}) :
{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
}).get();
return output;
}
Now examining the jQuery documentation, you meet all the requirements for it to behave as expected (http://api.jquery.com/serialize/):
Note: Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button. For a form element's value to be included in the serialized string, the element must have a name attribute. Values from checkboxes and radio buttons (inputs of type "radio" or "checkbox") are included only if they are checked. Data from file select elements is not serialized.
the "successful controls link branches out to the W3 spec and you definitely nailed the expected behavior on the spec.
Short lame answer: I think it is teh broken! Report for bug fix!!!
I've run into a rather unusual issue with this. I'm working on a project and have two separate php pages where one has html on the page separate from the php code and one is echoing html from inside php code. When I use the .serialize on the one that has the separate html code it works correctly. It sends my submit button value in its ajax call to another php page. But in the one with the html echoed from the php script I try to do the same thing and get completely different results. It will send all of the other info in the form but not the value of the submit button. All I need it to do is send whether or not I pushed "Delete" or "Update". I'm not asking for help (violating the rules of asking for help on another persons post) but I thought this info might be helpful in figuring out where the break down is occurring. I'll be looking for a solution and will post back here if I figure anything out.

MVC- receive selected Dropdownlist value in [HttpPost] method on change event

Hey..
How to receive selected Dropdownlist value in [HttpPost] method on change event? I always receive it in [HttpGet] method.
<%: Html.DropDownListFor(model => model.TipTpa, ViewData[ArtikliKonstante.vdListaTipovaTPa] as IEnumerable<SelectListItem>,
new { onchange = "location.href='/Artikli/PromjenaTipa? p='+this.value"})%>
If I declare my method as [HttpPost] I get error, that action doesn't exist. Any idea?
Thx
You need to POST if you want the proper action to be invoked. In your case you are simply redirecting (window.location.href) which sends a GET request.
So you could place the dropdown inside a form and use javascript to submit the form when the selection changes:
<% using (Html.BeginForm("PromjenaTipa", "Artikli", FormMethod.Post, new { id = "myform" })) { %>
<%: Html.DropDownListFor(
model => model.TipTpa,
ViewData[ArtikliKonstante.vdListaTipovaTPa] as IEnumerable<SelectListItem>,
new { id = "tipTpa" }
) %>
<% } %>
and then subscribe for the change event in javascript (example with jquery):
$(function() {
$('tipTpa').change(function() {
$('#myform').submit();
});
});
This will POST the form to the PromjenaTipa action where you could read the selected value:
[HttpPost]
public ActionResult PromjenaTipa(string tipTpa)
{
// tipTpa should contain the selected value
...
}
Another possibility would be to send an AJAX query in the change event. In this case you don't need a form as you could send POST request with AJAX.

ASP.NET MVC 2.0: Making the POST Action receive my Model's sub-models

I'm trying to reuse some existing Models (and especially the Load/Save functions associated with them), so I've aggregated them into the current Model:
public class EditModel {
public SubModel1 {get; set; }
public SubModel2 {get; set; }
/* ID and some text fields */
}
The problem is, after I fill the form and hit submit, in the Action associated with POST these sub-models all have default/empty content.
/// POST for Edit
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditCommunity(EditCommunityModel model) {
if (bad stuff happened)
return Json("Failure");
//model.SubModel1 is != null, but all fields are empty.
// ID and the aforementioned text fields come correctly.
Save(model.ID, model.SubModel1, model.SubModel2);
return Json("Succeeded");
}
I've done this reuse before without problems, when using an .aspx for the Edit equivalent, and would therefore call a GET Action to properly construct the Model. But now I'm restricted to an ascx, because I'm trying to edit in a modal dialog (if there's a way to load an aspx in a div, then this problem is over; but it occurs to me this would be contrary to what an aspx is intended for.)
This is, in short, what I'm trying to do; I'll also add two strategies I've tried to apply, both of which have the same effect: empty sub-models.
First try used an AJAX call to populate Edit.ascx.
In Edit.ascx, the wrapper for edit dialog was included in Manage.aspx, and the EditModel was passed without any initialization
<div id="editDialog" style="display: none;">
<% Html.RenderPartial("Edit", new EditModel()); %>
</div>
In the grid, a cell would be marked as edit, and on click would call the following javascript function:
function onSelectRowEdit_Click(id) {
if (id) {
//Get data from selected row
var ret = jQuery("#table_grid").getRowData(id);
//Show Edit modal control
var actionUrl = '<%= Url.Action("EditInfo", "Manage") %>';
var data = "externalId=" + ret.OrgId + '&Id=' + ret.Id;
$.ajax({
type: "POST",
url: actionUrl,
data: data,
error: AjaxError,
success: ShowEdit
});
}
}
EditInfo(string, string) would create and return a JsonResult, which was then received by ShowEdit; showEdit would fill Edit.ascx and use jQuery to present the div as a dialog:
function ShowRes(ret) {
$("#form_Edit").validate();
jQuery("#editDialog").dialog('destroy');
Init_EditDialog();
/* $('#...').val(ret...);, many times over */
//Show Dialog
$("#editCommunityDialog_Content").show();
$("#editCommunityDialog").dialog('open');
}
Second try attempted to bypass new EditModel(), and to use a View returned by a Controller. It did achieve exactly what the first try did, with significantly less code, but had the same issue on Submit.
<div id="editDialog" style="display: none;"></div>
<!-- ... -->
function onSelectRowEdit_Click(id) {
if (id) {
//Get data from selected row
var ret = jQuery("#table_communities").getRowData(id);
//Show Edit community modal control
var actionUrl2 = '<%= Url.Action("ShowEdit", "Manage",
new { CommunityId="_COMMID_", ExternalId="_ORGID_" }) %>';
editImg = editImg.replace("_COMMID_", ret.Id);
editImg = editImg.replace("_ORGID_", ret.OrgID);
$.ajax({
type: "POST",
url: actionUrl2,
data: data,
error: AjaxError,
success: ShowRes
});
}
}
ShowEdit was rewritten to return View("Edit", model), and ShowRes would simply write the result to the div's html.
function ShowRes(ret) {
//...
$("#editDialog_Content").html(ret);
//Show Dialog
}
Needless to say, the form in Edit.ascx has fields like <%= Html.HiddenFor(m => m.SubModel1.EditProfile)%> so that's not where the problem comes from.
Try checking out my answer in this question to see if that helps: How to handle `PartialRender` Models?

Submit PartialView

I have a masterpage that render's the following PartialView:
<% Html.RenderPartial("AddPage); %>
AddPage Controller looks like this:
public class PagController : Controller
{
[HttpGet]
public PartialViewResult AddPage()
{
return PartialView();
}
[HttpPost]
public PartialViewResult AddPage(FormCollection forms)
{
//some logic here
// some view data here
return PartialView();
}
}
And the view looks like this:
<% using (Html.BeginForm("AddPage", "Page", FormMethod.Post, new { ID = "PageManager" })){%>
<%= Html.TextBox("txtAddPage") %>
<input type="submit" value="AddPage" />
<%} %>
My issue is, that when i hit submit i get redirect to : http://localhost:1234/Page/AddPage, when instead i just want the partialview to be submitted, and return some basic view data if needed, as well as stay on the same page.
Am i having a blonde moment here? cause i know i have done this before
EDIT - This partial view is rendered in multiple pages, not just one.
Fullpage postback solution
This is a bit tricky since you have to know where to go back. I suggest you change your view and add two additional hidden fields (or one and parse its value - as you wish) and store current controller/action values in it.
You can then use this data in POST action to return a RedirectResult like:
return RedirectToAction("action_from_field", "controller_from_field");
Ajax postback solution
You can always submit your data using Ajax in which case your postback URL can be anything you want. In your case it should be to the current page URL. Edit: And Ajax would be the preferred solution in your particular case.
If you want to submit and only reload part of your page, you'll need to use AJAX. The most basic way to do this would be to render the partial view in an UpdatePanel.