I have a beginform that automatically sends EVERYTHING to the controller via a ajax script. The problem is I have one button in the form that should only send its value once per click. I cant seem to distinguish it between the rest of the automatic data.
GOAL: Once the button is clicked once, i want value 10 (from button) to stop posting to the controller.
AJAX FUNCTION (SUBMITS ALL DATA TO CONTROLLER)
function toconroller() {
$.ajax({
type: 'POST',
url: this.action,
data: $('form').serialize(),
success: function (result) {
$('#box').html(result.info);
}
});
}
BUTTON FUNCTION
Function submitonce() {
//I want to only submit value of button once.
}
BEGINFORM WITH BUTTON
#using (Html.BeginForm())
{
<input id="data" onkeyup="tocontroller();">
<input type="submit" name="clicked" id="clicked" value="10" onclick="submitonce();" />
}
You could remove the value attribute of the submit button when clicked:
function submitonce() {
$('#clicked').removeAttr('value');
}
or do it unobtrusively without using the onclick attribute but subscribing to the .click() handler using jQuery:
$(function() {
$('#clicked').click(function() {
$(this).removeAttr('value');
});
});
or instead of removing the value attribute of the button you might want to set it to empty or something else:
$('#clicked').val('');
And since this is a submit button you might want to cancel its default action of submitting the form by returning false from its click handler (my second unobtrusive jQuery example).
Related
This is an odd issue, and I'm sure it's something simple, but I couldn't find another post with the same issue. I have a MVC View with an AJAX.BeginForm() that posts to my controller. Also, I have a search box (input) above the form that when the Enter key is pressed, it performs a JQuery ajax post to my controller (GetData) to auto-populate some of the form fields before submitting it. What's strange, is if the search field is used, it successfully fills the form fields with data, but the form's submit button stops working (form does NOT submit at all)! Now, if I do NOT use the search field (which performs the ajax POST) and manually fill in the form fields, then hit submit, it correctly submits to my controller.
The GetData (field pre-filler action) returns a JSONified model object which I read into the form objects.
The form is in a PartialView with the master ViewModel as it's model. The search box is in the _Layout page with no model on the razor view.
Code below is simplified to the relevant chunks (let me know if I omitted something important):
_Layout.cshtml:
<body>
<div id="bodyFrame">
#RenderBody()
</div>
<footer>
<span>Project Number:</span><input id="projectSearch" type="text" />
<div id="inputFrame">
#{ Html.RenderPartial("InputPartialView"); }
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/scripts")
#RenderSection("scripts", required: false)
</body>
InputPartialView.cshtml:
#using (Ajax.BeginForm("AddEntry", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "bodyFrame", InsertionMode = InsertionMode.Replace }))
{
/*Table with numerous HTML helper input fields for my model*/
<input type="submit" value="Submit" />
}
Main.js (method to pre-fill form data on Enter key press in search box):
$('#projectSearch').keyup(function (event) {
if (event.keyCode == 13) {
$.ajax({
url: '/Home/GetData',
dataType: 'json',
type: 'POST',
data: {
project: $(this).val()
},
success: function (data) {
$('#tb_Client').val(data.Client);
/*Other field values filled the same way*/
},
fail: function () {
alert('fail');
}
});
}
});
controller actions:
[HttpPost]
public JsonResult GetData(string search)
{
var result = new SubModel(); //This is a submodel of the main viewmodel
/*Pull in data via SQL into result*/
return Json(result);
}
[HtppPost]
public ActionResult AddEntry(ReportLogViewModel model)
{
/*Only works if search function is not called*/
return PartialView("Index", ViewModel.Generate());
}
So to summarize: The search function (GetData) always works, the form only works when the search function is not used (once it is used, the form does not submit to the controller), no errors occur in the browser console. Normal usage would be:
Type query in search input, press enter
GetData action is called, data is retrieved and returned via $.ajax() and then the form fields are populated with the returned data
User correct/amends any autocompleted data, fills in manual data, then hits Submit button
AddEntry action is called to enter the form data into the database, then return a newly generated partialview with the newly entered record.
Thanks in advance for any help!
UPDATE 1: It seems commenting out the lines of code in the main.js ajax success command allows the form to submit normally (albeit without the data the GetData method received). In this case removing "$('#tb_Client').val(data.Client);" allows the form to submit. This doesn't solve my problem but further pinpoints the problem to these lines of code in main.js.
UPDATE 2: The problem indeed was one of the javascript/jquery value setters on one of my inputs. Something was wrong with the JSON object. I commented them out one by one till I found the culprit then went back to my controller/viewmodel to the method that set the values and corrected the problem.
This is more appropriate for a comment but I need more reputation to reply to people on this site for some reason.
With your update, it makes me think that you're using the #tb_Client ID in more than one place but I can't confirm that without seeing the rest of the program.
Alternatively, instead of submitting the data encapsulated into a single object, you can send variables individually:
data : { variable : 'variable',
variable2 : 'variable2'},
In my .Net MVC4 project the view contains partialviews, the partialviews replaced on another after each corresponding Ajax.Beginform with option InsertionMode = InsertionMode.Replace,
So the senario is
Partialview1 renders on first Ajax.Beginform call
Submit form, partialview2 render on 2nd Ajax.beginform, so partialview1 is replaced by partialview2
3. A previous button recalls partialview1
Im wondering how to implement step3 that goes to previous partialview with something simple as history back.
First Way: I think the best way to do that with browser Back button is to use history.pushState
How to implement it depends on your situation on View.
Some links about pushState:
http://rosspenman.com/pushstate-jquery/
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
Second Way: If you don't want to use browsers Back buttom you can use js:
function getBack()
{
$.ajax({
type: "GET",
url: '#Url.Action("ReturnPartialViewControllerMethod")',
success: function(data) {
// data is your view
$('#divForParticialView').html(data);
}
});
}
and in your Html:
Get Back
I have a View with the following layout
The parent View is composed of several PartialViews as ilustrated in the picture. One of which is a list where each item has a corresponding Edit button which loads the item into another PartialView, but this is loaded via ajax into a modal dialog-bootstrap. This part works fine.
The problem I have is that no script or jquery event related to the controls of this modal gets executed. For example datepicker widget is never displayed, can not capture the change event of the dropdown, or capture the submit event for the form or the click event of Submit button.
All the scripts are placed in the main View. for example this is the event handler for the modal submit:
$(function () {
$('#myModal form').on('submit', function () {
console.log("okk");
clearErrors();
$.post($(this).attr('action'), $(this).serialize(), function (data, status) {
$('#myModal').modal('hide');
$("#details").html(data);
}).error(function (error, status, a, b) {
$('.modal-body p.body').html(error.responseText);
});
return false;
});
});
In my _Layout.cshtm I have included the necessary scripts (I think):
#Scripts.Render("~/js")
#Scripts.Render("~/bundles/globalization")
#RenderSection("scripts", required: false)
</div>
</body>
where "~/js" is:
bundles.Add(new ScriptBundle("~/js").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-migrate-{version}.js",
"~/Scripts/bootstrap.js",
"~/Scripts/bootstrap-datepicker.js",
"~/Scripts/jquery.validate.js",
"~/scripts/jquery.validate.unobtrusive.js",
"~/Scripts/jquery.validate.unobtrusive-custom-for-bootstrap.js",
"~/Scripts/locales/bootstrap-datepicker.es.js"
));
What could be the problem with my scripts and jQuery for this dialog ? Indications from similar questions in the site have not worked for me so far.
I have tried to express as clearly as possible if something is not understood the code or the illustrations I'm all ears. Thank you
As Partial View is loaded via ajax you need to initialize datepicker after the html is rendered on page so you need to put datepicker initialization script in success function callback:
$.post($(this).attr('action'), $(this).serialize(), function (data, status) {
$('#myModal').modal('hide');
$("#details").html(data);
$("#textBoxID").datepicker(); // initialize datepicker for partial view element here
})
For events you can write delegated events to make them work,choose the closest element of the partial view, i am using container of partial in which you are appending partial view html:
For click event:
$("#details").on("click","#someButtonId",function(){
// write event code here
})
For more detials of on() you can see HERE
If they are being loaded in by ajax you may need to give more context to your selectors.
$(document).on('submit', '#myModal form', function () { ...
I have a form that auto submits and updates the same page. I have a java script function that changes a buttons value, but AJAX keeps posting the old value.
AJAX
$.ajax({
type: 'POST',
url: this.action,
data: $('form').serialize()
});
JQUERY
function changevalue()
{
$('#button').attr('value', 'grapes');
}
FORM
form...
<input type="submit" name="button" id="button" value="apple" onclick="changevalue();" />
...
Button will display new changed word, but code behind (controller) shows old variable.
Change the value using jQuery's .val() method.
function changevalue() {
$('#button').val('grapes');
}
As of jQuery 1.6.0, the .attr() method correctly stopped accessing and changing property values, it only changes attributes.
You are not cancelling the submit button's default action clicking on that button, it is refreshing the page which means the default value will reappear.
Add event handlers with code, not inline markup.
<input type="submit" name="button" id="button" value="apple" />
<script>
$( function() {
$("#button").on("click", changevalue); //assign the click for 1.7+
//$("#button").click( changevalue); //assign the click for 1.6.x and below
});
function changevalue(evt) {
evt.preventDefault(); //cancel the click action
$(this).val("grapes"); //set the value with val, do not use attr
}
</script>
And from the docs on serialize
Note: Only "successful controls" are serialized to the string. No
submit button value is serialized since the form was not submitted
using a button. For a form element's value to be included in the
serialized string, the element must have a name attribute. Values from
checkboxes and radio buttons (inputs of type "radio" or "checkbox")
are included only if they are checked. Data from file select elements
is not serialized.
I'm suffering a very strange behavior with the checkbox helper (razor syntax). The sequence of steps are:
In the Index ActionResult I build the ViewModel that will be shown in the web:
var viewModel = new MyViewModel
{
Field1 = service.GetField(),
Field2 = otherService.GetField()
Field3 = otherService.Class.BooleanField
};
The Field3 is "rendered" with:
#Html.CheckBoxFor(model => model.Field3, new { #class = "something" })
When the page is loaded, I can see the checkbox with the checked state (when the boolean value it's true, surely).
When the page is loaded, the "OnReady" Jquery event is launched. In this method I call (via AJAX) an ActionResult wich calculates a price based on the parameters that he receives from the ViewModel.
Don't know why, but the Field3 parameter is 'false' although the value is true, and the checkbox has the checked state. After that, if I change any control that fires this calculation, the ViewModel that receives the method contains this Field3 but with the correct value (true).
I've been looking for possible interactions with this value, but I've found nothing and, as I said, the field is correctly checked when the AJAX call is made.
Thanks!
Ps: HTML retrieved with FireBug:
<input id="Field_Field" class="canRequestCalculation" type="checkbox" value="true" name="Field.Field" data-val-required="Mandatory field" data-val="true" checked="checked">
<input type="hidden" value="false" name="Field.Field">
As you can see, the state is checked but the value in the hidden is false.
Information retrieval by AJAX jQuery call:
$.ajax({
type: "POST",
url: "/Controller/PerformCalculation",
data: $("#form").serialize(),
success: function (data) {
//UI Work
},
beforeSend: function (data) {
//UI Work
}
});
As I said, the second time I execute the call the form is correctly sent with the value as true. If I use software like Fiddle or HttpFox to inspect the HTTP call, the "Field.Field" is false although in the browser the check is checked!
How are you determining the checkbox's state in jQuery? I use $("#checkboxId").attr("checked") currently to get it's value.