Loading multiple Javascript files onsubmit - javascript

I have defined 3 javascript files with several functions, and I have event handler onsubmit in each of them (essentially same structure) the problem is, when I insert those 3 files at the bottom of the body section as filepath, only 2 of them are loaded while the third is not, and I cannot understand why...
This is the code:
function init() {
'use strict';
// Listen to see whether the form has been submitted:
//get a handle to my form
var demogrForm = document.getElementById("Demographics");
demogrForm.onsubmit = validateInputs;
console.log("submit");
} // End of init() function.
window.onload = init;
console.log("init");
essentially, the function called for each "onsubmit" is different in the 3 files, but the code to handle the call is the same...do you have any idea ?

Try using jQuery $(function(){}); or change your window.onload. It should look like this:
window.onload=function(){
console.log("init");
// Listen to see whether the form has been submitted:
//get a handle to my form
var demogrForm = document.getElementById("Demographics");
demogrForm.onsubmit = validateInputs;
console.log("submit");
};
or using jQuery:
$(function(){
console.log("init");
// Listen to see whether the form has been submitted:
//get a handle to my form
var demogrForm = document.getElementById("Demographics");
demogrForm.onsubmit = validateInputs;
console.log("submit");
});

Related

Marketo Form Embed to Vue JS Application

I'm trying to add a Marketo form to my Vue Js application but it doesnt seem to be working.
I loaded the initial forms2.min.js script in the created lifecycle hook and that loads just fine. Example code below.
created() {
const scriptTag = document.createElement('script');
scriptTag.src = "//app-ab00.marketo.com/js/forms2/js/forms2.min.js";
scriptTag.setAttribute('charset', 'utf-8');
document.head.appendChild(scriptTag);
}
Within the html template i added the container element to load the form.
<form id="mktoForm_1057"></form>
Then i created a method that gets triggered by a button to load the form into the container.
createForm(){
MktoForms2.loadForm("//app-ab00.marketo.com", "785-UHP-775", 1057)
}
As soon as i run the script i get this error "MktoForms2 is not defined." Am i doing something wrong?
Would someone be able to help me out?
Thanks!
It should be
created() {
const scriptTag = document.createElement('script');
scriptTag.src = "//app-ab00.marketo.com/js/forms2/js/forms2.min.js";
scriptTag.setAttribute('charset', 'utf-8');
scriptTag.onload = function() {
MktoForms2.loadForm("//app-ab00.marketo.com", "785-UHP-775", 1057);
};
document.head.appendChild(scriptTag);
}
It's hitting a snag because MktoForms2 is not defined as a variable. I had to append 'window' to MktoForms2 in order for it to pass linting
window.MktoForms2.loadForm('//app-ab00.marketo.com', '785-UHP-775', 1057)
Here is a little snippet I have used for Marketo templates. Make sure you have their forms2.min.js file loaded before using this script. You could also wrap this in a DOM ready/jQuery ready as well.
// check if we have their forms2.min.js script available
if (window.MktoForms2) {
// error handling
try {
MktoForms2.loadForm(baseUrl, munchkin_id, formId, function(form) {
// code to execute after load form
});
MktoForms2.whenRendered(function(a) {
// code to execute after the form has rendered its markup
var fid = a.getId(); // form id
});
} catch (a) {
console.log(a);
}
}

Tracking form submission

I'm developing tracking script which tracks some events (page view, link click, custom, ...) and sends them to API. Problem is I'm little bit stuck with form submission. So far I have following...
At first I add event listeners to every form on page:
const forms = document.getElementsByTagName("form");
for (let i = 0; i < forms.length; i++) {
forms[i].addEventListener("submit", trackFormSubmit);
}
}
And then trackFormSubmit function:
const trackFormSubmit = function(evt) {
if (evt.preventDefault) {
evt.preventDefault();
}
const form = evt.target || evt.srcElement;
const formElements = form.elements;
// parse form data payload here, not important to show
const event = {
...
};
Helper.sendEvent(event)
.then(() => {
form.submit();
})
.catch(error => {
console.log(error);
form.submit();
});
};
Helper.sendEvent function sends the event to the API. This solution works well for non-SPA websites, however it's not working great for SPA. I've tested it in React where I had a form using Redux Form library - the form submission was successfully tracked but I've received console error:
Form submission canceled because the form is not connected
The evt.preventDefault() doesn't work as expected in this case. Have someone an idea how this can be implemented?
Well I have to clarify the above statement: evt.preventDefault is called by Redux Form library so you have to handle onSubmit by your function (send data somewhere + redirect). I guess it's same in other Single-Page-Apps, there's no action where the user is sent ... default form behaviour is prevented initially.
First, make sure your ES6 arrow function trackFormSubmit is defined before your for loop that sets the event listener to every form. This could cause the code to work but without listening to the form submit.
Here is an example of setting up the event listener for every form in the document and handling their submit.
const trackFormSubmit = function(event) {
event.preventDefault();
const form = event.target || event.srcElement;
const formElements = form.elements;
alert(`Form ${event.target.name} was submited.`);
};
const forms = document.querySelectorAll("form");
forms.forEach(f=>{
f.addEventListener("submit",trackFormSubmit);
});
Here is a fiddle so you can view how this code works:
https://jsfiddle.net/k3llydev/fgL5owdj/
Also, I changed the way of setting the event listeners to a forEach way. Which is a lot more readable.
Hope this gives you at least an idea of how it would work.
Checking value of event.isDefaultPrevented solved the issue :-)

JQuery validation resetForm is not working

I have a very simple issue: There is a form with a clear form button. When I click on it, all fields reset. But I also have an extra validation rule: at least one additional field should be filled. After clearing, they all are empty, of course, but I don't want to see these validation messages. I want it to clear the entire form, hide all validation messages and so on. Here is my code:
$("a[data-clear]").click(function (event) {
var now = new Date();
$("#report_search section:gt(0) input").val("");
$("#includeDerived").prop("checked", true);
$("#includeApp").prop("checked", true);
$("#includeOrg").prop("checked", false);
$("input[name='FromDate']").datepicker().datepicker("setDate", now.dateAdd("year", -1));
$("input[name='ToDate']").datepicker().datepicker("setDate", now);
$("form").validate().resetForm();
event.preventDefault();
});
I have only one form on the page so multiple forms is not an issue.
Desired result: form is cleared, validation messages are not shown.
Actual result: form is cleared, validation messages persist.
Sample rule which is checking if fields are filled:
jQuery.validator.addMethod("isSufficientInfo",
function (value, element, params) {
var hasPersonInfo = $("input[name='LastName']").val() && $("input[name='FirstName']").val();
if (hasPersonInfo) {
return true;
}
var hasDocInfo = $("select[name='D']").val() && $("input[name='C']").val() && $("input[name='E']").val();
if (hasDocInfo) {
return true;
}
return $("input[name='A']").val() || $("input[name='B']").val();
}, "File some fields");
$("#IsEnoughInfo").rules("add", { isSufficientInfo: "" });
If you're still looking for the answer,
I suspect that $("form").validate() creates a new validator instance.
What you need is the previously created instance:
$("form").data("validator").resetForm()
Or store the validator in a variable:
var v = $("form").validate()
v.resetForm()
Reason for error
Your event for click event is getting propagated from button to window (inside-out). This is causing your form to trigger validation and thus you are getting the same error message, even after you call the resetForm. If you debug the validation library step by step and get to this.hideErrors then you will see that when this.hideErrors gets executed, the error messages are gone. Since the validation script hasn't finished yet, it continues with other statements, and at the end the event that got propagated is handled by the window from inside-out. The error messages are again shown as this event triggers the request on the form.
Solution
The solution is to move your call to event.preventDefault() to the top, like as shown below:
$("a[data-clear]").click(function (event) {
event.preventDefault(); // Move to top
var now = new Date();
$("#report_search section:gt(0) input").val("");
$("#includeDerived").prop("checked", true);
$("#includeApp").prop("checked", true);
$("#includeOrg").prop("checked", false);
$("input[name='FromDate']").datepicker().datepicker("setDate", now.dateAdd("year", -1));
$("input[name='ToDate']").datepicker().datepicker("setDate", now);
$("form").validate().resetForm(); // this should work now
});
Also see the updated jsfiddle sample
Give it a try and let me know if this works for you or not. I did the step-by-step debug and got to this conclusion.

Form not loaded while calling jquery validator

I have a registration form in jsp and i am validating the form in js file using jquery as shown in below code. When i call form() method of jquery validate, it says this.formValidation 'undefined' because my form is not loaded. i have tried setTimeout and delay methods but my problem did not solve. Please help me, my code:
UserRegistration.prototype.formValidation = function(){
var me = this;
this.formValidation = $('#user_form').validate({
rules : $.extend({}, rules)
});
if (this.formValidation !== 'undefined') {
this.formValidation.form();
}
else {
setTimeout(this.formValidation.form(), 50);
}
};
In else condition the error occurs.
In Jsp page i am loading my js file using headjs like:
head.load("scripts/userregistration.js");
Below that i have my form:
<form id="user_form">
</form>
How can i load my form by the time i call this.formValidation.form();

Detecting/handling changed data in ASP.NET MVC / jQuery / JS

We need to universally handle changed data on forms in ASP.NET MVC. Our application has ~100 forms, and the user should be prompted if they start editing a form and click on anything other than Save (i.e. something like "Your data has been changed. Click OK to return to the form, or Cancel to lose all changes.").
It looks like SO implements this (while asking a question) using JavaScript. In general, is this the best way? Also, any tips on how best to implement this?
The way I've done this is to use javascript to store the initial values of inputs when the page loads. Then I have a beforeunload handler that checks to see if any of the inputs have a different value than when the page was loaded. If any inputs are changed, it prompts the user to confirm that they want to leave the page, canceling the action if they cancel. In my submit logic, I set a flag that keeps the beforeunload check from happening so a submit doesn't get the prompt.
I suspect there is a jQuery plugin to do this, but I haven't implemented this since I started using jQuery. My earlier code used Prototype.
Edit: Couldn't find a jQuery plugin, but I could have just missed it. Here's a sample of how I might do it. Obviously, there's more that could be done. Note I wasn't able to get it to work with pure jQuery -- not sure exactly why, the popup would appear twice.
This should work with all input elements. You might want to change it to ignore/handle buttons, though. I only adjusted it to ignore a submit button (so it can post back without the popup). If other button types can cause a page unload, you may need to address that.
var CheckOnClose = function() {
this.initialize();
}
CheckOnClose.prototype = {
submitting: false,
initialize: function() {
var that = this;
window.onbeforeunload = function() { return that.checkLeavePage(); }
},
isChanged: function() {
var changed = false;
$('input:not(:submit)').each( function() {
var iv = $(this).data('initialValue');
if ($(this).val() != iv) {
changed = true;
return false;
}
});
return changed;
},
setSubmitting: function() {
this.submitting = true;
},
checkLeavePage: function() {
if (!this.submitting && this.isChanged()) {
return 'You have some unsaved changes.';
}
}
}
var checker = new CheckOnClose();
$(document).ready(function() {
$(':input:not(:submit)').each( function() {
$(this).data('initialValue',$(this).val() );
});
$(':submit').click( function() {
checker.setSubmitting();
});
});
JavaScript is your only shot for doing this. It doesn't even have to be a complicated bunch of code. All you have to do is have a global variable to flag if the form is in editing stages (var formEdited = false; would do), and then add this snippet to your page:
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (formEdited)
{
return "You have attempted to leave this page. If you have made any changes to the fields without Submitting the form, your changes will be lost. Are you sure you want to exit this page?";
}
// no changes - return nothing
}

Categories

Resources