Yii and Javascript form submission - javascript

I'm using Yii as a PHP framework for my site. Additionally, my site uses some js/jquery like, say, a jQuery UI Dialog widget (except for those dialogs, the rest of the code is pure normal html form components and jQuery code for the event handlers).
In the Yii side, I use CForms to build my forms from specifications file.
When I test if the form was submitted, I must do it for a certain button. This is not only forced, but I also take advantage of it.
if ($myCFormInstance->submitted('approve')) {
//process approval code
} else if ($myCFormInstance->submitted('reject')) {
//process rejection code
}
The actual problem I have is a bit conceptual one, since -fortunately- I know what's going on with my code and -again, fortunately- know the problem root:
Somewhere in My code I intercept the submit button's click event:
$(function(){
$(".critical-action").click(function(e){
var form = $(this).closest("form");
e.preventDefault();
e.stopImmediatePropagation();
confirmDialog("¿Continuar?", "#critical-action-dialog", function(){
form.submit();
});
});
});
Say the .critical-action classed elements are always a submit button in a form.
The intention of the code: cancel the form submission, and perform it only if the user -in the dialog- clicks the "Yes, Continue" (i.e. confirming the action) button.
This code works as expected, and have no problems at a javascript level BUT -and here goes my issue- when doing form.submit(), the button is not sent as part of the form. This is obvious: I'm sending the form without specifying any button. In the case of Approve and Reject, which have two buttons, the example explains itself: if the form.submit() call could send their buttons ¿which of them should send?.
Question: So, since form.submit() doesn't send any button, but I actually need buttons ¿how can I send the form "with the corresponding button" -i.e. a button I choose to specify, which should correspond to this in the click handler function context- automatically via javascript? The button NEEDS to be identified by Yii in order to process the form (specially with the Approve and Reject case).

If you added a hidden input to the form, you can modify the input value with jQuery before you submit the form, like this:
$("#inputID").val('approve');
If you want to set the value to the value of the clicked button via $(this).val(), be aware of the issue that could result in an IE browser, explain here. The second answer (by postpostmodern) has a solution to this issue.

Related

Disabling a submit button while still allowing a PHP script to run when the form is submitted

I have a simple acceptance form that has a single button that the user clicks.
On form submit, I have a php script that makes a command line call to a python script that adds records to my database.
All works great besides one thing:
I don't want the user to be able to click the button more than once.
If I disable the button using javascript, my if (isset($_POST['submit'])) statement doesn't evaluate to true and then my php doesn't run
If I call a javascript function within the php script, the user still has an opportunity to click the button multiple times before the php script calls the function to disable the button. This allows them to make multiple records in my db.
My idea was to have my python script, which is the one adding records, first check if a record with the same information already exists in the db and only create a new one if not. My concern is that if the user clicks the submit button multiple times, it could be that multiple php will execute multiple calls and the second one will check if a record is already created before the first call creates a new record.
In other words, maybe the php calls will work at the same time (asyncronously?) and checking the database won't cover for another call creating a record at the same time. Is this a valid concern?
Are there other ideas of how I could disable or hide my button but still have my php script run?
Thank you.
For future viewers, the workaround I ended up using is based on what Teemu said in the comments below.
Before adding a new record from the form submission to the db, I checked if a record already existed with that information. If not, I added a record, if so the button click did nothing. As Teemu mentioned, this check would be necessary anyway to cover for multiple submissions that could be posted even without the button on the page.
This is what I call a "workaround" and not an answer because the user can still click the submit button multiple times but only the first click has an effect.
The button then hides itself after the php has finished running.
All you need is that the disabled is set after the submission is sent. You can achieve that using a setTimeout with zero delay:
$('.myForm').submit(function () {
setTimeout(() => {
$(this).find('[type=submit]').prop('disabled', true)
}, 0)
})
Then, the following will happen:
Form submission event is fired because user clicked the button or pressed Enter
Browser is calling your submit handler
You are "arming" your timeout
Browser is submitting the form to the server (with the submit button's value)
Your timeout fires immediately afterwards, disabling the button
Note that I used a submit handler on the form instead of a click handler on the button because the form may be submitted by pressing Enter while focus is on a form field too, not only by clicking the button. Yet due to how form submission works, disabling the button will also prevent submission by Enter.
I recently had a similar situation where I was getting a double-click 'bounce' sometimes. Here's two ways I dealt with it:
1) Simply disable the button, send the AJAX data to PHP and restore the button on success
$("#save_button").click(function (e) {
e.preventDefault();
$(this).attr("disabled", true);
var settings = $('form').serialize();
console.log("settings are ", settings);
$.post("data/ajax.php", settings, function (data) {
data = JSON.parse(data);
console.log("data back from save is ", data);
$("#save_button").removeAttr("disabled");
})
});
2) create a 'nobounce' function (it does basically the same thing, but on a timer. It is a bit simpler to use as it only requires setting the class 'nobounce' on any button you want to disable, though as it is on a timer, it isn't as accurate to enable the button when the post is done.
$('.nobounce').click(function () {
$(this).attr("disabled", true);
setTimeout(function () {
$('.nobounce').removeAttr("disabled");
}, 3000);
});
These are both jquery methods - keeping the form on the page. From your description it seems maybe you are doing a form submit through PHP (please, if this isn't the answer you need, put up some code you are using so this can be more clear!). If you are submitting through PHP, then some of the comments to the original question are extremely valid.
Hope this helps - again, if not, put up some code and you can get much more direct help.

Calling JavaScript function on hitting enter key in input box

Although I am able to call Javascript function on hitting the enter key. I am calling a function shortIt() when user hits the enter key, shortIt() takes the text from input box and makes a request to Google URL Shortener API which returns a short URL, but the generated response is visible for only some seconds.
I am showing the response in a div.
Seems to be very weird problem, code is here https://s3-ap-southeast-1.amazonaws.com/s3freebucket/URLShortner/url-shortner.html
But when I click on shortIt button to short the url. It works fine and the response text stays in the div.
This is because on pressing the enter key, the form gets submitted. When this happens you will notice the page reloading. This is a default behaviour and is the consequence of using <form>. On form submission, the page in the forms action attribute is loaded. In this case the action attribute of the <form> is not set and so the page you are on is just reloaded, thus the script stops running and the page reloads.
Two straight forward options for fixing this:
(Simplest) Remove the form tag - it is not used to submit anything so removing it should leave things still working
Prevent the default action when the form submit event is fired.
With JQuery:
$('#myForm').on('submit', function (evt) {
evt.preventDefault(); // prevents form submission
});
Where myForm is the ID of your form tag. You will need add an id attribute to your existing html form tag: <form id="myForm" class="form-horizontal">

message to be displayed for incomplete forms in php

I have a form where in user will enter all of its data to contact us . Now if user fills half of the form and lives in middle I want to ask him whether he really want to live this page .Is it possible? my form submission is done using ajax post method
You are looking for the beforeunload event (https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload). Here is a quick example:
window.onbeforeunload = function(){return "Are you sure?";};
It would probably be ideal to detect partial user input and only add the event listener when some input has been entered. You will also want to remove the dialog when input is completed, or the forum is submitted.
you can place validation function prior to ajax call and consider validation's return value to conclude either submit the form or display message using Confirm() function of javascript. onclick of "yes" on confirmation box you can fire ajax call, below is example of confirmation box in javascript.
if (confirm('Are you sure you want to leave this page?')) {
// leave the page
} else {
// do nothing
}

Preventing multiple form submits

I am submitting a form using JQuery and an event listener bound to a div (not an input field) and I am trying to prevent multiple submits, so the customer does not get overcharged. I am trying to accomplish this by removing the submit-button class of the clicked div, so the next time the user clicks it, JQuery won't listen to the event that is associated with the submit-button preventing multiple submits.
Using the implementation below however, for some reason, does not prevent multiple submits, as intended.
HTML
<div class="submit-button button-style">Submit</div>
JQuery
$(".submit-button").click(function(){
$(this).removeClass("submit-button");
//**submit form**
});
NOTE: I must stick to a solution that uses the html above, so solutions using an input element of type submit, will not be useful.
I appreciate any suggestions on how to make this work. Many thanks in advance!
You can make use of .one() to prevent it from firing multiple times -
$(".submit-button").one('click',function(){
//**submit form**
});
http://api.jquery.com/one/
Edit :
In case of error :
function submitForm(){
//**submit form**
$.post('submit.php').error(function(){
// rebind event on error
$(".submit-button").one('click',submitForm);
});
}
$(".submit-button").one('click',submitForm);
You could use something like:
$('something').one('click', function(){
// submit code
});
Which will only fire once.
A significant portion of users don't bother clicking the submit button to submit a form - there's other more convenient ways, like hitting the enter key when the cursor focus is on a form field.
A more robust approach is to block the form via the forms submit event, and maintain a variable to keep track of the form submission state.
var submitted = false;
$("form#myForm").submit(function(evt){
if (submitted) {
evt.preventDefault();//stops form submission
return;
}
submitted = true;
});
I omitted form validation for this example.

Disable action in form when using AJAX commands?

When one uses AJAX commands with Jquery, is it necessary to disable form action parameter in the HTML? The load URL and the action point to the same place, so is it necessary to have the action parameter?
You should use the event object's preventDefault() method, which will disable any default behavior associated with the element type. This is very important for links and form submit buttons.
For example:
<!-- you have this link -->
<a id="clickme" href="test.html">Click me</a>
You can disable the loading of test.html by using preventDefault()
$('#clickme').click(function(event) {
event.preventDefault();
// ...
});
You can also return false in your click function for the same effect.
In this case I think is useful only for clarity of code. When you put your code to make the AJAX call you can get the url from the form's action but that depends on you.
Try to be clear and consistent it's my advice.
If you are submitting the form via Ajax, then you just need to make sure there is not a way for the form to be submitted traditionally. You can either remove the form tags themselves, remove the actions, or remove any submit buttons. You can also capture the submit event of the form and just return false to prevent the form from doing a postback submit.

Categories