Form default value not wanted after ajax submission - c#

I have this script, what it intends to do is: in a view with a list of contacts, each one with a edit link whenever you click on one of these links it displays an edit form in a partial view (there's only one div in the parent view for holding it) just below the clicked contact, for that it does a get ajax call to the server and gets the information for that contact. After submitting, via ajax as well, it refreshes the list.
Everything seems to work fine, but if I edit a contact, after the list being refreshed I try to open again the form on the same contact and the information is the same as it was before being edited. Although debugging I see the list for the server is correct (and so is the display in the list, it's only wrong in the form)
Thing is that in chrome developer tool I can see the form with some "default values" set to the previous stuff. I didn't know about them till now and I don't know how to get rid of them, because to my understanding I'm making a get call to the server, anyway I have tried this
document.getElementById("editForm").reset();
with no luck.
Thanks
The script
(function ($) {
var editContainer = $(document.getElementById('editContainer'));
$('#editContainer').on('submit', '#editForm', ajaxEditCall);
$('a.edit').on("click", displayEditForm);
function displayEditForm(e) {
var clickedElement = $(this).parent(),
url = editContainer.data('amp-edit-url');
$.get(url, {
id: parseInt(this.id, 10)
}, function (result) {
editContainer.html(result);
$.validator.unobtrusive.parse(editContainer);
// Display edit form just below the "item" clicked
if (editContainer.is(":visible")) {
editContainer.slideToggle(300, function () {
editContainer.appendTo(clickedElement);
editContainer.slideToggle(300);
});
} else {
editContainer.appendTo(clickedElement);
editContainer.slideToggle(300);
}
}, "html");
e.preventDefault();
}
function ajaxEditCall(e) {
e.preventDefault();
//if ($('#editForm').valid()) {
var list = $(document.getElementById('list'));
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.passedValidation == true) {
$.get(result.action, function (partial) {
document.getElementById("editForm").reset();
list.html(partial);
$('a.edit').on("click", displayEditForm);
$('#editForm').slideUp(300);
setTimeout(function () {
list.effect("highlight", {}, 3000);
}, 1000);
});
} else {
$(document).scrollTop(0);
editContainer.html(result);
$.validator.unobtrusive.parse('#editForm');
}
}
});
//} return false;
}
}(jQuery));
And the view in case is relevant
#model ContactListViewModel
#{
ViewBag.Title = " My Contacts";
}
<div id="myContacts">
<h2>My Contacts</h2>
<div id="editContainer" data-amp-edit-url="#Url.Action("Edit", "Contacts")" class="initiallyHidden"></div>
<div id="list">
#{ Html.RenderPartial("_ContactList", Model); }
</div>
<div id="dialog" data-amp-del-url="#Url.Action("Delete", "Contacts")" title="Confirmation Required">
<p>Are you sure you want to delete this Contact?</p>
</div>
</div>
#section Foot
{
<script src="~/Scripts/AMPContacts.js"></script>
<script src="~/Scripts/conditional-validation.js"></script>
<script src="~/Scripts/Placeholders.min.js"></script>
}
Well that's obviously the parent view, the partial one is just a bunch of fields, I remove most of them to avoid increase the already long post
#model AddContactViewModel
#using (Html.BeginForm("Edit", "Contacts", FormMethod.Post, new { #id = "editForm", #class = "addTab" }))
{
#Html.ValidationSummary(true, "Please correct the errors and try again.")
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.OwnedItemId)
#Html.HiddenFor(m => m.AddressId)
<div id="editContactDetails">
<div>
#Html.DisplayFor(m => m.PlanName)
</div>
<div>
#Html.DropDownListFor(m => m.Title, Model.TitleList, "Title")
</div>
<div>
#Html.EditorFor(m => m.FirstName, new { #id="editFirstName", data_placeholders_focus = "false", placeholder = ViewData.ModelMetadata.Watermark })
#Html.ValidationMessageFor(m => m.FirstName)
</div>
// And so on....
<div class="addDEC">
<input class="addDECButton" type="submit" value="Save" />
</div>
}

I ran into this problem with a site I was working on. You'll need to disable your ajax caching:
//Disbable cache for all jQuery AJAX requests
$.ajaxSetup({ cache: false });
That will do it for all ajax calls, so you may only want to do that on certain pages, depending on your usage.

Related

ASP.Net MVC Delete without load entire page

I'm still new to asp.net mvc, i want to delete list of partial view, the delete is working but i must reload the entire page to show the new list
What I want is the partial view show the new list after delete without load the entire page, so only the partial view is updated
Here is my code:
My view content some of partial view :
#model cc.Models.User
#{
Layout = "~/Views/Shared/_MemberLayout.cshtml";
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcValidation.debug.js")" type="text/javascript"></script>
<body class="container body-content">
<div id="partialView1">
#Html.Action(...)
</div>
<div id="partialView2">
#Html.Action(...)
</div>
<div id="partialView4">
#Html.Action(...)
</div>
<div id="partialView3" class="col-md-8 col-sm-1">
#Html.Action("UserHistory", "User")
</div>
</body>
Here is my partial view for UserHistory I tried to use ajax but it's not work. I already tried to use
$(this).closest('.historyRow').remove();
and
$("a.deleteHistory").live("click", function () {
$(this).parents("div.historyRow:first").remove();
return false;
});
Here is my code :
#model cc.Models.UserHistory
#{
Layout = null;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcValidation.debug.js")" type="text/javascript"></script>
<div id="formHistory">
<div id="historyDetail">
<div id="editDataHistoryUser">
#foreach (var item in Model.History)
{
#Html.Partial("UserHistoryDetail", item)
}
</div>
#Html.ActionLink("Add Form", "AddUserHistory", null, new { id = "btnFormHistory" })
</div>
</div>
<script type="text/javascript">
$("#btnFormHistory").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editDataHistoryUser").append(html); }
});
return false;
});
$('#formHistory').on('click', '.deleteHistory', function () {
var id = $(this).data('id');
if (id == 0) {
$(this).closest('.historyRow').remove();
//$("a.deleteHistory").live("click", function () {
// $(this).parents("div.historyRow:first").remove();
// return false;
//});
} else {
var url = '#Url.Action("DeleteUserHistory", "User")';
$.post(url, { ID: id }, function (response) {
if (response) {
$(this).closest('.historyRow').remove();
//$("a.deleteHistory").live("click", function () {
// $(this).parents("div.historyRow:first").remove();
// return false;
//});
}
}).fail(function (response) {
});
}
});
</script>
Here is my UserHistoryDetail Code :
#model cc.Models.IUserHistory
#{
Layout = null;
}
<div id="formUserHistoryDetail">
#using (Ajax.BeginForm("UserHistoryDetail", "User", new AjaxOptions { HttpMethod = "POST" }))
{
<div id="historyRow">
<div>#Html.LabelFor(model => model.IDHistory, new { style = "display:none;" })</div>
...
delete
</div>
}
</div>
And here is my JsonResult when button delete clicked :
[HttpPost]
public JsonResult DeleteUserHistory(string ID)
{
db.delUserHistory(ID);
return Json(true);
}
I still cannot find the solution for this , or maybe i used ajax in wrong way, any suggestion?
Let's assume that the DeleteUserHistory post url is '/[Controller]/': '/UserHistory'
$('.deleteHistory').click(function(){
var url = '/UserHistory';
$.ajax({
type: "POST",
url: url,
data: data,
success: onSuccessCallback
});
});
What you should really do is use WebApi to manage data and use the views to display.
As for the delete, use method type 'delete' instead of 'post'. Post should be used for "adds".

Rendering a Partial View on button click in a div C# MVC 5

I have been following the answers on here but can't seem to get it to work. I think it's firing my function and calling my controller but it isn't rendering my partial view. Any help would be awesome.
Controller
public ActionResult Detail(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User_Accounts user_accounts = db.User_Accounts.Find(id);
if (user_accounts == null)
{
return HttpNotFound();
}
return PartialView("_Detail", user_accounts);
}
HTML
<h2>Index</h2>
<div class="container left">
<div class="panel-default panelbox" style="position:static">
#*<p>
#Html.ActionLink("Create New", "Create")*#
#using (Html.BeginForm("Index", "Users", FormMethod.Get))
{
<p>
Type: #Html.DropDownList("userType", "All")
</p>
<p>
Last Name: #Html.TextBox("SearchString")
</p>
}
</div>
<div class="panel panel-default left">
<div class="panel-heading">
<label style="text-align:center">
User
</label>
</div>
<div class="table-responsive">
<table id="UserTable" class="table-bordered table leftPanel table-condensed">
#foreach (var item in Model)
{
<tr>
<td>
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' id="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
#*#Html.ActionLink(item.DisplayName, "Detail", new { id = item.user_id_IN }, new { onclick = "renderPartial();" })*#
</td>
</tr>
}
</table>
</div>
</div>
</div>
<div>
<label>Details</label>
<div id="detailsDiv"></div>
</div>
Script
<script>
$('.js-reload-details').click(function (evt) {
var $detailDiv = $('#detailsDiv'),
url = $(this).data('url');
$.get(url, function (data) {
$detailsDiv.replaceWith(data);
});
});
</script>
Let me know if you need anything else.
You cant use data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' in your button to generate a url. #Html.Action() is a method which calls you controller. What would be happening is that for each item in your model you would be hitting the Detail method of UsersController (performance must of been awful if you had a lot of items :) ).
Since you appear to need only the one url (/Users/Detail) I suggest you just store the ID in data to minimize the html generated. As noted in the other answers you also need to use a class name for the button to prevent invalid html, and I also suggest using type="button" because the default (depending on the browser) may be "submit" (you don't have a form so does not matter in this case, but its good practice to get into). There is also no real need to use #Html.DisplayFor() unless your using a custom DisplayTemplate or have a [DisplayFormat] attribute on the property.
Change the html to
<button type="button" data-id="#item.user_id_IN" class="js-reload-details">#item.DisplayName</button>
and the script to
var url = '#Url.Action("Detail", "Users");
$('.js-reload-details').click(function() {
$.get(url, { id: $(this).data('id') }, function (data) {
$('#detailsDiv').html(data);
});
});
Note you do not want to use replaceWith() in your case. .replaceWith() would replace the actual div <div id="detailsDiv"></div> with the html your method returned, so the next time a user clicked on this or any other button, the method would be called, but <div id="detailsDiv"></div> no longer exists and nothing would happen.
$('#detailsDiv').html('Hello world');
renders
<div id="detailsDiv">Hello world</div>
but
$('#detailsDiv').replaceWith('Hello world');
renders
Hello world
The id of your button id="js-reload-details"
Mistake this code is repeated in a foreach loop. which will cause multiple id's of the same name on your HTML page.
Your click event is on : '.js-reload-details'. which is a class:
so make your code like this:
#foreach (var item in Model)
{
<tr>
<td>
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' class="js-reload-details">
#Html.DisplayFor(modelItem => item.DisplayName)
</button>
</td>
</tr>
}
One error I noticed in your jQuery is that you have $detailsDiv.replaceWith(data);
It should be $detailDiv according to your code: var detailDiv = $('#detailsDiv'); instead of $detailsDiv
<script>
$(document).ready(function(){
$('.js-reload-details').click(function (evt) {
evt.stopPropagation();
var detailDiv = $('#detailsDiv');
// TRY using the attr function:
var url = $(this).attr("data-url");
$.get(url, function (data) {
detailDiv.html(data);
});
});
});
</script>
UPDATE:
<script>
$(document).ready(function(){
$('.js-reload-details').click(function (evt) {
evt.stopPropagation();
var detailDiv = $('#detailsDiv');
// TRY using the attr function:
var url = $(this).attr("data-url");
$.get(url).success(function(result) {
detailDiv.html(result);
});
});
</script>
It's a good practice we use unique id's for our HTML elements. Since the following statement is going to be executed mulitple times
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' id="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
You will have multiple buttons with the same id. Instead of doing so, you could use a class.
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' #class="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
Then you have to correct your script:
// Now we bound the click event in all the elements that contain
// the .js-reload-details class
$('.js-reload-details').click(function (evt) {
var $detailDiv = $('#detailsDiv');
// Here was your the error
var url = $(this).attr("data-url");
$.get(url, function (data) {
$detailsDiv.replaceWith(data);
});
});

Jquery template anchor tag click

SO i have this jquery template and i need to call a jquery or javascript function on the click of this anchor tag. Ive tried it a few different ways.
<a href="yourfunction()"
Ive tried
$('#number').click(function(e){
So if anyone could help it would be highly appreciated. The anchor tag in question is the phone number one with the id of number.
#model OpenRoad.Web.Areas.Marketing.Models.MobyNumberSelectionModel
#{
ViewBag.Title = "Moby Number Selection";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section scripts {
<script type ="text/javascript">
$('#number').click(function (e) {
alert('test');
});
});
mixpanel.track("View Marketing | Moby | Number Selection");
//$(document).on("click", "#number", function (e) {
// event.preventDefault();
// alert('test'); });
//$('#number').click(function (e) {
// Alert('test');
//});
</script>
}
<label class="lgform" style="text-align: left; padding: 10px 0;">Select state and area code:</label>
#Html.DropDownListFor(m => m.State, OpenRoad.Web.Helpers.DropDownLists.GetOptionValues("States", Model.State),
new { #class = "ddtrigger", data_url = "/Marketing/Moby/GetAreaCodes", data_template = "areaCodeTemplate", data_target = "AreaCode" })
#Html.DropDownListFor(m => m.AreaCode, (IEnumerable<SelectListItem>)ViewData["AreaCodes"],
new { #class = "ddtrigger", data_url = "/Marketing/Moby/GetPhoneNumbers",
data_template = "phoneNumberTemplate",
data_target = "phoneNumbers",
data_listtarget="true" })
#Html.HiddenFor(m => m.MobyNumber)
<script id="areaCodeTemplate" type="text/x-jquery-template">
<option value="${AreaCode}">${AreaCode}</option>
</script>
<br />
<script id="phoneNumberTemplate" type="text/x-jquery-template">
<div class="numberselectbox">
<strong>${FormattedPhoneNumber}</strong> Select<br/>
</div>
</script>
<div id="phoneNumbers">
</div>
Since you are using a template to generate the elements, these elements will be dynamic so you need to use delegated event model.
Also since it is a template, do not use static id for the elements since the elements can be duplicated - use class attribute instead
<script id="phoneNumberTemplate" type="text/x-jquery-template">
<div class="numberselectbox">
<strong>${FormattedPhoneNumber}</strong> Select<br/>
</div>
$(document).on('click', '.number', function(){
//do something
})
You could try jQuery's on() method or click() shorthand:
$(document).ready( function() {
$('#number').on('click', function(e){
// your method implementation here
e.preventDefault();
});
// OR //
$('#number').click(function(e){
// your method implementation here
e.preventDefault();
});
});

Reloading partial page after jQuery ajax command

I am very new to both JQuery and Asp.net MVC 3 (C#), so I apologize if this is trivial. I have an MVC partial view (Index.cshtml) that has a list of tasks. These tasks are contained within indivudal divs that I have in a list style layout. I have a button called "add task" that opens a dialog. This dialog will save the added task to the database via an AJAX Json call to the controller.
This is where I am having trouble - after the dialog closes I would like the list of tasks to reload with the task i just added. I have found examples where the entire page is reloaded, and I found examples where the controller is supposed to return a rendered view. My problem is that the dialog is being opened from the partial I want to reload. Is there a way to accomplish what I am trying to do.
Index.cshtml
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
#foreach(var task in item.Tasks) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
</div>
</div>
}
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">All form fields are required.</p>
<form>
<fieldset>
<label for="TaskName">Task Name</label>
<input type="text" name="TaskName" id="name" class="text ui-widget-content ui-corner-all" />
<label for="TaskDescription">Task Description</label>
<input type="text" name="TaskDescription" id="description" value="" class="text ui-widget-content ui-corner-all" />
<input type="hidden" name="TaskID" id="ID" />
<input type="hidden" name="ProjectID" id="ProjectID" />
</fieldset>
</form>
</div>
Partial Javascript
function GetTask(id) {
if (id.length > 0) {
$.ajax({
url: '/Project/GetTaskFromID',
type: "POST",
data: { "id": id },
success: PopulateDialogFields,
error: HandleError
});
}
}
function PopulateDialogFields(data) {
$("#name").val(data.TaskName);
$("#description").val(data.TaskDescription);
$("#ID").val(data.TaskID);
}
function HandleError(data) {
alert(data.error);
var foo = data;
}
function SaveTask() {
var taskName = $("#name").val();
var taskDescription = $("#description").val();
var id = $("#ID").val();
var projectID = $("#ProjectID").val();
if (id.length > 0) {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
});
}
else {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "projectID": projectID }
});
}
}
$("#dialog-form").dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function () {
SaveTask();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
},
close: function () {
allFields.val("").removeClass("ui-state-error");
window.location.reload(true);
},
open: function () {
var id = $(this).data("id");
var projectID = $(this).data("projectID");
$("#ProjectID").val(projectID);
var button = $("#" + id);
GetTask(id);
}
});
$(".editTaskButton")
.button()
.click(function () {
$("#dialog-form").data('id', this.id).dialog("open");
});
$(".createTaskButton")
.button()
.click(function () {
$("#dialog-form").data('projectID', this.id).dialog("open");
});
I am relatively new to jQuery and ASP.NET MVC as well, however, here's what first comes to mind.
In order to maintain the AJAX-y aspect of the page, I suggest that you create a method that handles a POST which returns a JSON formatted set of TaskManagementApplication.Models.Project. This method can optionally return filtered results.
The markup would look like this,
<div id="ProjectAccordionWrapper">
<div id="ProjectWrapperTemplate" class="ProjectWrapper" style="display: none;">
<h3 id="itemName"></h3>
<div class="column">
<button class="createTaskButton" id="itemProjectID">Create New Task</button>
<div id="portletTemplate" class="portlet">
<div class="portlet-header" id="taskName"></div>
<div class="portlet-content" id="taskDescription"></div>
<button class="editTaskButton" id="taskID">Edit Task</button>
</div>
</div>
</div>
</div>
Next, you would have jQuery clone the ProjectWrapperTemplate element, and set all of the corresponding fields.
$(function () {
$.ajax({
url: '/Project/GetTasks',
type: "POST",
data: { }
}).done(function (data) {
data.forEach(function (element) {
AppendProjectWrapper(element);
});
});
function AppendProjectWrapper(data) {
var projectAccordionWrapper = $('#ProjectAccordionWrapper');
var projectWrapper = $('#ProjectWrapperTemplate').clone(true, true);
projectWrapper.id = nothing; // remove the id, so as to not have duplicates
projectWrapper.style.display = nothing; // remove the style "display: none"
var itemName = projectWrapper.children('#itemName'); // h3
itemName.id = nothing;
itemName.text(data.ItemName);
var itemProjectID = projectWrapper.children('#itemProjectID'); // button Create New Task
itemProjectID.id = data.ItemProjectID;
var portletTemplate = projectWrapper.children('#portletTemplate'); // div
data.Tasks.forEach(function (element) {
var portlet = portletTemplate.clone();
portlet.id = nothing;
var taskName = portlet.children('#taskName');
taskName.id = nothing;
taskName.text(element.TaskName);
var taskDescription = portlet.children('#taskDescription');
taskDescription.id = nothing;
taskDescription.text(element.TaskDescription);
var editTaskButton = portlet.children('#taskID');
editTaskButton.id = element.TaskID;
portlet.appendTo(projectWrapper);
});
portletTemplate.remove(); // remove the portlet template element
projectWrapper.appendTo(projectAccordionWrapper);
}
}
Finally, have '/Project/SaveTask' return a JSON formatted TaskManagementApplication.Models.Project of the currently saved task.
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
}).done(function (data) {
AppendProjectWrapper(data);
});
The return data for '/Project/GetTasks' should look as follows:
[
{
ItemName: '#item.Name',
ItemProjectID: '#item.ProjectID',
Tasks: [
TaskName: '#task.TaskName',
TaskDescription: '#task.TaskDescription',
TaskID: '#task.TaskID'
]
}
]
The return data from '/Project/SaveTask' should follow the same format, except or the outer-most array.
Please note that a lot of this code is untested.
It may be easiest to refactor the list into another action+view. Then, you can call this in both the original Index.cshtml view, and via the .load() method in jQuery. So, assuming this:
Projects controller
[HttpGet]
[ChildActionOnly]
public ActionResult Tasks(int id)
{
// create the appropriate model object as an IEnumerable of your Task type
return View(model);
}
Tasks.cshtml
#foreach(var task in Model) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
You would adjust Index.cshtml like so:
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
<div id="tasks-#item.ProjectID">
#Html.Action("Tasks", "Project", new { id = item.ProjectID })
</div>
</div>
</div>
}
</div>
//... the rest of the view
And finally,
// this should happen inside the callback of your .ajax() method
$('#tasks-'+projectID).load('/project/tasks/'+ projectID);

Ajax function called twice when clicking a button

I've seen a couple of similar questions here but I couldn't fix this problem. It seems not be a bid deal because eventually it works, but trying to display a hidden div (imitating a popup) using Ajax when clicking a button if I debug I can see the controller in the method (ConfirmMaxBid) is called twice (even more I feel sometimes even more times, and mixing the flow through the code, i.e going back and forth).
Here's the view
#model UI.Models.BidOnAuctionViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Content/js/BidAndMaxBidConfirmation.js")" type="text/javascript"></script>
#{
var disableButton = Model.AuctionOpen ? "" : "bid-btn-disabled";
}
#using (Html.BeginForm("ConfirmMaxBid", "Lot"))
{
<fieldset>
<div class="lotdetail-maxbid-row">
<label>Your Max Bid</label>
#*<input id="Amount" class="radius2 text-box single-line valid" type="text" name="Amount" data-val-required="The Amount field is required." data-val-number="The field Amount must be a number." data-val="true">*#
#if (Model.AuctionOpen)
{
#Html.TextBoxFor(model => model.Amount, new {#class = "radius2 text-box single-line valid"})
}
else
{
#Html.TextBoxFor(model => model.Amount, new {#class = "radius2 text-box single-line valid", #disabled = "disabled"})
}
</div>
<input type="submit" id="autobidButton" value="Increase Max bid" class="btn btn-level2 btn-maxbid #disableButton" />
</fieldset>
<div id="autoBidConfirmation" class="lotdetail-modal" style="display: none;">
#Html.HiddenFor(model => model.AuctionId)
#Html.HiddenFor(model => model.AutobidAmount)
#Html.HiddenFor(model => model.AuctionEventId)
<h4 id="confirmationMessage"></h4>
<span id="returnedCorrectedAmount" class="lotdetail-modal-msg"></span>
<input name="button" value="Place bid" type="submit" class="btn btn-level2" />
<input id="cancelAutoBid" name="button" value="Cancel" type="submit" class="btn btn-level2 btn-cancel" />
</div>
}
And here's the script's function called when document.ready
$('#autobidButton').click(function (e) {
e.preventDefault();
var model =
{
AuctionEventId: $('#AuctionEventId').val(),
AuctionId: $('#AuctionId').val(),
Amount: $('#Amount').val()
};
$.ajax({
url: "/Lot/ConfirmMaxBid",
dataType: 'json',
type: "POST",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(model),
success: function (data) {
var amount = "$" + data.AutobidAmount;
$('#returnedCorrectedAmount').html(amount);
$('#AutobidAmount').val(data.AutobidAmount);
$('#confirmationMessage').text(data.AutobidConfirmationMessage);
$('#autoBidConfirmation').show();
}
});
});
And finally this is the method (the part is called twice at least, to avoid this question be too long)
public ActionResult ConfirmMaxBid(string button, BidOnAuctionViewModel model)
{
if(Request.IsAjaxRequest())
{
var confirmationMessage = "Confirm your bid";
var correctedAmount = model.Amount;
if (!CheckMaxBidFitsIncrementTier(model.Amount, model.AuctionEventId))
{
confirmationMessage = "This bid can't be placed, do you want to place the following instead?";
correctedAmount = CalculateNextBidAmountForWrongMaxAmount(model.Amount, model.AuctionEventId);
}
return Json(new
{
AutobidAmount = correctedAmount,
model.AuctionId,
model.AuctionEventId,
AutobidConfirmationMessage = confirmationMessage
});
}
if (button == "Place bid")
{
//Here's the code to do the stuff when confirming in the partial view
Any idea why this happens?
Thanks in advance
Update
After placing some alerts (quite primitive way of debugging, I guess) I see that the method is called again just after the last line of the success function (after $('#autoBidConfirmation').show();)
Your document is probably ready multiple times after asyncronous post-backs.
Try something like:
$(document).ready(OnDocumentReady);
function OnDocumentReady()
{
$("#autobidButton")
.unbind("click", AutoBidFunction)
.click(AutoBidFunction);
}
function AutoBidFunction(e)
{
// Code Here
}

Categories

Resources