jquery, binding order/wait for callback - javascript

I wrote a jquery plugin for validating forms. It bounds itself to the $('element').Submit event to trigger the validation (the bind is inside the plugin). Somehow like this:
// pseudocode
jquery.rdy {
$('form').validate(); //binding the plugin
}
Inside of the validate plug I bind the validation to the submit
//pseudocode
[...]
$().submit(function () {
validating... //returning true/false
if (false) {
return false //prevent submit form
}
}
[...]
So and now my question is how can I bind (in other js scripts for example) other stuff to the submit but just if a validation is done.
so like this
$('form').submit(function () {
if (validate plugin was executed) {
//do stuff like check if validation was returning a true and now do something else
}
}
Hopefully I descriped it right ...my english is not the best but I tryed to be as concrete s possible (and i hope, pseudocode is a right approach as well)
// EDIT: make the problem more concrete:
I'm trying to figure out a way to solve the following problem: (its very out of the context but the problem is exactly there..)
I have a submit event which is doing something depending on some code triggered in a another decleration.
$('element').submit(function () {
if ($(this).hasClass('foo')) {
// do something
}
});
$('element').submit(function () {
$(this).addClass('foo');
});
And now the first function is doing nothing cause it has been triggered before the second one. Is there a clean way to solve this. Maybe I need a timeout event (even I hate them)?

If you are using jQuery.Validate (which it looks like you are with the .validate() syntax), you can just call the isValid() method:
if (validate plugin was executed) {
can then be
if ($('form').isValid()) {

You can bind more functions to the form element with custom names.
$('form').bind('after_validation',function(){ console.log('hello'); });
And trigger them in your submit form function when you need it:
$('form').trigger('after_validation');
http://api.jquery.com/trigger/
Update:
You cannot change the order of your bound submit events without removing them .unbind('submit') and re-applying in the correct order. What you can do is use custom binds (see above) and trigger them exactly when you need it - like.. inside the submit function.
$('form').submit(function () {
//run validation
$('form').trigger('validation');
//did it pass validation?
if($(this).data('invalid')){
console.log('did not pass validation');
return false;
}
//passed validation - submit the form
return true;
});
//add validation to the "form"
$('form').bind('validation',function () {
//do validation on form...
if(false){
$(this).data('invalid',true);
}
});
//add another validator to the form, etc.
$('form').bind('validation',func...
Im using .data() to store variables to the 'form' element so you can access them down the chain.
This is the basis of what you need and can be applied to a custom jquery plugin to form custom named functions. eg. $().validator().
http://docs.jquery.com/Plugins/Authoring

Related

How to get this form to submit only when it should

Probably an idiotic question but I find this really tricky:
I am trying to make a form submit only when it specifically should.
The script below executes every time I submit any other form in my page.
How can I make it not execute, unless it is called for?
$('#nurturing_pop_up_form').validate({
rules: {
emailaddress: {
required: true,
email: true
},
board_meeting: {
required: {
depends: function () {
return $('input[name=in_12_months]').is(':checked')==false && $('input[name=in_6_months]').is(':checked')==false
}
}
}
},
submitHandler: function(form) {
var url_remind = 'http://example.com';
var data_remind = $('#nurturing_pop_up_form').serializeArray();
$.ajax({
type: "POST",
url: url_remind,
data: data_remind,
success: function(){
$('.nurturing_pop_up').fadeOut();
}
});
}
});
Should I add something like this?
$('#nurturing_pop_up_form').submit(function(e){
e.preventDefault();
$('#nurturing_pop_up_form').validate({
rules: {
//the rest like above
Help is very very appreciated!
I am trying to make a form submit only when it specifically should.
This process is handled automatically by jQuery Validate. You should not be doing anything special to force this.
The script below executes every time I submit any other form in my page.
The script "below", .validate({...}), is simply the plugin's initialization routine. Within the code you've shown, you are only initializing ONE form with id="nurturing_pop_up_form". Other forms on the page would be completely unaffected. Perhaps you have invalid HTML, additional instances of .validate(), other submit handlers, or some erroneous code you have not shown us.
How can I make it not execute, unless it is called for?
I think your question is based on an erroneous assumption of what's happening. .validate() is only supposed to be called ONCE on page load (DOM ready handler) to initialize the plugin on your form. The plugin then automatically captures the click, validates the data, and handles the submit.
Should I add something like this?
$('#nurturing_pop_up_form').submit(function(e){
e.preventDefault();
$('#nurturing_pop_up_form').validate({...
Absolutely not. You should never put .validate() within a .submit() handler for the same form. It's completely unnecessary, delays the plugin's initialization, and interferes with the built-in submit handler.
Nothing you've shown can explain how/why other forms would be affected.

TinyMCE with jQuery validation plugin

I am trying to use the jQuery validation plugin with tinyMce but I am having a small problem.
By default the validation plugin has the following behavior: initially every field is marked as valid and the validation is lazy i.e. the error isn't shown until the user enters a value and moves away from the field. Once a field is marked as invalid, it is eagerly validated which means the validation is done on every key stroke.
I am having difficulty simulating this behavior for the TinyMCE field. If I use the onChange method the validation is always done on focus out. If I use the onKeyDown method, validation is done on every key stroke, even if the user is changing the field for the first time.
Is there some way I can use a combination of onChange and onKeyDown in order to mimic the default behavior of jQuery validation plugin? Here is the code that I currently have:
function(ed) {
ed.onChange.add(function(ed, e) {
tinyMCE.triggerSave();
jQuery('#'+ed.id).valid();
});
}
In case I am not making sense you can read how the validation plugin behaves here.
Thanks in advance!
I think you're going to have to have a valid state variable
Something like this
function(ed) {
var validState = true;
ed.onKeyDown.add(function(ed, e) {
if (validState) {
return
}
else {
// check if new content is valid
validState = jQuery('#'+ed.id).valid();
}
}
ed.onChange.add(function(ed, e) {
validState = jQuery('#'+ed.id).valid();
if (validState){
tinyMCE.triggerSave();
}
});
}
Note this is just some sample code. I haven't verified that this will work

How do I detect an attempted submission of invalid HTML forms?

When using HTML form validation, having an invalid input value in a form will halt submission of that form. How can I detect that the user attempted a failed form submission? The form's onsubmit handler does not fire when submission is halted by validation failure.
I'm currently listening for keypress and click events on the submit button to detect submit attempts. Is there a better way of detecting a failed form submission?
A simple way to get around this is to add an event listener to each input in the form to see when it has been prevented from submitting. The 'invalid' event should do everything you need.
Example
Array.prototype.slice.call(document.querySelectorAll("[required]")).forEach(function(input){
input.addEventListener('invalid',function(e){
//Your input is invalid!
})
});
More info here
http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/
I suggest you to use noValidate property. You can turn off default validation, and run it manually within onsubmit method
var form = document.getElementById("myForm");
form.noValidate = true; // turn off default validation
form.onsubmit = function(e) {
e.preventDefault(); // preventing default behaviour
this.reportValidity(); // run native validation manually
// runs default behaviour (submitting) in case of validation success
if (this.checkValidity()) return form.submit();
alert('invalid'); // your code goes here
}
you can check it here: https://jsfiddle.net/titulus_desiderio/Laon29f3/
Building on #Titulus' code above, here's how I would do it in jQuery; you can adapt this to native events if need be.
$('form-selector').on('submit', function(event) {
// Don't do anything if constraint validation isn't supported by the browser.
if (
!('checkValidity' in this) ||
// In the unlikely case this is a property but not actually a function.
// Hypothetically, a botched polyfill could do this; it pays to be careful
// and build resilient code.
typeof this.checkValidity !== 'function'
) {
return;
}
if (this.checkValidity() === true) {
// Valid values code.
} else {
// Invalid values code.
// Leave this until the last possible moment in the handler in case there's
// an error in any of the handler code to reduce the chances of a broken
// form where the submit does nothing. If an exception is thrown before
// this, the browser shouldn't get this far, (hopefully) allowing the basic
// form to still work.
event.preventDefault();
}
});
// Tell the browser to not validate automatically, as that would prevent submit
// from being triggered. We prevent the submission above if form doesn't pass
// validation. This is here in case there's an error in the preceding code, so
// this (hopefully) doesn't get applied in that case and browser validation
// takes place as a fallback.
this.noValidate = true;

How can I check the value returned by a validation function to pass along the metrics to Google Analytics?

I use a system that captures visitors information via a form. I can't edit the code of the form validation scripts. I am trying to see if I can check upon clicking on the submit button, before the form submit sends the person to the response URL if the validation was passed.
The "submit" calls the function "formSubmit()", if validation is passed myFormIsValid() is returned. If not, then return false to the form.
Like this:
function formSubmit(elt) {
if (!myFormIsValid()) {
return false;
}
I want to know if validation was passed before allowing the form to move forward and do something like setting a variable value so I can tell Google Analytics that the form was successfully submitted. Is there a way to setup a "listener" to the results of the formSubmit function before it is called? I can put the code on the header or footer and I can use jQuery.
You can handle the submit before it reaches it's destination with an event handler.
jQuery.submit()
$(function () {
$("#MyForm").submit(function (e) {
if (!$(this).valid()) {
e.preventDefault(); // prevents the form from submitting.
return;
}
// you can do things here or just let it continue submitting.
});
});

Why does my custom javascript prevent the validators from firing

In .NET 2.0, I have several client side validators ala the .NET validator controls. These run fine when I click a button...until I add my own javascript function to this button. Instead of running in addtion to the validators, it seems to prevent them from running at all.
To be clear, the validator controls are basic required field validators, and here is the javascript I added:
<script language="javascript">
function yaya()
{
var chkAmount = document.frmSearchFor.txtCheckAmount.value;
var amtApplied = document.frmSearchFor.lblAmountApplied.value;
if (amtApplied < chkAmount)
{
return confirm('Continue?');
}
}
</script>
And it's tied to the button like this...
OnClientClick="return yaya();
those are probably not the ID's being rendered to your page. Try this:
function yaya()
{
var checkAmount = parseFloat(document.getElementById("<%=txtCheckAmount.ClientID %>").value);
var amoutApplied = parseFloat(document.getElementById("<%=lblAmountApplied.ClientID %>").text);
if (amoutApplied < checkAmount)
{
return confirm('Continue?');
}
}
And try attaching it like this:
OnClientClick="javascript:yaya();";
Client-side validation is done via javascript just like your client click. When you specify the client-side event, I'm guessing there's nowhere for the validation code to attach. You may need to modify either the validation code to call your function, or your function to call the validation code. Probably the latter is easier. Instead of assigning OnClientClick at design time, add a client script that stores the current click handler function, creates a function that runs your code and then runs the stored handler function, and attaches that new function as the click handler.
<script>
var baseHandler = myElement.onclick;
myElement.onClick = function() {
// run your code here
baseHandler();
}
</script>
issue is that you are specifying a return in your OnClientClick attribute. when the page renders, it comes out like this
<input ... onclick="return yaya();WebForm_DoPostBackWithOptions...
after yaya completes, the onclick function concludes and I believe it's shutting down any further action that would normally happen before the form is submitted. it's kind of ugly but you can get around this by only having a return when your function evaluates to false:
OnClientClick="if (!yaya()) { return false; }"
for this to work you should also include return true; at the end of your function in case the conditions for the if check are not met.
you may also be having issues with references to elements as Hunter mentions but you're not providing your markup to verify that.

Categories