Script to push UTM values from URL to hidden fields (Webflow) - javascript

I just released our new website in Webflow, but there is no easy way to collect UTM values from the URL and push them to the form fields. I created the 5 UTM hidden fields (UTM Medium, UTM Source, UTM Campaign, UTM Content, UTM Term). Now I need to add a HTML code to the page to push the values from the URL.
I was given this script:
<script>
const urlParams = new URLSearchParams(window.location.search);
const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
let utmFieldValue = '';
utmParams.forEach(function (param) {
const paramValue = urlParams.get(param);
if (paramValue) {
utmFieldValue += `${param}=${paramValue} `
}
});
const utmField = document.getElementById('utm-field');
utmField.value = utmFieldValue.trim();
</script>
However, it looks like all the values are pushed into one single field. Can anyone rewrite this script to reflect that each value should be added to the right field?
This is an example of a URL with UTMs: google.com/?utm_source=crowdcast&utm_medium=webinar&utm_campaign=blog&utm_content=how-we-use-linkedin-ads
The URL where the form lives is https://saasmql.com/contact-us
This is the code for the form:
<html>
...
<div id="w-node-07aa8d855a85-8d855a85" class="form-wrap">
<h2 class="h2 center white">Book an Intro Call</h2>
<div>
<div class="w-form">
<form id="wf-form-Contact-Us-Form" name="wf-form-Contact-Us-Form" data-name="Contact Us Form"
redirect="/thank-you" data-redirect="/thank-you">
<input type="text" class="text-field w-input" maxlength="256" name="First-2" data-name="First 2"
placeholder="First Name" id="First-2" required="" />
<input type="text" class="text-field w-input" maxlength="256" name="Last-2" data-name="Last 2"
placeholder="Last Name" id="Last-2" required="" />
<input type="email" class="text-field w-input" maxlength="256" name="email-2" data-name="Email 2"
placeholder="Email Address" id="email-2" required="" />
<input type="text" class="text-field w-input" maxlength="256" name="Company-2" data-name="Company 2"
placeholder="Company" id="Company-2" required="" />
<input type="text" class="text-field w-input" maxlength="256" name="Job-Title-3" data-name="Job Title 3"
placeholder="Job Title" id="Job-Title-3" required="" />
<textarea placeholder="Comments" maxlength="5000" id="Comments-2" name="Comments-2"
data-name="Comments 2" class="text-field w-input">
</textarea>
<input type="text" class="text-field-utm w-input" maxlength="256" name="utm_source"
data-name="utm_source" placeholder="UTM Source" id="utm_source" />
<input type="text" class="text-field-utm w-input" maxlength="256" name="utm_campaign"
data-name="utm_campaign" placeholder="UTM Campaign" id="utm_campaign-2" />
<input type="text" class="text-field-utm w-input" maxlength="256" name="Utm-Content"
data-name="Utm Content" placeholder="UTM Content" id="Utm-Content-2" />
<input type="text" class="text-field-utm w-input" maxlength="256" name="Utm-Term" data-name="Utm Term"
placeholder="UTM Term" id="Utm-Term-3" />
<input type="submit" value="SUBMIT" data-wait="Please wait..." class="blue-button full-size w-button" />
</form>
</div>
</div>
</div>
...
</html>

This should work
const urlParams = new URLSearchParams(window.location.search);
const utmParams = [
'utm_source',
'utm_medium',
'utm_campaign',
'utm_term',
'utm_content'
];
let paramValue, utmField;
utmParams.forEach(function (param) {
paramValue = urlParams.get(param);
utmField = document.querySelector("input[name='"+param+"']");
if (paramValue && utmField) {
utmField.value = paramValue.trim();
}
});
Make sure to have all your fields strictly follow this naming:
utm_source
utm_medium
utm_campaign
utm_term
utm_content

Related

React Comment Section Character Counter

Hey fellow developers,
so, I'm having this issue with React, and although I think I'm getting to show the 2000 as a number and a value overall, when I write inside the comment section, the number changes to NaN. I tried using the parseInt() in order to turn the span into a number, but nothing happens... Any suggestions?
Here's the code :)
import React from "react";
import Header from "../Header";
import "./contact-form.css";
function characterCounter() {
let text = document.getElementById("message").value;
let textLength = text.length;
let counter = document.getElementById("characterCounter");
let counterNumber = parseInt(counter);
counter.textContent = counterNumber - textLength;
}
class ContactPage extends React.Component {
render() {
return (
<div>
<Header />
<h1>Contact.</h1>
<form action="" className="contact-form" id="contactForm">
<label>Your Name</label>
<input type="text" placeholder="First Name..." />
<label>Your Last Name</label>
<input type="text" placeholder="Last Name..." />
<label>Your Email</label>
<input type="text" placeholder="Email..." />
<label>Your comment</label>
<textarea
name=""
id="message"
cols="10"
rows="10"
placeholder="Hey..."
onKeyDown={characterCounter}
></textarea>
<span>
Max words <span id="characterCounter">2000</span>
</span>
<button id="buttonSubmitContact" type="submit">
Submit
</button>
</form>
</div>
);
}
}
export default ContactPage;
So... you are using React, don't you? Well I will rewrite the component to solve the issue in the React's way
const MAX_CHARS = 2000
function ContactPage() {
const [charsLeft, setCharsLeft] = useState(0);
const updateCharsCount = ({target:{value}}) => {
setCharsLeft(MAX_CHARS - value)
}
return (
<div>
<Header/>
<h1>Contact</h1>
<form action="" className="contact-form" id="contactForm">
<label>Your Name</label>
<input type="text" placeholder="First Name..."/>
<label>Your Last Name</label>
<input type="text" placeholder="Last Name..."/>
<label>Your Email</label>
<input type="text" placeholder="Email..."/>
<label>Your comment</label>
<textarea
name=""
id="message"
cols="10"
rows="10"
placeholder="Hey..."
onChange={updateCharsCount}
></textarea>
<span>Max words {charsLeft}/{MAX_CHARS}</span>
<button id="buttonSubmitContact" type="submit">
Submit
</button>
</form>
</div>
);
}
export default ContactPage;
By the way, I've used functional component instead of class component, it's the current approach

How to disable submit button until all input classes have class="valid"

I want to create a sign-up form. I have 6 inputs: First Name, Last Name, E-mail, Password, Password confirmation and a checkbox for user agreement. If inputs have class="valid", value is valid, otherwise invalid. I put all the classes a default class="invalid". I want to disable my submit button until all input fields have class="valid". According to my research, I saw that the button should be disabled first using the window.onload eventlistener, but I still couldn't figure out how to do it.
This is the basic form:
<form class="signup__form" action="/">
<input class="invalid" type="text" name="fname" placeholder="name"/> </br>
<input class="invalid" type="text" name='lname' placeholder="Last Name" /></br>
<input class="invalid" type="email" name='email' placeholder="E-mail" /></br>
<input class="invalid" type="password" name="password" placeholder="Password" />
<input class="invalid" type="password" name="password" placeholder="Password Confirm" />
<input class="invalid" type="checkbox" /> User Agreement</br>
<button type="submit" >Sign Up</button>
</form>
I am controlling checkbox validation with an eventlistener:
checkbox.addEventListener('click', (e) => {
if (e.target.checked) {
checkbox.classList.remove('invalid');
checkbox.classList.add('valid');
} else {
checkbox.classList.remove('valid');
checkbox.classList.add('invalid');
}
})
And for the rest, i am checking with regexs:
// Regex values
const regexs = {
fname: /^[a-zA-Z0-9]{3,24}$/,
lname: /^[a-zA-Z0-9]{3,24}$/,
email: /^([a-z\d\.-]+)#([a-z\d-]+)\.([a-z]{2,8})$/,
password: /^[\w#-]{8,20}$/
};
// Regex Validation
const validation = (input, regex) => {
if (regex.test(input.value)) {
input.classList.remove('invalid');
input.classList.add('valid');
} else {
input.classList.remove('valid');
input.classList.add('invalid');
}
}
inputs.forEach((input) => {
input.addEventListener('keyup', (e) => {
validation(e.target,regexs[e.target.attributes.name.value])
})
})
Something like this might come in handy.
var form = document.querySelector('.signup__form'), is_valid = false, fields, button;
form.addEventListener('change', function(){
fields = form.querySelectorAll('input');
button = form.querySelector('button');
for (var i = fields.length - 1; i >= 0; i--) {
if( fields[i].classList.contains('invalid') )
{
is_valid = false;
break;
}
is_valid = true;
}
is_valid ? button.removeAttribute('disabled'): button.setAttribute('disabled', 'disabled');
});
<form class="signup__form" action="/">
<input class="invalid" type="text" name="fname" placeholder="name"/> <br>
<input class="invalid" type="text" name='lname' placeholder="Last Name" /><br>
<input class="invalid" type="email" name='email' placeholder="E-mail" /><br>
<input class="invalid" type="password" name="password" placeholder="Password" />
<input class="invalid" type="password" name="password" placeholder="Password Confirm" />
<input class="invalid" type="checkbox" /> User Agreement<br>
<button type="submit" disabled>Sign Up</button>
</form>
Since you don't have all of your code, I'm adding a second example myself so that I can fully test the validation part.
But you just need to copy the above JavaScript code and set the button to disabled="disabled"in the first place.
var form = document.querySelector('.signup__form'),
is_valid = false,
fields, button;
form.addEventListener('change', function() {
fields = form.querySelectorAll('input');
button = form.querySelector('button');
for (var i = fields.length - 1; i >= 0; i--) {
if (fields[i].value.length) {
fields[i].classList.remove('invalid');
} else {
fields[i].classList.add('invalid');
}
if (fields[i].classList.contains('invalid')) {
is_valid = false;
break;
}
is_valid = true;
}
is_valid ? button.removeAttribute('disabled') : button.setAttribute('disabled', 'disabled');
});
<form class="signup__form" action="/">
<input class="invalid" type="text" name="fname" placeholder="name" /> <br>
<input class="invalid" type="text" name='lname' placeholder="Last Name" /><br>
<input class="invalid" type="email" name='email' placeholder="E-mail" /><br>
<input class="invalid" type="password" name="password" placeholder="Password" />
<input class="invalid" type="password" name="password" placeholder="Password Confirm" />
<input class="invalid" type="checkbox" /> User Agreement<br>
<button type="submit" disabled>Sign Up</button>
</form>
Note: This example does not follow because it does not validate the Checkbox.
#Enes, 1. kod parçacığındaki JavaScript kodunu kopyalarsan çalışacaktır. 2. Kodu test edebilmen için ekledim. Bir değer girilmişse onu doğru "valid" kabul eder.
I would try to the native use of HTML properties (pattern & required) and CSS instead of giving in to javascript. Just give it a go, and see how it feels like. Do note that I excluded a pattern on your email input.
The only thing I would use javascript for is to check if the password fields are the same, but I would do that by injecting the password of the first password input into the confirming password input's pattern attribute, replacing ^[\w#-]{8,20}$.
The pink background is just there to show-case the validation rules.
By the way, you got the wrong formatting on some of the HTML tags. You don't need an ending slash on input and you should type <br/>, not </br>.
input:invalid {
background-color: pink;
}
form:invalid button[type="submit"] {
opacity: 0.5;
}
<form class="signup__form" action="/">
<input type="text" required pattern="^[a-zA-Z0-9]{3,24}$" placeholder="Name"> <br/>
<input type="text" required pattern="^[a-zA-Z0-9]{3,24}$" placeholder="Last Name"><br/>
<input type="email" required placeholder="E-mail"><br/>
<input type="password" required pattern="^[\w#-]{8,20}$" placeholder="Password"><br/>
<input type="password" required pattern="^[\w#-]{8,20}$" placeholder="Password Confirm"><br/>
<input type="checkbox" required>User Agreement<br/>
<button type="submit" >Sign Up</button>
</form>
you can use required="required", then the submit won't be called before the field has value.
A solution which tests the number of invalid classes:
var checkbox = document.querySelector("input[type=checkbox]");
var inputs = document.querySelectorAll("input:not([type='checkbox'])");
var but = document.querySelector("button[type=submit]");
but.disabled= true;
checkbox.addEventListener('click', (e) => {
if (e.target.checked) {
checkbox.classList.remove('invalid');
checkbox.classList.add('valid');
} else {
checkbox.classList.remove('valid');
checkbox.classList.add('invalid');
}
but.disabled = !document.querySelectorAll("input.invalid").length == 0;
})
// Regex values
const regexs = {
fname: /^[a-zA-Z0-9]{3,24}$/,
lname: /^[a-zA-Z0-9]{3,24}$/,
email: /^([a-z\d\.-]+)#([a-z\d-]+)\.([a-z]{2,8})$/,
password: /^[\w#-]{8,20}$/
};
// Regex Validation
const validation = (input, regex) => {
if (regex.test(input.value)) {
input.classList.remove('invalid');
input.classList.add('valid');
} else {
input.classList.remove('valid');
input.classList.add('invalid');
}
}
inputs.forEach((input) => {
input.addEventListener('keyup', (e) => {
validation(e.target,regexs[e.target.attributes.name.value]);
but.disabled = !document.querySelectorAll("input.invalid").length == 0;
})
})
<form class="signup__form" action="/">
<input class="invalid" type="text" name="fname" placeholder="name"/> </br>
<input class="invalid" type="text" name='lname' placeholder="Last Name" /></br>
<input class="invalid" type="email" name='email' placeholder="E-mail" /></br>
<input class="invalid" type="password" name="password" placeholder="Password" />
<input class="invalid" type="password" name="password" placeholder="Password Confirm" />
<input class="invalid" type="checkbox" /> User Agreement</br>
<button type="submit" >Sign Up</button>
</form>
We will use couple of properties to validate the form which are required, pattern, disabled and also we will use CSS properties to control the form validation
input:invalid {
background-color: red;
}
form:invalid input[type="submit"] {
opacity: 0.5;
cursor: not-allowed;
}
<form class="login__form" action="/">
<input type="email" required placeholder="E-mail"><br/><br/>
<input type="password" required pattern="^[\w#-]{8,20}$" placeholder="Password"><br/><br/>
<input type="submit" >
</form>

How to keep session storage for all form inputs after submission?

How to save all the values from customer? I can only save first name and last name. Can I pass more than 2 inputs in set details? I tried adding date of birth that had input type text in dd/mm/yyyy format but the value was being shown as "undefined".
Java Script
function getDetails(){
if (typeof(Storage)!=="undefined"){
if (sessionStorage.getItem("firstName") !== null){
document.getElementById("firstName").value = sessionStorage.getItem("firstName");
}
if (sessionStorage.getItem("lastName") !== null){
document.getElementById("lastName").value = sessionStorage.getItem("lastName");
}
}
}
function setDetails(firstName, lastName) {
if (typeof(Storage)!=="undefined"){
sessionStorage.setItem("firstName", firstName);
sessionStorage.setItem("lastName", lastName);
}
}
HTML Code
<label for="firstName">First Name</label>
<br>
<input type="text" name="firstName" id="firstName" placeholder= "Enter first name" title="20 characters" />
<br>
<label for="lastName">Last Name</label>
<br>
<input type="text" name="lastName" id="lastName" placeholder= "Enter last name" class="field" required pattern="([A-z]){1,20}" title="20 characters" />
<br>
<label for="dob">Date of Birth</label>
<br>
<input type="text" name="dob" id="dob" maxlength="10" placeholder="dd/mm/yyyy" pattern="\d{1,2}\/\d{1,2}\/\d{4}"/>
Below code will work to set & get "dob" in cookie:
<html>
<body>
<label for="dob">Date of Birth</label>
<br>
<input type="text" name="dob" id="dob" maxlength="10" placeholder="dd/mm/yyyy" pattern="\d{1,2}\/\d{1,2}\/\d{4}"/>
<button onclick = "setDateInCookie();">SetCookie</button>
<button onclick = "getDateFromCookie();">GetCookie</button>
<script>
function setDateInCookie(){
var myDate = document.getElementById("dob").value;
if(typeof(Storage)!=="undefined")
sessionStorage["myDate"] = myDate;
}
function getDateFromCookie(){
var myDate = document.getElementById("dob").value;
if(typeof(Storage)!=="undefined")
{
if (sessionStorage.getItem("myDate") !== null){
document.getElementById("dob").value = sessionStorage.getItem("myDate");
}
}
}
</script>
</body>
</html>
Future Note: Avoid using input type "text" for input type "date". Use the exact input types for not getting any issues in future.

Why wont my radio button response respond to my Google Spreadsheet?

I've used the following code as a method to send user input data on my html site to a Google Spreadsheet:
Javascript:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
function postContactToGoogle() {
var firstname=$('#firstname').val();
var surname=$('#surname').val();
var dob=$('#dob').val();
var email=$('#email').val();
var option=$('#option').val();
$.ajax({
url:"https://docs.google.com/forms/d/e/1FAIpQLSfe760bJi_65cvSGfu4HckMdmAs1ahBkO7oE6njBTYZh4A/formResponse",
data: {"entry.1012452068":firstname, "entry.1038894874":surname, "entry.1352091133":dob, "entry.1048111489":email, "entry.1786559101":option}, type: "POST", datatype: "xml", statusCode: {0:function() {window.location.replace("thankyou.html");}, 200:function(){window.location.replace("thankyou.html");}}
});
}
</script>
HTML:
<form>
First Name:<br>
<input id="firstname" name="firstname" type="text" placeholder="First Name"/><br>
Surname:<br>
<input id="surname" name="surname" type="text" placeholder="Surname"/><br>
DoB:<br>
<input id="dob" name="dob" type="text" placeholder="DoB"/><br>
Email:<br>
<input id="email" name="email" type="text" placeholder="Email"/><br>
Option Pledge:<br>
<input id="option" name="option" type="radio"/> £49 <br>
<input id="option" name="option" type="radio"/> £69 <br>
<input id="ButtonSubmit" name="" type="button" value="Send" onclick="postContactToGoogle()"/>
</form>
It all works perfectly well except for the last 2 radio button options don't appear on the spreadsheet (shown on the image below). Does anyone have an insight into what I'm doing wrong?
You have 2 issues:
Your radio inputs have the same id="option" and id's should be unique .
Your radio inputs haven't value attribute to send like value="your value".
So this example should work
function postContactToGoogle() {
var firstname = $('#firstname').val();
var surname = $('#surname').val();
var dob = $('#dob').val();
var email = $('#email').val();
var option = $("[name='option']").val();
console.log({
"entry.1012452068": firstname,
"entry.1038894874": surname,
"entry.1352091133": dob,
"entry.1048111489": email,
"entry.1786559101": option
});
alert("your radio button value: " + option);
//it's working..
//then validate your data before sending
$.ajax({
url: "https://docs.google.com/forms/d/e/1FAIpQLSfe760bJi_65cvSGfu4HckMdmAs1ahBkO7oE6njBTYZh4A/formResponse",
data: {
"entry.1012452068": firstname,
"entry.1038894874": surname,
"entry.1352091133": dob,
"entry.1048111489": email,
"entry.1786559101": option
},
type: "POST",
datatype: "xml",
statusCode: {
0: function() {
alert("status:0, thank you");
window.location.replace("thankyou.html");
},
200: function() {
alert("status:200, thank you");
window.location.replace("thankyou.html");
}
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<form>
First Name:
<br>
<input id="firstname" name="firstname" type="text" placeholder="First Name" />
<br>Surname:
<br>
<input id="surname" name="surname" type="text" placeholder="Surname" />
<br>DoB:
<br>
<input id="dob" name="dob" type="text" placeholder="DoB" />
<br>Email:
<br>
<input id="email" name="email" type="text" placeholder="Email" />
<br>Option Pledge:
<br>
<input id="option1" value="Black Ballad Membership - £49" name="option" type="radio" />£49
<br>
<input id="option2" value="Premium Black Ballad Membership - £69" name="option" type="radio" />£69
<br>
<input id="ButtonSubmit" name="" type="button" value="Send" onclick="postContactToGoogle()" />
</form>
Do following change in your code,
var option = $('input[name=option]:checked').val()
Note: There should not be the same id for two different element, you have used id "option" for both radio.

How can i update the text of more than one label with the same class name using the input blur event

I am working in a project and i have to update the text of a label when the focus is losed in the input
This is the html part:
<input id="FirstName" name="FirstName" type="text" value="" class="inputName"/>
<input id="MidName" name="FirstName" type="text" value="" class="inputName"/>
<input id="LastName" name="FirstName" type="text" value="" class="inputName"/>
<p class="passengerTitle1">hola</p>
<input id="FirstName" name="FirstName" type="text" value="" class="inputName"/>
<input id="MidName" name="FirstName" type="text" value="" class="inputName"/>
<input id="LastName" name="FirstName" type="text" value="" class="inputName"/>
<p class="passengerTitle1">hola</p>
and the js code of firing the blur event of the inputs is:
$(document).ready(function () {
fullName = '';
$(".inputName").blur(
function (event) {
var name = $(this).val();
fullName += name+ ' ';
$(".passengerTitle1").text(fullName);
}
);
});
I get the following result:
the text of both labels: Phellip E. Summer Edgar B. Thompson
But the expected result is :
for the first label Phellip E. Summer
for the second label Edgar B. Thompson
this is the jsfiddle link:jsfiddle lin
I wonder for a little help because it a very important project and don't want to miss the deadline of the project.
cheers.
As others have proposed solutions by changing the html, I'm proposing a solution to implement this without changing the html (if you want to stick to your current html).
Use .nextAll() and .first() like this:
$(this).nextAll(".passengerTitle1").first().text(fullName);
Implemented on your fiddle: JSFiddle
But you also have another problem, where you are not properly setting the fullName variable.
Again, if you don't want to change the html, you could solve it using .prev() like this:
JSFiddle
You may need to make some changes in your html.
I hope this is what you want to achieve.
$(".inputName").on("blur", function() {
var inputName = $(this).parent(".passengerInfo").children(".inputName");
var outputName = "";
$(inputName).each(function() {
outputName += $(this).val() + " ";
})
$(this).parent(".passengerInfo").children(".passengerTitle1").text(outputName)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="passengerInfo">
<input id="FirstName" name="FirstName" type="text" value="" class="inputName" />
<input id="MidName" name="FirstName" type="text" value="" class="inputName" />
<input id="LastName" name="FirstName" type="text" value="" class="inputName" />
<p class="passengerTitle1">hola</p>
</div>
<div class="passengerInfo">
<input id="FirstName" name="FirstName" type="text" value="" class="inputName" />
<input id="MidName" name="FirstName" type="text" value="" class="inputName" />
<input id="LastName" name="FirstName" type="text" value="" class="inputName" />
<p class="passengerTitle1">hola</p>
</div>
$(document).ready(function () {
$(".inputName").blur(
function (event) {
var titel = getPassengerTitel($(this)); // find the titel element
var fullName = getName(titel); // read Fullname by titel element
titel.html(fullName);
}
);
});
function getName(passengerTitelElem){
var last = passengerTitelElem.prev();
var middel = last.prev();
var first = middel.prev();
var name ='';
if(first.val()) name += first.val() + ' ';
if(middel.val()) name += middel.val() + ' ';
if(last.val()) name += last.val() + ' ';
return name;
}
function getPassengerTitel(e) {
var next = e.next();
if(next.attr('class') == 'passengerTitle1') {
return next;
}
return getPassengerTitel(next);
}

Categories

Resources