Is it possible to get an alert popup on return to same view after success in mvc4 without using ajax begin form?
I'm trying to submit a form and on success want to show a alert box without using ajax and jquery .
When you submit form, I think then you are redirecting, am i right? So you can use TempData for this purpose:
In controller action:
if(success)
{
TempData["AlertMessage"] = "my alert message";
return RedirectToAction("SomeAction");
}
The view which SomeAction action returns (or in layout view):
#{
var message = TempData["AlertMessage"] ?? string.Empty;
}
<script type="text/javascript">
var message = '#message';
if(message)
alert(message);
</script>
NOTE: If you are not redirecting, but returning view, just use ViewBag instead of TempData.
Related
Form for AJAX call:
#using(Ajax.BeginForm("RefineSearchResults", "Search", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "resultsSec" }))
{
<input type="submit" value="submit" />
<div id="resultsSec"></div>
}
after form tag:
#{Html.RenderAction("Index", "NewsLetter", new { area = "" });}
but, it throws exception on second piece of code when posted back although it's not supposed to be execued because it's an AJAX call and it's outside the Ajax form.
Exception message:
Error executing child request for handler
'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
Can anyone please tell me what's going wrong here. Thanks!
oops!!! My mistake!
Actually, I was returning the main view again that's why code that wasn't supposed to be rendered was being rendered.
Now I have added the view code that was to be refereshed through Ajax.BeginForm() to a partial view.
My openion:
You should apply Ajax form on partial view preferably because from
controller when you return a view then the target view have to be rendered
again (it's ok when you have to show only a string through Content()
method.)
So, refreshing the partial view through Ajax form would be an ideal way to use Ajax.BeginForm() in my humble openion.
I'm new to MVC (using 4, framework 4.0) and I understand the basics but this page redirect isn't working as I expect. The application is a login/authentication which if the user successfully logs in it redirects them to the target application. That part works just fine. However the user may forget his/her login credentials, so I have a series of pages that will prompt the user for a registered email address and decoded captcha value. If that information is validated then another page prompts for a series of (up to 3) pre-determined security question answers (in the case of a password forgotten). If the security challenge question is successfully answered the user is redirected to a password change page. At any point in the process the user may click a cancel button which should redirect back to the login page and clear any state variables tracking their progress through the recovery process. The problem is I keep getting stuck on pages that even after a RedirectToAction("SomeAction", "SomeController"); I still stay on the page? The URI even changes on the browser but the page asking for email address or security question stays active. I'm using an ajax $.get() to call various actions for submit and cancel.
view is defined like this:
#using (Html.BeginForm("RecoverUserCredentialsByModel", "Account", FormMethod.Get, new { id = "form1" }))
{
<!--... three input controls and a submit and cancel button-->
<p>
<button id="btnSubmit" onclick="return CheckUserEmail()">Submit</button>
<button id="btnCancel" onclick="return CancelRecovery()">Cancel</button>
</p>
}
<script type="text/javascript">
function CheckUserEmail() {
var emailAddress = document.getElementById("EmailAddress").value;
var pictogramHref = document.getElementById("pictogramHref").src;
var pictogramAnswer = document.getElementById("Pictogram").value;
if (emailAddress != null) {
var url = "/Account/ValidateEmail";
$.get(url, { "emailAddress": emailAddress, "pictogramHref": pictogramHref, "pictogramTranslation": pictogramAnswer }, null);
return true;
}
}
</script>
<script type="text/javascript">
function CancelRecovery() {
var url = "/AuthenticationModule/Account/CancelRecovery";
$.get(url, {}, null);
return true;
}
</script>
Codebehind redirections look like:
/// <summary>
/// Global cancel recovery, clears the stateful session object and redirects back to login view
/// </summary>
/// <returns>ActionResult</returns>
[AllowAnonymous]
public ActionResult CancelRecovery()
{
LoginModel statefulLoginModel = null;
try
{
// Reset everything active and redirect to login view
statefulLoginModel = new LoginModel();
Session["LoginModel"] = statefulLoginModel;
return Redirector(statefulLoginModel);
}
catch (Exception ex)
{
// Log the error and Reset everything active and redirect to login view
FileLogger.Log(ex);
statefulLoginModel = new LoginModel();
Session["LoginModel"] = statefulLoginModel;
return Redirector(statefulLoginModel);
}
}
[AllowAnonymous]
public ActionResult Redirector(LoginModel model)
{
... some code
Session["LoginModel"] = statefulLoginModel;
if (loginState == 0)
{
RedirectToAction("LogOn");
}
}
When it hits the RedirectToAction("LogOn"); the view "RecoverUserInfo" stays active on the browser and no redirection occurs?
What am I doing wrong?
Try this..........
Proper Syntax is return RedirectToAction("ActionName","ControllerName");
In this case if Logon Action is written on the same Controller Then use following Code..
return RedirectToAction("LogOn");
or it is written on another controller then just replace your Action Name and Controller Name in the following code.
return RedirectToAction("ActionName","ControllerName");
Is there a way to make a CGridView Not load data on the initial rendering of the view it lives on, and instead make it load the first page with a subsequent AJAX request after the initial page load?
This is mostly for performance optimization. There is a data model that is rather slow behind that CGridView, and I would like to be able to have the page load in a snappy way, then have the data load up a few seconds later with an AJAX request.
You could modify the action as follows:
public function actionIndex() {
$dataProvider = new CActiveDataProvider('User'); // The dataprovider your grid uses
if (!$this->isAjaxRequest()) {
$dataProvider->criteria->addCondition('1 = 0'); // You could also use 0, but I think this is more clear
}
[...]
}
And then in your view in the javascript section:
$(function() { // If you are using jQuery this is executed when the page is loaded
$.fn.yiiGridView.update("{id-of-your-grid-view}");
});
Brewer Gorge was very close, and thanks to his suggested answer, it put me on the right track. This works:
// Controller, after creating $dataProvider, before calling $this->render...
if (!Yii::app()->request->isAjaxRequest) {
$dataProvider->criteria->addCondition('1 = 0');
}
// View
<script type="text/javascript">
$(window).load(function() {
$('#id-of-grid').yiiGridView('update');
});
</script>
Just write your code in controller like this:
$model= new Data('search');
$model->unsetAttributes();
if(isset($_GET['Data']))
$model->attributes = $_GET['Data'];
if (!Yii::app()->request->isAjaxRequest)
$data->id=0; //or something that sure model return empty
I'm having problems trying to get the unobtrusive jquery validation to work with a partial view that is loaded dynamically through an AJAX call.
I've been spending days trying to get this code to work with no luck.
Here's the View:
#model MvcApplication2.Models.test
#using (Html.BeginForm())
{
#Html.ValidationSummary(true);
<div id="res"></div>
<input id="submit" type="submit" value="submit" />
}
The Partial View:
#model MvcApplication2.Models.test
#Html.TextAreaFor(m => m.MyProperty);
#Html.ValidationMessageFor(m => m.MyProperty);
<script type="text/javascript" >
$.validator.unobtrusive.parse(document);
</script>
The Model:
public class test
{
[Required(ErrorMessage= "required field")]
public int MyProperty { get; set; }
}
The Controller:
public ActionResult GetView()
{
return PartialView("Test");
}
and finally, the javascript:
$(doument).ready(function () {
$.ajax({
url: '/test/getview',
success: function (res) {
$("#res").html(res);
$.validator.unobtrusive.parse($("#res"));
}
});
$("#submit").click(function () {
if ($("form").valid()) {
alert('valid');
return true;
} else {
alert('not valid');
return false;
}
});
The validation does not work. Even if I don't fill any information in the texbox, the submit event shows the alert ('valid').
However, if instead of loading dynamically the view, I use #Html.Partial("test", Model) to render the partial View in the main View (and I don't do the AJAX call), then the validation works just fine.
This is probably because if I load the content dynamically, the controls don't exist in the DOM yet. But I do a call to $.validator.unobtrusive.parse($("#res")); which should be enough to let the validator about the newly loaded controls...
Can anyone help ?
If you try to parse a form that is already parsed it won't update
What you could do when you add dynamic element to the form is either
You could remove the form's validation and re validate it like this:
var form = $(formSelector)
.removeData("validator") /* added by the raw jquery.validate plugin */
.removeData("unobtrusiveValidation"); /* added by the jquery unobtrusive plugin*/
$.validator.unobtrusive.parse(form);
Access the form's unobtrusiveValidation data using the jquery data method:
$(form).data('unobtrusiveValidation')
then access the rules collection and add the new elements attributes (which is somewhat complicated).
You can also check out this article on Applying unobtrusive jquery validation to dynamic content in ASP.Net MVC for a plugin used for adding dynamic elements to a form. This plugin uses the 2nd solution.
As an addition to Nadeem Khedr's answer....
If you've loaded a form in to your DOM dynamically and then call
jQuery.validator.unobtrusive.parse(form);
(with the extra bits mentioned) and are then going to submit that form using ajax remember to call
$(form).valid()
which returns true or false (and runs the actual validation) before you submit your form.
Surprisingly, when I viewed this question, the official ASP.NET docs still did not have any info about the unobtrusive parse() method or how to use it with dynamic content. I took the liberty of creating an issue at the docs repo (referencing #Nadeem's original answer) and submitting a pull request to fix it. This information is now visible in the client side validation section of the model validation topic.
add this to your _Layout.cshtml
$(function () {
//parsing the unobtrusive attributes when we get content via ajax
$(document).ajaxComplete(function () {
$.validator.unobtrusive.parse(document);
});
});
test this:
if ($.validator.unobtrusive != undefined) {
$.validator.unobtrusive.parse("form");
}
I got struck in the same problem and nothing worked except this:
$(document).ready(function () {
rebindvalidators();
});
function rebindvalidators() {
var $form = $("#id-of-form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse($form);
$form.validate($form.data("unobtrusiveValidation").options);
}
and add
// Check if the form is valid
var $form = $(this.form);
if (!$form.valid())
return;
where you are trying to save the form.
I was saving the form through Ajax call.
Hope this will help someone.
just copy this code again in end of modal code
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
;)
I like the way MVC4 manage the new logon screen: it is possible to have a modal dialog showed.
I tried to reproduce the same behavior in the same solution for another view. But it doesn't work because Request.QueryString["content"] is null. I don't know why. In fact, there is an action method called ContextDependentView (generated by the MVC template) where the trick occurred. Here it is:
private ActionResult ContextDependentView()
{
string actionName = ControllerContext.RouteData.GetRequiredString("action");
if (Request.QueryString["content"] != null)
{
ViewBag.FormAction = "Json" + actionName;
return PartialView();
}
else
{
ViewBag.FormAction = actionName;
return View();
}
}
If the value of Request.QueryString["content"] is not null then we display a partial view (modal jQuery) otherwise it is a classic view.
Can someone help me understand why this is not working?
PS: another thread already exists but without any solution.
The login and register links are bound to a click handler in AjaxLogin.js which then adds content=1 in loadAndShowDialog