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.
Related
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.
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>
...
}
I need to manage a Hyperlink object in GWT. What i need is :
1 - add it into a span (like InlineLabel)
I tried Hyperlink affitta_3_span_1=new Hyperlink(result.get(i)[0], "");, but it create somethings like this :
<div class="affitta_3_span_1">
t1
</div>
in fact i need this :
<span class="affitta_3_span_1">
t1
</span>
2 - manage Hyperlink History token
I put my internal links such Hyperlink affitta_3_span_1=new Hyperlink(result.get(i)[1], "article/"+result.get(i)[0]) but i don't know how to get the parameter on token when they call the onValueChange() function. How can I do it?
Cheers
Use an Anchor. The output is just an <a> tag that has no <div> or <span> around it, but if you need a <span> you can add it with an HTML panel.
To set a URL that history can access, just put a # at the beginning. Something like
myAnchor.setText(result.get(i)[1]);
myAnchor.setUrl("#article/"+result.get(i)[0]);
Now, when you click myAnchor, onValueChange will be passed the token "article/whatever". The unfortunate side effect is that your urls look like http://example.com/#article/whatever, but that's the only way to get the token to the History object with just GWT.
For the first question, use an Anchor since it's inlined.
For the second one, you need to 'listen' to history change events by extending ValueChangeHandler and calling History.addValueChangeHandler(this); in your class. For example,
class MyClass implements ValueChangeHandler<String> {
public MyClass {
...
History.addValueChangeHandler(this);
}
#Override
public void onValueChange(ValueChangeEvent<String> event) {
String token = event.getValue();
if (token.equals("foo")) {
// go to one page
} else if token.equals("bar")) {
// go to another page
}
}
}
If you only need a ClickHandler on your link and no history support, you can use the Anchor widget, which is based on an <a> tag that has display: inline by default.
I'm pretty new to MVC 2 and I'm having problems figuring out how to post values that lies outside the form.
This is my code very simplified:
<input type="text" id="TextboxOutsideForm"/>
<% using (Html.BeginForm("Edit", "Home", FormMethod.Post)) {%>
<%: Html.ValidationSummary(true) %>
<%: Html.TextBoxFor(model => model.Stuff) %>
<input type="submit" value="Save" />
<% } %>
TextboxOutsideForm can be changed by the user and when pushing save I want to include the value from this control to the action in the controller. It would also be great if i could use model binding at the same time.
This would be great:
[HttpPost]
public ActionResult Edit(int id, Model model, string valueFromTextbox)
Or just a FormCollection and a value..
I know that in this simplified example i could just put the textbox inside of the form, but in real life the control is 3rd party and is creating loads of of other stuff, so i just need to grab the value with jquery maybe and post it..
Is this possible?
Thanks
you can have a look at this question that explains how to dynamically create the form and submit it. you can hijeck the submit event and add value into form dynamically
$(function() {
$('form').submit(function() {
$(this).append($("#ValueOutsideForm"));
return true;
});
});
this way u don't have to rely on ajax and u can post ur form synchronously.
If you use a normal form post only inputs inside the form will be sent to the server. To achieve what you are looking for you will need to submit the form using AJAX. Example:
$(function() {
$('form').submit(function() {
$.ajax{
url: this.action,
type: this.method,
data: $(this).clone().append($('#TextboxOutsideForm').clone()).serialize(),
success: function(result) {
alert('form successfully posted');
}
});
return false;
});
});
Also don't forget to give a name to the input field which is outside the form.
I have an index page which shows a paged list of data from a database. When that list is empty, I want to show a "blank slate" view that clearly indicates to the user where they are and what they can do there: "You can add a new item by clicking here" type of thing.
Is there a better/cleaner way to do this than just having a big if statement around the entire page?
<% if (Model.Items.Count > 0) { %>
normal view
<% }
else { %>
blank slate view
<% } %>
Good suggestions from Benjamin Anderson. In addition, you many want to look into the MVCContrib Grid (see the .Empty method)
http://www.jeremyskinner.co.uk/2009/02/22/rewriting-the-mvccontrib-grid-part-2-new-syntax/
<%= Html.Grid(Model.People).Columns(column => {
column.For(x => x.Id).Named("Person ID");
column.For(x => x.Name);
column.For(x => x.DateOfBirth).Format("{0:d}");
})
.Attributes(style => "width:100%")
.Empty("There are no people.")
.RowStart(row => "<tr foo='bar'>") %>
Other than redirecting to a different View in the controller, or using a different view engine, that is the best way.
A slightly cleaner alternative would be to use a Partial View for the grid and paging, but you'd still have an If clause in the middle of the view.
How about the following HtmlHelper where viewName is the name of a partial view. It is not exactly what you are after but may provide a start. What I would consider is that assuming you have a set list of actions that can be performed in the event of an empty list, you could create partial views that reflect that. Maybe one for each controller but named the same and can replace the "NoResultsView" argument.
Depending if you are using ViewModels in your project - you can create a naming convention to for result type views and this could further eliminate the need for the viewName argument
public static MvcHtmlString ResultsView<TModel> (this HtmlHelper helper, IList<TModel> items, string viewName) where TMdodel: class
{
if (items.Count() != 0)
{
return System.Web.Mvc.PartialExtensions.Partial(helper, viewName, items);
}
}
return return System.Web.Mvc.PartialExtensions.Partial(helper, "NoResultsView", items); // View is Shared
}