Calling preventDefault on DOM element - asp.net-mvc

I am currently in the process of creating an MVC4 web application, and I seem to have run into a weird issue. I have created a unordered list with some list items in it, and their respective anchor tags, in which I am going to be able to click, that will return the respective /CONTROLLER/ACTION view.
<div>
<ul>
<li>
<a class="ajax" href="/Test/One"></a>
</li>
<li>
<a class="ajax" href="/Test/Two"></a>
</li>
<li>
<a class="ajax" href="/Test/Three"></a>
</li>
<li>
<a class="ajax" href="/Test/Four"></a>
</li>
</ul>
</div>
<div id="body">
</div>
I have then created some jQuery to call when you click either of the anchor tags, looking for a class of "ajax", and if you are to click the anchor tag, it will then run another function called GetContent, passing through the HREF value of the anchor tag, which will be used as the path for the ajax call.
$(document).ready(function () {
$(".ajax").click(function () {
var path = $(this).attr("href");
GetContent(path);
});
});
function GetContent(path) {
$.ajax({
url: path,
type: 'POST',
async: false,
success: function (result) {
$("#body").html(result);
}
});
}
I have heard of a function you can call, called preventDefault I believe. I am finding that I am not sure when to call this preventDefault to override the click of the anchor tag.
I did try placing it into a couple of places, but with no luck... I am finding at the moment I am able to click any of the anchor tags, and the default action occurs, it simply returns the whole website with the new view loaded. However if I open up the console in google chrome developer tools, and call the function GetContent, passing through the path I am expecting, it will then call the function, return the ajax, and update my web page.
If someone is able to point out where I am supposed to call the preventDefault function that would be great.

preventDefault is a method of event object. You get the reference to event object as first param of the click event handler…
$(".ajax").click(function (event) {
var path = $(this).attr("href");
GetContent(path);
event.preventDefault();
});

Related

jquery mobile load external page, events not getting triggered

I want to transition to an external jquery mobile page, but none event is getting trigger, when the transition is called:
jQuery("#test1").on("pagebeforeshow", function(event) {
WL.Logger.debug("pagebeforeshow: test1");
});
function loadHTML(){
$.mobile.pageContainer.pagecontainer("load", "./pages/test1/test1.html", {});
}
function openHTML(){
$.mobile.pageContainer.pagecontainer("change", "./pages/test1/test1.html", {});
}
and this is the content on my HTML :
<div data-role="page" id="test1">
<div data-role="content" style="padding: 15px"></div>
</div>
Is there any way to use any event?
To attach the pagebeforeshow handler to a page not loaded into the DOM yet, you must use event delegation:
https://learn.jquery.com/events/event-delegation/
jQuery(document).on("pagebeforeshow", "#test1" function(event) {...

Partial view in a dialog

I have managed to get the JQuery Modal dialog to show and within it, I load a partial view:
var url = '#Url.Action("ShowCarDetail", "Car")?id=' + id;
$('#dialog-modal').dialog(
{
title: "Car Detail",
width: 600,
height: 500,
draggable: false,
close: function (event, ui) {
$(this).dialog('close');
}
});
$('#dialog-modal').load(url, function()
{
$(this).dialog('open');
});
So that works fine. The problem is that when the dialog is closed, and I re-open it, the data is not refreshed. I have a DateTime on that partial view that tells me this so leaving it for a few seconds still shows me the old values.
how can I force the modal dialog to load correctly (without it using the old html that may have been rendered from the previous request)?
also - if the partial view has some actions like a submit or something, will the dialog still remain open or will this refresh the page fully? I want to be able to have that modal dialog similar to an iframe style where any actions that happen within the page in the modal will still be there and be updated without the page having a full refresh and the dialog closing.
thanks
Regarding your question:
also - if the partial view has some actions like a submit or
something, will the dialog still remain open or will this refresh the
page fully? I want to be able to have that modal dialog similar to an
iframe style where any actions that happen within the page in the
modal will still be there and be updated without the page having a
full refresh and the dialog closing.
The page will be refreshed fully with a normal form. To achieve what you describe, use an ajax form which does a post to a controller method and returns a partial view. Then have a success callback for the ajax form, which would replace the contents of a div (within the open dialog) with the response content (which would be the partial view returned from the post).
Simplified example...
View:
<div id="dialog-modal">
<p>Some optional static content here (within the dialog)
that should not change when the form is submitted.</p>
<div id="dialog-content">
#using (Html.BeginForm("MyAction", "MyController", null, FormMethod.Post, new { #id="MyForm" }))
{
#Html.EditorFor(x => x.Foo)
<input type="submit" value="OK" />
}
</div>
</div>
Controller:
[HttpPost]
public ActionResult MyAction(MyModel model)
{
// Do some stuff here with the model if you want
MyNewModel newModel = new MyNewModel();
return PartialView("_MyPartialView", newModel);
}
JavaScript:
$(function () {
$('#MyForm').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (xhr) {
$('#dialog-content').html(xhr);
}
});
return false;
});
});
Note that this implementation will replace the form, so you could put the form outside the div that gets replaced if needed, or have a different form in the partial view that gets returned if you want different forms submitted within the dialog in series. It's flexible to tweak to your needs. It also will not close the dialog until you explicitly call close on it, or affect any content outside of the replaced div's content. Hope this helps!

jQuery UI Modal Dialogs in MVC

Excuse me for the simplistic question, but I've had a hard time getting my head around this. I have a View (.cshtml) with the following contents (Per this sample):
<div id='dlgLogin'>
<h1>Log in</h1>
<table>
<tr>
<td>Username:</td>
<td>#Html.TextBox("username")</td>
</tr>
<tr>
<td>Password:</td>
<td>#Html.Password("password")</td>
</tr>
</table>
</div>
<script type="text/javascript">
$(function () {
$("#dlgLogin").dialog({
modal: true,
autoOpen: true,
resizable: false,
buttons: {
Login: function () {
// perform login
$.post("#Url.Action("Login", "Home")",
{
username: $('#username').val(),
password: $('#password').val()
},
function( data, status, xhr ) {
if(data.Success){
alert('great'); // do something
$('#dlgLogin').dialog("close");
$('#divLoginButton').load("#Url.Action("GetLoginButton", "Home")");
} else {
// do something else
}
});
},
Cancel: function () {
$(this).dialog("close");
}
}
});
});
</script>
Basically the View will always load in a jQuery UI Dialog whenever it's opened, that is, it's the responsibility of the View itself to place it's own content inside a jQuery UI dialog. I've done this so that I can override the OnAuthorzation() event of my Log In and redirect the user to a pop up when they are required to log in. I have 3 questions:
1. How would I display a loading animation (a .gif) when the form is posted back to the server? With this approach? I'm aware that if I used an Ajax.BeginForm I could have specified a UpdateTargetId which would have been used as an area to load the animation during post back, but how would I achieve that effect with this approach?
2. How would I attach and handle the success event to the form post above? i.e. When the form is posted back to the Login Action of the Home Controller.
3. I've seeing at least 3 or 4 different approaches to displaying dialogs in MVC. What is the correct way to do this? Is the approach that I posted above considered good/mvc-friendly practise, if not what do you recommend?
1 How would I display a loading animation (a .gif) when the form is posted back to the server?
Take a look at ajaxSend:
<div id="loader"></div>
$("#loader").bind("ajaxSend", function () {
$(this).show();
}).bind("ajaxStop", function () {
$(this).hide();
}).bind("ajaxError", function () {
$(this).hide();
});
2 How would I attach and handle the success event to the form post above?
I don't understand what you are asking. You have attached an anonymous function to handle the post to the server in your sample code.
3 I've seeing at least 3 or 4 different approaches to displaying dialogs in MVC. What is the correct way to do this?
There is no best way of showing a dialog.
You can use the approach you showed with loading the dialog content with the page, but i would add a style="display: none;" to the dialogs div. Another approach would be to load the dialog content with ajax from a partial view when opening the dialog.

unwanted multiple ajax request to an action in asp.net mvc

I am developing an asp.net mvc application and have ajax calls on my page. Here is a form which I load by ajax call to page :
The form is located in a partial view
<div id="CreateCultureArea">
<%
using (Ajax.BeginForm("CreateCulture", "Admin", new AjaxOptions() { OnSuccess = "handleCreateCulture" }))
{ %>
.....
<% } %>
</div>
Code Updated
The following script is located in a view :
Create Culture
<script type="text/javascript">
$('.CreateCulture').live('click', function (e) {
e.preventDefault();
var idval = this.id;
$.ajax({
url: "/Admin/CreateCulture",
dataType: 'html',
data: { id: idval },
success: function (mydata) {
$("#CultureContentArea").empty();
$("#CultureContentArea").empty().hide().append(mydata).fadeIn(2000);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
},
type: "GET"
});
return false;
})
</script>
When users click on a link with CreateCulture class, the form is loaded to page. But as I saw the requests in firebug, it calls the action multiple times. I read similar posts like mine on stackoverflow.com and most of them suggested removing repetitive "jquery.unobtrusive-ajax.min.js" calss in page, but as I saw the output page I only see on link to the "jquery.unobtrusive-ajax.min.js" script.
The problem is that #Ajax.BeginForm emits a form that has the attribute data-ajax="true". In the unobtrusive AJAX script (see the non-minified version and look for calls to asyncRequest). So by calling $.ajax yourself, you are repeating the work of #Ajax.BeginForm. Just take out your call to $.ajax and you'll see your action get called only once.
If you need to take action after the AJAX call completes, set the OnComplete property of AjaxOptions in your call to Ajax.BeginForm.
Make sure that you have not multiple .js refrence in page
<script src='/Scripts/jquery.unobtrusive-ajax.min.js'></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
The problem was that I put some scripts in partial view and each time it duplicated by loading this. So I put the scripts all in on page and problem solved.

Display MVC3 Unobtrusive ValidationSummary errors in a jQuery UI Dialog

I'm looking to display MVC3's unobtrusive ValidationSummary errors in a jQuery UI Dialog. Specifically, I want to be able to have a "live" $('.validation-summary-errors').dialog(...);-like experience. That is to say, whenever MVC3 client-side validation would show (for the first time) or update (on repeat offenses) the .validation-summary-errors element, I want the results to appear in a jQuery UI Dialog.
I currently have something along the lines of
#Using Html.BeginForm("Action", "Controller", FormMethod.Post, New With {.id = "MyForm"})
#Html.ValidationSummary()
...
$('#MyForm').submit(function () {
if (!$(this).valid()) {
$('.validation-summary-errors').dialog(...);
return false;
}
});
but this doesn't feel right to me.
It feels like I should be able to hook into the validation framework and be notified that validation completed, and there was an error summary that is now shown or updated with the errors. Then using that event, dialog() the now-shown/updated .validation-summary-errors element. Is there such a thing? Or are there any other suggestions?
So this is how I ended up doing it. I didn't find much documentation, but did enough JS digging to get to this point. Not sure how I feel about it. I do know that I no longer need to hook the form's submit event and "double-up" on the validation calls, so that's good. It just seems that this solution feels "cryptic" (at least in my inexperienced eyes), and I would have expected (and am still looking for) a solution that feels more baked-in.
$(function () {
// If there is an error element already (server side error), show it.
showValidationSummaryDialog();
// When the form validates, and there is an error element, show it
$('#MyForm').bind('invalid-form.validate', function (error, element) {
showValidationSummaryDialog();
}
}
function showValidationSummaryDialog() {
$('.validation-summary-errors').dialog({
title: 'Unable to Save',
close: function () {
$(this).dialog('destroy')
.prependTo($('#MyForm')); // jQuery moves the source element out of the DOM.
// We need to put it back in its place afterwards for validation to maintain its contents.
// TODO: Is there a better way?
}
});
}
If some one want to display both ValidationSummary & ValidationSummaryDialog then try this.
as per #ckittel.
#using (Html.BeginForm())
{
#Html.ValidationSummary()
<div id="ValidationSummary" style="display:none" class="validation-summary-errors">
</div>
}
<script type="text/javascript">
function showValidationSummaryDialog() {
$('#ValidationSummary').html($('.validation-summary-errors').html());
$('#ValidationSummary').dialog({
title: 'Error',
modal: true
});
}
$(document).ready(function () {
$('form').bind('invalid-form.validate', function (error, element) {
showValidationSummaryDialog();
});
});
</script>

Resources