calling javascript function for ajax.actionlink - asp.net-mvc

I have the following ajax.actionlink. i want to add click event to this actionlink. How can i do that
<%= Ajax.ActionLink("text", "textaction", new { param = 1}, new AjaxOptions
{
OnSuccess = "updatePlaceholder",
UpdateTargetId = "result"
})%>

The click event handler is already added to this link because you are using the Ajax.ActionLink helper method. This click event handler will cancel the default action and send an AJAX request to the address this link is pointing to. You may try setting the OnBegin option.
And if you use jquery in your project you could have a normal link (without all the javascript added to your markup by the Ajax.ActionLink helper):
<%= Html.ActionLink(
"text",
"textaction",
new { param = 1 },
new { id = "mylink" })
%>
and then in a separate javascript file attach the click event handler:
$(function() {
$('#mylink').click(function() {
// here you could execute some custom code
// before sending the AJAX request
$('#result').load(this.href, function() {
// success function
});
return false;
});
});
This way will achieve a clear separation between your markup and javascript files. As javascript will be in separate files which will be cached by client browser you will reduce bandwidth.

You need to change the code:
$('#mylink').click(function(e) {
e.preventDefault();
....do what ever you want

Related

Refresh list and not page in MVC

I have a requirement where on the left side of the page there are links and in the center, there is a table so I have to refresh the table based on the link selected however it should not refresh page, I opted for Ajax action link, however, there are issues post the implementation and I realised that is not good from design perspective so could you please help me with some solution possibly code to achieve my requirement.
#Ajax.ActionLink("click me",
"GetContacts",
"Home",
new AjaxOptions
{
UpdateTargetId = "DepartmentDetails",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
OnSuccess = "OnAjaxRequestSuccess"
}
)
Move the table to a partial view and load it on click of the link. This will just refresh the partial view instead of the entire master page.
You can use jQuery Ajax. It doesn’t required to refer any additional script for partial load.
Example:
#using (Html.BeginForm(new { id = "DepartmentDetails" }))
{
#Html.TextBox("deptName ");
<input type="submit" value="List Department" id="btnList" />
<div id="divDepartmentDetails"></div>
}
#section Scripts{
<script>
$("#btnList").click(function (event) {
$.ajax({
url: "#(Url.Action("Department"))",
type: "GET",
data: { deptName: $("deptName").val() },
success: function (data) {
$("#divDepartmentDetails").html(data);
}
});
});
</script>
}

My asp.net MVC partial view is unresponsive after initial ajax call?

I am working on an asp.net mvc 4 application and I am using a PartialView for a table in the Index view. After I make the initial ajax call the request is successful and the UI is updated accordingly. But when I try to update again, the JavaScript is unresponsive for the click event.
Is this typical?
AJAX call:
$("#button").click(function(){
$.ajax({
url: 'url',
type: "POST",
data: $("#form0").serialize()
}).done(function (allData) {
$("#mypartialId").html(allData);
ResizeContent();
}).fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
Something like this is in my controller Index action:
if(Request.IsAjaxRequest())
{
return PartialView("_PartialView", model);
}
return View(model);
Razor Ajax.BeginForm, has id of form0 by default:
#using (Ajax.BeginForm("Index", "MyController",
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "mypartialId"
}))
My partial rendering in Index:
<div id="mypartialId">
#{Html.RenderPartial("_PartialView", Model);}
</div>
This works once but when I click the button switch is in the partialView the JavaScript becomes unresponsive. I am guess its something with the Index view not reloading with the partialView...would there be any way around that?
I used .on() function instead of just the .click() as #Sergey Akopov suggested. After that I had another problem after that because the data coming back was a table, so IE9 was giving me UI problems.
The fix was to remove the white space from the table tags like so, before injecting it into the DOM
var expr = new RegExp('>[ \t\r\n\v\f]*<', 'g');
table = table.replace(expr, '><');
$("#mypartialId").html(table);
Here is a link to the 'td' issue displaying weird in IE9.

Getting a toggle image to work properly on mvc page?

Using MVC 3.
(The code below was an attempt to recreate the toggle effect of stackoverflow's checked answer)
I have a ajax actionlink when you click it calls an update to db to switch the flag/image. However it works one time, if I click it again it will not toggle. Because there is no postback, model.IsIssue is not updated (its server code). Not sure the best approach to fix the issue. Should I handle it in the code, where I check the current flag in db and pass it back to the view. Or via Jquery, not sure how to code it (my preference)?
My code in the view (toggle):
<div>
#Html.Raw(
Ajax.ActionLink("[replacethis]",
"ToggleEnabled",
new { questionId = question.QuestionID, reviewId = step.ReviewID, flag = question.IsIssue },
new AjaxOptions { UpdateTargetId = "toggleimage" + question.QuestionID })
.ToHtmlString()
.Replace("[replacethis]",
string.Format("<div id='toggleimage{0}'><img src='/Content/images/{1}' border='0' alt='toggle'/></div>",
question.QuestionID, question.IsIssue ? "issue_on.png" : "issue_off.png")
)
)
My action controller:
public ActionResult ToggleEnabled(int questionId, int reviewId, bool flag)
{
using (var db = new NexGenContext())
{
db.Database.ExecuteSqlCommand(
"EXEC SP_AddUpdateQuestionFlagged #QuestionID, #ReviewID",
new SqlParameter("#QuestionID", questionId),
new SqlParameter("#ReviewID", reviewId)
);
return flag ? Content("<img src='/Content/images/issue_off.png' border=0 />") : Content("<img src='/Content/images/issue_on.png' border=0 />");
}
}
I would just change a css class to toggle the image.
So instead of holding the image in img ... I would use a div and placing the image as a background.
So, instead of replacing the html with the DIV and IMG in it (what removes the callback to handle the click), just change the class of the div.
In your view:
<div id="myimage" class="NormalState"></div>
In JS:
$('#myimage').click(function () {
$.ajax({
url: 'yourControllerActionURL'
type: 'POST',
contentType: "application/json; charset=utf-8",
data: {'questionId': question.QuestionID, 'reviewId': step.ReviewID, 'flag': question.IsIssue },
success: function (data) {
if(data.isClicked == true){
$('#myimage').addClass('ClickState').removeClass('NormalState');
}
else{
$('#myimage').addClass('NormalState').removeClass('ClickState');
}
}
});
});
In your CSS:
.NormalState { background-color: #ABCDEF;}
.ClickState { background-color: #FF0000;}
In your controller:
You need to return JSON with isClicked set as true or false. You could also return the css class to apply from the controller, but that way your controller knows about the view and that is not the idea of the MVC pattern. So telling the view what happenned more suitable.

jQuery Ajax Form Submit Fails

I am developing an MVC4 mobile app that uses several forms which are loaded into a section on the layout via ajax. I've got jQuery mobile set with Ajax turned off so I can manage the Ajax myself. Most of the forms work fine, the load and submit via ajax as they should. However, so far there is one form that refuses to fire the form submit and submit the form via ajax like the rest. First, the form is loaded when a user clicks to add a contact and this works fine:
// Handle the add contact button click
$('#btnAddNewContact').on('click', function (e) {
e.preventDefault();
// Make sure a location was selected first.
var locationID = $('#cboLocation').val();
if (locationID.length === 0) {
//$('#alertTitle').text('REQUIRED');
$('#alertMsg').html("<p>A Contact must be associated with a Location.</p><p>Please select or add a Location first.</p>");
$('#alertDialogDisplay').click();
} else {
SaveOpportunityFormState();
$.cookie('cmdLocationId', locationID, { path: '/' });
$.mobile.loading('show');
$.ajax({
url: '/Contact/Add',
type: 'GET',
cache: false,
success: function (response, status, XMLHttpRequest) {
$('section.ui-content-Override').html(response);
// Refresh the page to apply jQuery Mobile styles.
$('section.ui-content-Override').trigger('create');
// Force client side validation.
$.validator.unobtrusive.parse($('section.ui-content-Override'));
},
complete: function () {
$.cookie('cmdPreviousPage', '/Opportunity/Add', { path: '/' });
AddContactLoad();
ShowSearchHeader(false);
$.mobile.loading('hide');
},
error: function (xhr, status, error) {
// TODO - See if we need to handle errors here.
}
});
}
return false;
});
Notice that after successfully loading the form the AddContactLoad() function is fired. This works fine and here is that code:
function AddContactLoad() {
$('#contactVM_Phone').mask('(999) 999-9999? x99999');
$('#frmAddContact').on('submit', function (e) {
e.preventDefault();
if ($(this).valid()) {
$.mobile.loading('show');
$.ajax({
url: '/Contact/Add',
type: 'POST',
cache: false,
data: $(this).serialize(),
success: function (response, status, XMLHttpRequest) {
if (!response) { // Success
ReturnToAddOpportunity();
} else { // Invalid Form
$('section.ui-content-Override').html(response);
// Force jQuery Mobile to apply styles.
$('section.ui-content-Override').trigger('create');
// Force client side validation.
$.validator.unobtrusive.parse($('section.ui-content-Override'));
AddContactLoad();
$.mobile.loading('hide');
}
},
complete: function () {
},
error: function (xhr, status, error) {
// TODO - See if we need to handle errors here.
}
});
}
return false;
});
$('#btnCancel').on('click', function (e) {
e.preventDefault();
// See where add contact was called from.
var previousPage = $.cookie('cmdPreviousPage');
if (previousPage.indexOf("Detail") >= 0) {
ReturnToOpportunityDetails();
} else {
ReturnToAddOpportunity();
}
return false;
});
}
If I click the cancel button, that code is fired so I know this is working too. Here is my form code:
#using (Html.BeginForm("Add", "Contact", FormMethod.Post, new { #id = "frmAddContact" }))
{
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
-- Form Fields Here --
<div class="savecancel" >
<input type="submit" value="Save" data-mini="true", data-theme="b", data-inline="true" />
Cancel
</div>
}
As you can see the form is named frmAddContact and that is what the AddContactLoad() function is attaching the submit event to. To save my sole I cannot figure out why the form does not submit via the ajax post like every other form in the app. Am I missing some kind of initialization, I just don't know. If anyone can please help I'd really appreciate it!!
As it turns out, I had created a custom unobtrusive Ajax validator for a phone number then copied and pasted it to do the same with a zip code. Unfortunately in the process I forgot to rename a variable and thus an error was occurring in the validation script which caused the problem. In the mean time, if you're reading this, you might take a note of the code here and how to inject HTML into a page via Ajax and jQuery mobile. I've never found this in a book or on the web and it contains some very useful methodology and syntax. On the form submit the reason I'm checking for the empty response is I just return null from the controller to validate the form was valid and the save worked in which case I send them to a different HTML injection i.e. that page they originally came from. If null is not returned I inject that page with the HTML containing the original form and error markup so the user can make corrections then resubmit. I'm also calling a form load method that attaches handlers to the HTML once it's injected into the main page. Hope this helps somebody!

Replace the Ajax.ActionLink by the same functionality with jQuery

With asp.net mvc we can do an ajax call like this:
#{
var ajaxOpts = new AjaxOptions { UpdateTargetId = "main-content", OnBegin = "fctTabLoading", OnComplete = "fctTabLoaded", InsertionMode = InsertionMode.Replace };
}
#Ajax.ActionLink("my link text", "MyAction", "MyController", new { id = Model.RequestID }, ajaxOpts)
Which produce the following html:
<a data-ajax="true" data-ajax-begin="fctTabLoading" data-ajax-complete="fctTabLoaded" data-ajax-mode="replace" data-ajax-update="#main-content" href="/MyController/MyAction/19">my link text</a>
Now I would like to execute the same ajax call but from jQuery and I don't know how to proceed!
I would like something like:
$.ajax({
type: "Post",
url: myURL,
begin: fctTabLoading,
complete: fctTabLoaded,
mode: "replace",
update: "#main-content",
cache: false,
success: function () { alert('success'); }
});
I know the above ajax script won't work because 'mode' and 'update' are not recognized. So I am blocked.
It drives me crazy :(
Why I cannot use the MVC ActionLink? Because I first need to show a jquery dialog to let the user confirm then only do the ajax call in order to refresh a specific div on my page.
Any help is greatly appreciated.
Thanks.
You could start by replacing your Ajax link with a normal link:
#Html.ActionLink(
"my link text", // linkText
"MyAction", // actionName
"MyController", // controllerName
new { id = Model.RequestID }, // routeValues
new { id = "mylink" } // htmlAttributes
)
which will produce the following markup:
my link text
and then in a separate js file unobtrusively AJAXify it:
$(function() {
$('#mylink').click(function() {
$.ajax({
url: this.href,
type: 'POST',
beforeSend: fctTabLoading, // corresponds to your OnBegin callback
complete: fctTabLoaded, // corresponds to your OnComplete callback
success: function(result) {
$('#main-content').html(result);
}
});
return false;
});
});
As you know, the Ajax.ActionLink uses jquery.unobtrusive-ajax.js to execute the ajax links.
If you look at that file, you will see that the event handlers use jquery's live event binder. This binds the event listener to the document object. So, if you wanted to confirm before this event was triggered, you could bind directly to the element like the following:
$('#YOUR_ELEMENT').click(function () {
var confirmed = confirm("CONFIRM_MESSAGE");
if (!confirmed ) {
return false;
}
return true;
});
To use jquery dialog you could do the following:
function confirmDialog () {
$('#YOUR_DIALOG').dialog(
{ buttons: { "Ok": function() { return true; },
{ "Cancel": function() {return false;}
}
});
}
and then you would set confirmed in the previous function to confirmDialog().
***The dialog options may not be exactly what you want, but this should get you going.

Resources