In my .Net MVC4 project the view contains partialviews, the partialviews replaced on another after each corresponding Ajax.Beginform with option InsertionMode = InsertionMode.Replace,
So the senario is
Partialview1 renders on first Ajax.Beginform call
Submit form, partialview2 render on 2nd Ajax.beginform, so partialview1 is replaced by partialview2
3. A previous button recalls partialview1
Im wondering how to implement step3 that goes to previous partialview with something simple as history back.
First Way: I think the best way to do that with browser Back button is to use history.pushState
How to implement it depends on your situation on View.
Some links about pushState:
http://rosspenman.com/pushstate-jquery/
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
Second Way: If you don't want to use browsers Back buttom you can use js:
function getBack()
{
$.ajax({
type: "GET",
url: '#Url.Action("ReturnPartialViewControllerMethod")',
success: function(data) {
// data is your view
$('#divForParticialView').html(data);
}
});
}
and in your Html:
Get Back
Related
I have an ajax call
$.ajax({
type: "POST",
data: $("#divInfoRecherche :input").serialize(),
url: '#Url.Action(Action, Controler)',
success: function(resultat) {
$("#tableauResultatRecherche").css("display", "");
$("#tableauResultatRecherche").html(resultat);
$.validator.unobtrusive.parse($('#PartialViewModel'));
}
});
The line $.validator.unobtrusive.parse($('#PartialViewModel')); makes it possible for the client side validation to pop, everything works fine.
Problem is when I click on Submit of the page, the message errors go back to the error of native JavaScript "This field is required" instead of my custom message linked in the model.
Option I think of is add the content of the partial view in the main view and populate it manually so that all the validations are added on Pageload.
But I still ask to see if another option is possible.
https://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
Here is the script to add and call on the div containing the partial view.
I have a page that is mostly informational data (not an input form, overall). And it has a title that can be edited.
Clicking the Edit Title button pops up a modal window where the user can edit the title and hit submit.
Because this form is a very small part of the page, and because I may need other small forms on the same page, I just created a small handler in the controller to handle this one submit.
[HttpPost]
public ActionResult PageTitle(string title)
{
// ... Save new title to the database ...
// I have no PageTitle page, so just redirect back to the source page
return RedirectToAction("Index");
}
This works okay, but I don't like the extra redirect here. A redirect back to the client causes another round trip back to the server.
Is there a more efficient way to handle small forms on a page, where you don't want to resubmit every input element on the page each time?
I don't think there is a convenient way how to avoid the redirection after a post request (without using Ajax).
You can of course return any View:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult ProcessForm1(FormOneData data)
{
// process form
return View("Index");
}
[HttpPost]
public ActionResult ProcessForm2(FormTwoData data)
{
// process form
return View("Index");
}
So the user will get the same page but the problem with this solution is that the url will be different.
You can have one function for GET request, another for POST requests, both with the same URL. But than you would have to figure out how one action method would handle more forms - doable but terrible for maintenance.
And this can get even more complicated if those forms can appear on more than one page.
But actually, it solves one thing. With the redirection you avoid the re-POST dialog that user gets if they press F5 (and sometimes submit the form again by mistake).
As #TiesonT. points out, post/redirect/get is a standard pattern. No, it doesn't seem like the most efficient. But without doing AJAX or something a little more elaborate, there is really no way to postback to a specialized handler and then refresh the page without a redirect.
Was hoping I overlooked something simple but it looks like I did not.
What about sending form data via Ajax as shown below?
#model Models.YourModel
$('form').submit(function (event) {
event.preventDefault();
//Send the values of all form controls within the <form> tags including the token
var formdata = $('#frmRegister').serialize();
$.ajax({
type: "POST",
url: '#Url.Action("ProcessForm", "Controller")',
cache: false,
dataType: "json",
data: formdata,
error: function (response) {
$("#error_message").html(data);
},
success: function (data, textStatus, XMLHttpRequest) {
$('#result').html(data);
}
});
});
You can also use Partial Views in order to use multiple forms or fragment on the same View.
I have a MVC Controller with an Index that will cycle through multiple PartialView as the user goes through the form process.
Here is the Index:
#section pageMain {
<div id="partialView">
#Html.Partial("SelectAccount", SUPR.Models.Account.GetAccounts());
</div>
}
This works fine and I get the SelectAccount page just fine.
My issue is that I have an AJAX call that runs when the user selects a row in a table on the SelectAccount page. What is supposed to happen is that the PartialView is then replaced with another PartialView that displays the details of the selected row. This actually does work, but after about 1 second it cycles back to the SelectAccount PartialView with a query string attached, for some reason, to the URL.
Before
After
Here is the code for the AJAX call:
$.ajax({
type: "GET",
url: "/Review/GetReviewView",
data: { profitCenter: profitCenterNo }
}).done(function (data) {
$('#partialView').html(data);
});
The ONLY that is happening in the controller for GetReviewView is that I'm returning the PartialView with the PartialView name and model. This working because, in that brief moment that I can see the ReviewAccount view, the proper data is in the fields.
Any thoughts as to why this odd behavior is occurring?
Are you capturing the event in JS? If you are triggering off of a click event then add the event parameter to the method and then at the end of the method add:
event.preventDefault()
And see if it still happens. It sounds like a client side JS issue, not a C# issue.
The way you are doing this is actually fine. There used to be a Microsoft library called ASP-AJAX or something, don't remember because I didn't use it much. This library basically allowed you to decorate HTML elements with ASP-AJAX-METHOD , ASP-AJAX-REFRESH-TYPE and it would automatically do something similar to what you are doing now. Go to the Server and retrieve a PartialView.
This is an odd issue, and I'm sure it's something simple, but I couldn't find another post with the same issue. I have a MVC View with an AJAX.BeginForm() that posts to my controller. Also, I have a search box (input) above the form that when the Enter key is pressed, it performs a JQuery ajax post to my controller (GetData) to auto-populate some of the form fields before submitting it. What's strange, is if the search field is used, it successfully fills the form fields with data, but the form's submit button stops working (form does NOT submit at all)! Now, if I do NOT use the search field (which performs the ajax POST) and manually fill in the form fields, then hit submit, it correctly submits to my controller.
The GetData (field pre-filler action) returns a JSONified model object which I read into the form objects.
The form is in a PartialView with the master ViewModel as it's model. The search box is in the _Layout page with no model on the razor view.
Code below is simplified to the relevant chunks (let me know if I omitted something important):
_Layout.cshtml:
<body>
<div id="bodyFrame">
#RenderBody()
</div>
<footer>
<span>Project Number:</span><input id="projectSearch" type="text" />
<div id="inputFrame">
#{ Html.RenderPartial("InputPartialView"); }
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/scripts")
#RenderSection("scripts", required: false)
</body>
InputPartialView.cshtml:
#using (Ajax.BeginForm("AddEntry", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "bodyFrame", InsertionMode = InsertionMode.Replace }))
{
/*Table with numerous HTML helper input fields for my model*/
<input type="submit" value="Submit" />
}
Main.js (method to pre-fill form data on Enter key press in search box):
$('#projectSearch').keyup(function (event) {
if (event.keyCode == 13) {
$.ajax({
url: '/Home/GetData',
dataType: 'json',
type: 'POST',
data: {
project: $(this).val()
},
success: function (data) {
$('#tb_Client').val(data.Client);
/*Other field values filled the same way*/
},
fail: function () {
alert('fail');
}
});
}
});
controller actions:
[HttpPost]
public JsonResult GetData(string search)
{
var result = new SubModel(); //This is a submodel of the main viewmodel
/*Pull in data via SQL into result*/
return Json(result);
}
[HtppPost]
public ActionResult AddEntry(ReportLogViewModel model)
{
/*Only works if search function is not called*/
return PartialView("Index", ViewModel.Generate());
}
So to summarize: The search function (GetData) always works, the form only works when the search function is not used (once it is used, the form does not submit to the controller), no errors occur in the browser console. Normal usage would be:
Type query in search input, press enter
GetData action is called, data is retrieved and returned via $.ajax() and then the form fields are populated with the returned data
User correct/amends any autocompleted data, fills in manual data, then hits Submit button
AddEntry action is called to enter the form data into the database, then return a newly generated partialview with the newly entered record.
Thanks in advance for any help!
UPDATE 1: It seems commenting out the lines of code in the main.js ajax success command allows the form to submit normally (albeit without the data the GetData method received). In this case removing "$('#tb_Client').val(data.Client);" allows the form to submit. This doesn't solve my problem but further pinpoints the problem to these lines of code in main.js.
UPDATE 2: The problem indeed was one of the javascript/jquery value setters on one of my inputs. Something was wrong with the JSON object. I commented them out one by one till I found the culprit then went back to my controller/viewmodel to the method that set the values and corrected the problem.
This is more appropriate for a comment but I need more reputation to reply to people on this site for some reason.
With your update, it makes me think that you're using the #tb_Client ID in more than one place but I can't confirm that without seeing the rest of the program.
Alternatively, instead of submitting the data encapsulated into a single object, you can send variables individually:
data : { variable : 'variable',
variable2 : 'variable2'},
I've come from a Classic ASP background and have started developing ASP.NET MVC 4 with C#.
Previously in classic ASP I would post the whole form and page to the resulting URL. However in MVC4 I've seen other ways of just updating the partial view.
Basically at the moment on the left hand side of my page I have three different combo boxes with some data in. I have a Submit button that when pressed, I want to search my database and return a list of results from the database to a partial view (I've already got the code working to search the database and populate a list of objects.), so that the whole page isn't refresh.
In addition, for partial views, can then handling paging. For example my query could return 100 records, but the user only wants to display 20 per page giving 5 pages of results. Is this possible ?
Can anybody offer any examples of what I'm trying to achieve.
for updating your partial view you should use an ajax call
$('.btnSubmit').on('click', function(){
$.ajax({
url: "#(Url.Action("Action", "Controller"))",
type: "POST",
cache: false,
async: true,
data: { combo1: $('.Combo1').val(), combo2: $('.Combo2').val(), combo3: $('.Combo3').val() },
success: function (result) {
$(".Content").html(result);
}
});
});
then on your view just put a div with class that matches where it will put the returned partial view. For paging I just use a jquery plugin. Here is a page that has some options http://plugins.jquery.com/tag/paging/ Let me know if you have any questions.