Weird double post call in sitefinity - c#

I have a very weird problem. Let's say I have two same forms/widgets on the same page , this is the code for the form:
<form>
<input class="form-group" type="text" title="FirstName" name="FirstName" id="FirstName" /><br />
<input class="form-group" type="text" title="LastName" name="LastName" id="LastName" /><br />
<input class="form-group" type="tel" title="PhoneNumber" name="PhoneNumber" id="PhoneNumber" /><br />
#Html.DropDownListFor(m => m.HearingID, Model.Hierings, new { #id = "HearingID", #class = "form-group" })<br />
#Html.DropDownListFor(m => m.ConnectTypeID, Model.ConnectTypes, new { #id = "ConnectTypeID", #class = "form-group" })<br />
<input type="button" value="Save" id="#buttonid" />
</form>
And the following js sends an ajax request.
<script type="text/javascript">
$(document).ready(function () {
$("form").submit(function (e) {
debugger;
e.preventDefault();
var form = $("form");
$.ajax({
type: "POST",
url: jQuery(location).attr('pathname') + '/Save/',
data: form.serialize(),
error: function (xhr, status, error) {
alert("Error");
},
success: function (e) {
}
});
});
return false;
});
</script>
By the laws of logic it should send the post request one time, but for some weird reason the number of calls correlates with the number of forms on the page. So if I have two forms - it sends the request two times. I tried everything, even giving the form a unique id, and yet still - two requests. The JS isn't working two times, the JS works one time but it still sends the request two times, and I can't figure out why.

I think you should give your form a unique ID which is generated on the server. In this way, when you drag your widget twice on the page, it will be rendered with different IDs, and moreover the jQuery selector will look for the form with the right ID. Following is a sample code of how I managed to get only one submit when I drag the widget two times on the page:
#{
// generate ID on the server
string formId = System.Guid.NewGuid().ToString();
}
<form id="#formId">
...
</form>
<script type="text/javascript">
$(document).ready(function () {
$('#' + '#formId').submit(function (e) {
// code here
});
});
</script>

Related

MVC Form values not reset

I have an issue where the hidden values in a form are not updating when the new ActionResult is returned.
For example, a user will check several records and click the Update Completion button. This makes an Ajax called to the UpdateCompleted action that sets a date for the checked records and once the Ajax call returns the form is submitted. After performing some logic in the form submit Action method, an updated model is returned with the IsChecked value set to false for all records in the model, but the form is retaining the previous checked value due to the generated id below having the same value.
Code
<td>
#Html.CheckBoxFor(model => Model.WorkOrderDetails[x].IsChecked)
#Html.HiddenFor(modelItem => Model.WorkOrderDetails[x].IsChecked)
#Html.HiddenFor(modelItem => Model.WorkOrderDetails[x].WorkOrderEntityId)
#Html.HiddenFor(model => model.WorkOrderDetails[x].WorkOrderId)
</td>
Rendered HTML
<td>
<input data-val="true" data-val-required="The IsChecked field is required." id="WorkOrderDetails_0__IsChecked" name="WorkOrderDetails[0].IsChecked" type="checkbox" value="true"><input name="WorkOrderDetails[0].IsChecked" type="hidden" value="false">
<input id="WorkOrderDetails_0__IsChecked" name="WorkOrderDetails[0].IsChecked" type="hidden" value="False">
<input id="WorkOrderDetails_0__WorkOrderEntityId" name="WorkOrderDetails[0].WorkOrderEntityId" type="hidden" value="ODU=">
<input id="WorkOrderDetails_0__WorkOrderId" name="WorkOrderDetails[0].WorkOrderId" type="hidden" value="NjQ4OTU3">
</td>
Submit Code
#using(#Html.BeginForm("Index", "WorkOrderMaster", FormMethod.Post, new { id = "workOrderMasterForm" }))
{
<div>
<div class="project-buttons">
<div class="btn-group">
<input id="submitCompletion" class="btn btn-success" value="Update Completion" data-submit-url='#Url.Action("UpdateCompleted", "WorkOrderMaster")' />
</div>
</div>
$(function () {
$('#submitCompletion').click(function () {
$.ajax({
type: 'POST',
url: $(this).data('submit-url'),
data: $('#workOrderMasterForm').serialize(),
success: function (data) {
$('#workOrderMasterForm').submit();
}
});
});
});
I would expect the new values from the model to be used but this is not occurring.
Is it recommended to code the input values manually in this situation in order to avoid the following format?
ClassName_Index_PropertyName
Thanks in advance for the time you took to look at this question.
Based on the provided code, you are performing an AJAX call to the server but expects the values to be cleaned up after the operation is finished.
It will not work since you are not refreshing the page. To clean up the form values without refreshing the page you need to do a small change in your code:
$(function () {
$('#submitCompletion').click(function () {
$.ajax({
type: 'POST',
url: $(this).data('submit-url'),
data: $('#workOrderMasterForm').serialize(),
success: function (data) {
$('#workOrderMasterForm').reset();
}
});
});
});
The change is in the success promise where "$('#workOrderMasterForm').sugmit();" changed to "$('#workOrderMasterForm').reset();".
In an effort to keep moving on this. I moved the form to a partial view, and added a div to load the partial view into. Anytime an event fires on the page thru many filters or the users submitting checked records the div is cleared and reloaded. This solved my issue.

Dropzone on razor Page returns 400 status code

I am using DropZone on a RAZOR page in ASP.NET core 2.0 with other form inputs like this -
DzDemo.cshtml Page -
<form method="post" enctype="multipart/form-data">
<input type="text" id="Username" name="Username" />
<div class="dropzone" id="my-dropzone" name="mainFileUploader">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</div>
</form>
<div>
<button type="submit" id="submit-all"> upload </button>
</div>
JS:-
Dropzone.options.myDropzone = {
url: "/DzDemo?handler=Upload",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
acceptedFiles: "image/*",
// paramName: myParamName,
init: function () {
var submitButton = document.querySelector("#submit-all");
var wrapperThis = this;
submitButton.addEventListener("click", function () {
wrapperThis.processQueue();
});
this.on('sendingmultiple', function (data, xhr, formData) {
formData.append("UserName", $("#Username").val());
});
this.on('error',
function (file, response) {
console.log(response);
alert(response);
});
}
};
DzDemo.cshtml.cs Page:-
[HttpPost]
public IActionResult OnPostUpload()
{
var data = Request.Form; //This is
return Page();
}
but I get 400 response from server and I am not able to process uploaded file server side Also it wont hot the Upload method on server side. Please help
One thing that will result in 400 using dropzone.js together with Razor Pages is if the AntiforgeryToken is missing from the form.
This is normally injected automatically but removing _viewimports or its taghelpers will prevent this.
To verify just add this line inside the <form/> element or look at the debug console for error messages.
#Html.AntiForgeryToken()
I got it working by setting the headers options
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }
Certainly, you need to have either at <form /> element or explicitly adding the #Html.AntiForgeryToken() in your page
Add this line in sendingmultiple, it will resolve your pb:
this.on('sendingmultiple', function (data, xhr, formData) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
});

ViewModel is null on second jQuery Ajax post

I have a page with a form per "Order". Each "Order" has multiple "items". Also, each form has an anchor tag "Mark as Shipped" that does a jQuery Ajax post. This post will mark "Order" as shipped and return the orderID to the view. On success of post I remove the form associated to the "Order" that was just marked shipped. This is all working great. Here is where the problems start. When I click "Mark as Shipped" for the second "Order" in the list, the ViewModel is passed to the controller as null. I do notice that the orderID is still being picked up by my js code on click of the anchor tag. Any suggestions would be greatly appreciated! I'm pulling my hair out here.
Here is my javascript:
<script type="text/javascript">
$(function () {
$(".MarkAsShipped").click(function () {
var valid = true;
var orderNumber = $(this).attr("data-id");
var formID = "#" + orderNumber;
if (valid) {
$.ajax({
url: "/NeedsShipped/MarkAsShipped",
type: "POST",
data: $(formID).serialize(),
success: function (data, textStatus, jqXHR) {
// remove the form for this order
$(formID).remove();
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
}
});
});
Each form has a list of items in it. Here is the part of my view that creates the forms.
if (#Model.Count() > 1)
{
for (int i = 0; i < Model.Count(); i++)
{
using (Html.BeginForm(null, null, FormMethod.Post, new { id = #Model[i].OrderID, name = #Model[i].OrderID }))
{
<br />
<div class="roundedDivVendor">
<div id="contactInfo" style="float:left; padding-left:5px; border-right:thin solid black; width:300px;">
<span style="font-weight:bold;">Order Number: </span>
#Model[i].OrderID<br />
<span style="font-weight:bold;">Ship To:</span><br />
#Model[i].FirstName.ToString()<span> </span>#Model[i].LastName.ToString()
<br />
#Model[i].Address1
#Html.HiddenFor(m => m[i].OrderID)
<br /><br />
</div>
<div id="itemsToShip" style="padding-left:20px;">
<span style="font-weight:bold; padding-left:5px;">Items to Ship: </span><span style="padding-left:450px;">
Mark as Shipped</span><br />
#for (int x = 0; x < #Model[i].OrderItems.Count(); x++)
{
#Html.HiddenFor(m => #Model[i].OrderItems[x].OrderProductsID)
#Html.CheckBoxFor(m => #Model[i].OrderItems[x].isShipped)
#Model[i].OrderItems[x].ShortDescription
<br />
}
</div>
<div style="clear:left;"></div>
</div>
<br />
}
}
In the controller I return OrderID as Json:
return Json(order.OrderID, JsonRequestBehavior.AllowGet);

issue calling a c# function from jquery

I am attempting to call a function through a view using jquery.. originally i was using razor's #html.BeignForm but for the web it needs to be converted to jquery
i don't know if i'm on the right path, however this is what i have in razor that's currently working.
#foreach(var up in Model)
{
#up._id
using (#Html.BeginForm("DQPost", "Disqus", new { ID = up._id }, FormMethod.Post))
{
<h7>The thread ID</h7>
<input type="text" name="ThreadID" /><br />
<h7>The message </h7>
<input type="text" name="Message" /><br />
<input type="submit" value="Post Comment"/>
}
}
what i'm trying to do is change the submit to button that then fires off the jquery. and this is the jquery i currently have written out.
<script type="text/javascript">
$(document).ready(function () {
$('#post').click(function () {
var dataToSend = { ID: ID, MethodName: 'DQPost', Message: message };
var options =
{
data: dataToSend,
dataType: 'JSON',
type: 'POST',
}
});
});
</script>
any help would be greatly appreciated.
You are wrong here,$('#post').
$('#post').click(function () {
Post is not an identifier., so, you could declare your own. You could try something like
<input type="submit" id="submitButton" value="Post Comment"/>
Then,
$('#submitButton').click(function () {
will work fine.
Looks like you want to intercept the form submission so you can handle submit yourself with AJAX. If I'm reading that right, instead of attaching to the button's event, attach to the form's event:
$("#my-form-id").submit(function() {
// do my AJAX stuff
return false; // this will prevent the form from being submitted like normal
});

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