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

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.

Related

How to call partial view in script section

I am new in MVC. I have a button when i click it should go to a partial view and return data i need. I do not know how should i achieve that:
Main view:
<script>
if ($("#btnFilter").click(function () {
#{Html.RenderPartial("partialView"); }
}));
</script>
partial view
var dtDrpVals = new selectedDateDrpdnVal();
debugger;
$.ajax({
dataType: "json",
type: "POST",
url: "#Url.Action("controller","Dashbrd")",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ "regionalManager": dtDrpVals.drpValue, "dtFrom": dtDrpVals.fromDate, "dtTo": dtDrpVals.toDate }),
success: function (result) {
}
});
In the html define a div where you want the partial to be located in and in the ajax success put the result of the call to the controller into that div, assuming you are returning a partialview:
$("#The id of the div").html(result);
The best way to do it is Make an Action in your ASP.NET controller that returns a Partial View and in your jquery, you should make an AJAX call to that action with required parameters that eventually will return a Partial View to your Jquery, and the data you will receive from your action will be of type 'HTML' and not JSON.
once you receive HTML data in your success function of AJAX call you can replace it with any Div.

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>
}

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!

calling javascript function for ajax.actionlink

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

Resources