I realize that FireFox, Chrome, Safari, & Opera can limit the number of cookies a domain/website can set. So I thought of a different approach to storing my web forms many text, radio buttons, and select box values -Set a multi-variable cookie for each major section of the web form, instead of a separate cookie for each variable.
It would look something like this (inside each cookies content)...
firstName=John;&&;lastName=Andrews;&&;streetAddress=1234 Memory Ln.
What I'm looking for is a JavaScript function that will create/update this type of cookie on-the-fly properly (using element names instead of ID's for max compatibility with radio buttons) , triggered on each form elements 'onchange' event.
Then when needed, a function to load the cookie into a JavaScript string variable, parse the string for actual variables from between ';&&;' and load them into real JavaScript variables by the corresponding name, then when the user returns to the form the JavaScript fills in the values of the corresponding (by same name) form elements with these values, automatically.
Any help would be greatly appreciated.
Thanks in Advance!!
-James A.
FULL SOLUTION BELOW : Here is the complete 'save_form.js' code!
//<!-- Prerequisites: jquery.min.js -->
//<!-- A script to set a cookie [Argument(s) accepted: Cookie Name, Cookie Value, etc.] [BEGIN] -->
function set_cookie ( name, value, path, domain, secure )
{
var cookie_string = name + "=" + escape ( value );
var cookie_date = new Date(); // current date & time ;
var cookie_date_num = cookie_date.getTime(); // convert cookie_date to milliseconds ;
cookie_date_num += 35 * 60 * 1000; // add 35 minutes in milliseconds ;
cookie_date.setTime(cookie_date_num); // set my_date Date object 35 minutes forward ;
cookie_string += "; expires=" + cookie_date.toGMTString();
if ( path )
cookie_string += "; path=" + escape ( path );
if ( domain )
cookie_string += "; domain=" + escape ( domain );
if ( secure )
cookie_string += "; secure";
document.cookie = cookie_string;
};
//<!-- A script to set a cookie [Argument(s) accepted: Cookie Name, Cookie Value, etc.] [END] -->
//<!-- A script to grab a cookies value by name [Argument(s) accepted: Cookies Name] [BEGIN] -->
function get_cookie ( cookie_name )
{
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
{
return ( unescape ( results[2] ) );
}
else
{
return null;
};
};
//<!-- A script to grab a cookies value by name [Argument(s) accepted: Cookies Name] [END] -->
function populateCookieFromForm ( cookieName ) {
var encodedCookie;
var preCookieObj = '{';
var allMainElements = $('form').find('input[type=text], select');
for (var i=0; i < allMainElements.length; i++)
{
preCookieObj = preCookieObj + '"' + allMainElements[i].name +'":"'+ allMainElements[i].value +'",';
};
preCookieObj = preCookieObj.substring(0, preCookieObj.length - 1);
preCookieObj = preCookieObj + '}';
//<!-- btoa() encodes 'string' argument into Base64 encoding -->
encodedCookie = btoa( preCookieObj );
set_cookie(cookieName, encodedCookie);
};
function populateFormFromCookie (cookieName) {
if ( ! get_cookie ( cookieName ) )
{
//<!-- Do Nothing - No Cookie For this form set. -->
}
else
{
//<!-- atob() decodes 'string' argument from Base64 encoding -->
jSONCookieObj = atob( get_cookie ( cookieName ) ) ;
jSONObj = JSON.parse( jSONCookieObj );
var allMainElements = $('form').find('input[type=text], select');
for (var i=0; i < allMainElements.length; i++)
{
var elementName = allMainElements[i].name;
var elementValue = jSONObj[elementName];
allMainElements[i].value = elementValue;
};
};
};
function populateCookieFromRadios (cookieName) {
var radioState={};
$(':radio').each(function(){
if(!radioState[this.name]){
radioState[this.name]={};
}
radioState[this.name][this.value]=this.checked;
});
/* stringify to JSON and convert to Base64 */
var storeString= btoa(JSON.stringify(radioState));
/* store in cookie*/
set_cookie(cookieName, storeString);
};
function populateRadiosFromCookie (cookieName) {
if ( ! get_cookie ( cookieName ) )
{
//<!-- Do Nothing - No Cookie For this form set. -->
}
else
{
var cookieString = get_cookie ( cookieName );
var newPageState= JSON.parse(atob(cookieString));
/* loop through radios setting state */
$(':radio').prop('checked',function(){
return newPageState[this.name][this.value];
});
};
};
This is how you properly call these functions. Near the bottom of the HTML/PHP page containing the form, place this JavaScript respectively:
<script type="text/javascript">
//<!-- If returning user detected, populate form with cookie values [BEGIN] -->
populateFormFromCookie('thisForm');
populateRadiosFromCookie('thisFormRadios');
//<!-- If returning user detected, populate form with 'section' cookie values [END] -->
//<!-- On change of ALL form elements re-save form cookie(s) [BEGIN] -->
$('input[type=radio]', $('form')).on('change',function(e){
populateCookieFromRadios('thisFormRadios');
});
$('input[type=text], select, textarea', $('form')).on('change',function(e){
populateCookieFromForm('thisForm');
});
$('input[type=text]', $('form')).on('input',function(e){
populateCookieFromForm('thisForm');
});
//<!-- On change of ALL form elements re-save form cookie(s) [END] -->
</script>
The next task is to see if all of this can be done without jQuery...hmm...
Related
I made this little code using JS to disable cookies:
$(document).ready(function() {
var cookie_settings = getCookie("cookie-settings"); //Main cookie which contains cookie preferences
var cookie_selector = document.getElementById("cookie-selector"); //Modal for cookie selection
var g_recaptcha = document.getElementById("cookie-g-recaptcha"); //Example checkbox cookie
var g_tag_manager = document.getElementById("cookie-g-tag-manager"); //Example checkbox cookie
var messenger_plugin = document.getElementById("cookie-fb-mccp"); //Example checkbox cookie
var g_analytics = document.getElementById("cookie-g-analytics"); //Example checkbox cookie
var cookie_set = document.getElementById("cookie-set"); //Button to save preferences
if (cookie_settings == null) { //Check if main cookie exist
$(cookie_selector).modal({
backdrop: 'static',
keyboard: false
}); //If not exist, open cookie selector modal
} else {
var cookie_settings_raw_values = getCookie("cookie-settings"); //read and save main cookie in var
var cookie_settings_values = cookie_settings_raw_values.split('&'); //save main cookie content in array
if (cookie_settings_values.includes(g_recaptcha.id)) {
//If array contains recaptcha example include it
//for example append in head -> $('head').append('myscript');
}
if (cookie_settings_values.includes(g_tag_manager.id)) {
//same
//for example append in head -> $('head').append('myscript');
}
if (cookie_settings_values.includes(messenger_plugin.id)) {
//same
//for example append in head -> $('head').append('myscript');
}
if (cookie_settings_values.includes(g_analytics.id)) {
//same
//for example append in head -> $('head').append('myscript');
}
//or you can remove else condition and manage this part from php
}
$(cookie_set).click(function() { //on save preferences click
var selected_cookies = [g_recaptcha.id, g_tag_manager.id]; //make array and include required cookies
if (messenger_plugin.checked == true) {
//if messenger plugin example checkbox is checked push it's reference in array
selected_cookies.push(messenger_plugin.id);
}
if (g_analytics.checked == true) {
//same for the other optional checkboxes
selected_cookies.push(g_analytics.id);
}
var expiry_date = new Date();
expiry_date.setMonth(expiry_date.getMonth() + 6); //expiration date 6 months in my case, you can set what you want
document.cookie = document.cookie = "cookie-settings=" + selected_cookies.join('&') + "; expires=" + expiry_date.toGMTString(); //make main cookie with required and optional selected checkboxes (the deadline is 6 months after the creation of the cookie)
location.reload(); //reload page
});
//get cookie by name
function getCookie(name) {
var document_cookie = document.cookie;
var prefix = name + "=";
var begin = document_cookie.indexOf("; " + prefix);
if (begin == -1) {
begin = document_cookie.indexOf(prefix);
if (begin != 0) {
return null;
}
} else {
begin += 2;
var end = document.cookie.indexOf(";", begin);
if (end == -1) {
end = document_cookie.length;
}
}
return decodeURI(document_cookie.substring(begin + prefix.length, end));
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
My question is it enough to disable third-party cookies?
Not including the scripts if the user does not accept cookies, do the stored ones become useless? Does the site comply with the GDPR?
If not, do you have any other valid alternative to propose that is not the use of third party codes?
Most of the websites, which are trying to be GDPR compliant are not loading any of these scripts by default (as you probably do). First they show a popup, if a user wants to load e.g. tracking cookies and if the user agrees they will be loaded. The configured setting which services should be loaded / what the user has selected will then be stored either in a cookie or e.g. the localStorage.
So yes, your site seems to be GDPR compliant when we take a look at the approach how you load the external scripts.
If you’re talking about deleting them, set it again with the expiry date before today.
I'm using TypeForm to handle my lead generation forms. The form I'm using has been embedded on the home page of my site. This embedding creates an iframe showing the popup every time the home page is loaded, even if the 'X' is clicked.
Having contacted TypeForm, I have been told that I would need to set a cookie to prevent the popup loading each time. In fact their reply was "To ensure the Typeform only appears once you will have to add cookies to your site in order to ensure a user only sees it one time. This isn't a feature we currently have but hopefully with more requests it's something we could add!"
Embed Code:
<a class="typeform-share button" href="https://example.typeform.com/to/fbPnzs" data-mode="drawer_left" data-auto-open=true target="_blank" style="display:none;"></a>
<script>
(function() {
var qs, js, q, s, d = document,
gi = d.getElementById,
ce = d.createElement,
gt = d.getElementsByTagName,
id = "typef_orm_share",
b = "https://embed.typeform.com/";
if (!gi.call(d, id)) {
js = ce.call(d, "script");
js.id = id;
js.src = b + "embed.js";
q = gt.call(d, "script")[0];
q.parentNode.insertBefore(js, q)
}
})()
</script>
The embed URL is example.typeform.com whereas the website where the form is to be embedded is not the same. Does consideration need to be made about same-origin?
What do I need to implement in terms of code to the functions.php file of my WordPress site to add a cookie that allows the popup to show only once and/or never show again if the 'X' is clicked?
Thank to Nicolas for his answer!
Having checked over the SDK, I've adapted Nicolas' snippet to cater to the left draw popup. This checks if a cookie exists, if it does not, it should set it and display the left draw TypeForm popup; if the cookie does exist, it won't show.
var url = "https://demo.typeform.com/to/njdbt5" // Update with your TypeForm URL
let params = new URLSearchParams( location.search );
url += "?utm_source=" + params.get( 'utm_source' ); // Replace with the hidden values you want to pass
var displayed = getCookie( "typeform_displayed" ); // Check for the cookie typeform_displayed
if ( displayed ) {
null
} else if ( !displayed && displayed === "" ) {
setCookie( "typeform_displayed", true, 365 ); // Set typeform_displayed cookie with a value of true and an expiry of 365 days
showEmbed();
}
//
function showEmbed() {
window.typeformEmbed.makePopup( url, {
mode: 'drawer_left',
autoOpen: true,
hideHeaders: true,
hideFooters: true,
} )
}
// Cookie Manipulation
// Source: https://www.w3schools.com/js/js_cookies.asp
function setCookie( cname, cvalue, exdays ) {
var d = new Date();
d.setTime( d.getTime() + ( exdays * 24 * 60 * 60 * 1000 ) );
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie( cname ) {
var name = cname + "=";
var decodedCookie = decodeURIComponent( document.cookie );
var ca = decodedCookie.split( ';' );
for ( var i = 0; i < ca.length; i++ ) {
var c = ca[ i ];
while ( c.charAt( 0 ) == ' ' ) {
c = c.substring( 1 );
}
if ( c.indexOf( name ) == 0 ) {
return c.substring( name.length, c.length );
}
}
return "";
}
I think this is totally doable using Typeform Embed SDK.
You will need to check if the cookie is already set. And depending on the value display or not the embed typeform.
I made a working example on Glitch, you can look at it here.
In code the logic would look like this:
var displayed = getCookie("displayed_typeform");
if (displayed){
embedElement.innerHTML="<h2>Typeform already displayed once.</h2>"
} else if (!displayed && displayed === "") {
setCookie("displayed_typeform", true, 365);
showEmbed();
}
Hope it helps :)
Just a day ago I posted this question and found/built my own solution, for lack of a sufficient answer. Now, I need help going through a similar process again. This time, however, I need to capture (save to cookie as 'Base64' data) and recall (recheck upon user return) the state of all the radio button groups (by 'name' not 'ID', for obvious reasons), after the page loads, and if need be trigger all corresponding onchange events attached to them. For example, if a radio button group label has the question, "Have you lived at this address for more than 3 years?' one radio button label says 'Yes', and the other, 'No'. If the user chooses 'No' an extra 'address' table row is displayed in the table. All of the mechanics of the table appearing on 'No' 'checked' has already been done. I'm looking for a simple way to:
A:) Record all radio button group(s) state(s) (i.e which one is checked), on the 'onchange' event of any radio button on the form.
B:) Convert that information to JSON or some other record keeping
C:) Base64 encode data in step [B:]
D:) Save to a cookie
Upon page reload (user returns to page)...
E:) Grab data from cookie
F:) Decode Base64 and assign to variable
G:) From data iterate through all the forms radio buttons re-checking what was originally checked.
Sound easy? Give it a try! I did....and am still.
Here's the basics in jQuery without the cookie saving, will leave that to you
var radioState={};
$(':radio').each(function(){
if(!radioState[this.name]){
radioState[this.name]={};
}
radioState[this.name][this.value]=this.checked
});
/* stringify to JSOn and convert to Base64 */
var storeString= btoa(JSON.stringify(radioState));
/* store in cookie*/
/* on page load pull data from cookie (if exists) - add a cookie validation test*/
var cookieString=storeString;// just using this for demo
var newPageState= JSON.parse(atob(cookieString));
/* loop through radios setting state */
$(':radio').prop('checked',function(){
return newPageState[this.name][this.value];
});
DEMO
atob() and btoa() docs
EDIT: Use localStorage if browser supported, with cookie fallback. Will minimize cookie size sent to server for each and every http request made to site
Thank You #Charlietfl. +1! Here is the complete 'save_form.js' code!
//<!-- Prerequisites: jquery.min.js -->
//<!-- A script to set a cookie [Argument(s) accepted: Cookie Name, Cookie Value, etc.] [BEGIN] -->
function set_cookie ( name, value, path, domain, secure )
{
var cookie_string = name + "=" + escape ( value );
var cookie_date = new Date(); // current date & time ;
var cookie_date_num = cookie_date.getTime(); // convert cookie_date to milliseconds ;
cookie_date_num += 35 * 60 * 1000; // add 35 minutes in milliseconds ;
cookie_date.setTime(cookie_date_num); // set my_date Date object 35 minutes forward ;
cookie_string += "; expires=" + cookie_date.toGMTString();
if ( path )
cookie_string += "; path=" + escape ( path );
if ( domain )
cookie_string += "; domain=" + escape ( domain );
if ( secure )
cookie_string += "; secure";
document.cookie = cookie_string;
};
//<!-- A script to set a cookie [Argument(s) accepted: Cookie Name, Cookie Value, etc.] [END] -->
//<!-- A script to grab a cookies value by name [Argument(s) accepted: Cookies Name] [BEGIN] -->
function get_cookie ( cookie_name )
{
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );
if ( results )
{
return ( unescape ( results[2] ) );
}
else
{
return null;
};
};
//<!-- A script to grab a cookies value by name [Argument(s) accepted: Cookies Name] [END] -->
function populateCookieFromForm ( cookieName ) {
var encodedCookie;
var preCookieObj = '{';
var allMainElements = $('form').find('input[type=text], select');
for (var i=0; i < allMainElements.length; i++)
{
preCookieObj = preCookieObj + '"' + allMainElements[i].name +'":"'+ allMainElements[i].value +'",';
};
preCookieObj = preCookieObj.substring(0, preCookieObj.length - 1);
preCookieObj = preCookieObj + '}';
//<!-- btoa() encodes 'string' argument into Base64 encoding -->
encodedCookie = btoa( preCookieObj );
set_cookie(cookieName, encodedCookie);
};
function populateFormFromCookie (cookieName) {
if ( ! get_cookie ( cookieName ) )
{
//<!-- Do Nothing - No Cookie For this form set. -->
}
else
{
//<!-- atob() decodes 'string' argument from Base64 encoding -->
jSONCookieObj = atob( get_cookie ( cookieName ) ) ;
jSONObj = JSON.parse( jSONCookieObj );
var allMainElements = $('form').find('input[type=text], select');
for (var i=0; i < allMainElements.length; i++)
{
var elementName = allMainElements[i].name;
var elementValue = jSONObj[elementName];
allMainElements[i].value = elementValue;
};
};
};
function populateCookieFromRadios (cookieName) {
var radioState={};
$(':radio').each(function(){
if(!radioState[this.name]){
radioState[this.name]={};
}
radioState[this.name][this.value]=this.checked;
});
/* stringify to JSON and convert to Base64 */
var storeString= btoa(JSON.stringify(radioState));
/* store in cookie*/
set_cookie(cookieName, storeString);
};
function populateRadiosFromCookie (cookieName) {
if ( ! get_cookie ( cookieName ) )
{
//<!-- Do Nothing - No Cookie For this form set. -->
}
else
{
var cookieString = get_cookie ( cookieName );
var newPageState= JSON.parse(atob(cookieString));
/* loop through radios setting state */
$(':radio').prop('checked',function(){
return newPageState[this.name][this.value];
});
};
};
This is how you properly call these functions. Near the bottom of the HTML/PHP page containing the form, place this JavaScript respectively:
<script type="text/javascript">
//<!-- If returning user detected, populate form with cookie values [BEGIN] -->
populateFormFromCookie('thisForm');
populateRadiosFromCookie('thisFormRadios');
//<!-- If returning user detected, populate form with 'section' cookie values [END] -->
//<!-- On change of ALL form elements re-save form cookie(s) [BEGIN] -->
$('input[type=radio]', $('form')).on('change',function(e){
populateCookieFromRadios('thisFormRadios');
});
$('input[type=text], select, textarea', $('form')).on('change',function(e){
populateCookieFromForm('thisForm');
});
$('input[type=text]', $('form')).on('input',function(e){
populateCookieFromForm('thisForm');
});
//<!-- On change of ALL form elements re-save form cookie(s) [END] -->
</script>
The next task is to see if all of this can be done without jQuery...hmm...
This is code which shows URL and delete image for delete cookie. add and display function is working but how to delete ??
function backLinks(){
var pathname = window.location;
var patientName = document.getElementById("general:patientDetailName").value;
var cookieTimeVal = jQuery.cookie('PCC_Back_Button');
if( cookieTimeVal== null){
cookieTimeVal ="";
}
// for writing Cookie
var stringCookie = "<span class='backLinkText1'><img src='../images/deleteImg.png' alt='' class='backLinkDeleteButton' onClick='deleteBackLink()'/></span><a class='backLinkText' href=\""+pathname+"\"> Patient History For \""+patientName+"\"</a>"+cookieTimeVal;
jQuery.cookie('PCC_Back_Button', stringCookie , { expires: 1 });
// read Cookie and set in HTML
jQuery('#backButtonSpan').append(
jQuery('<div>').attr({style:'padding-top:-10px;' }).append(cookieTimeVal)
);
}
**
function deleteBackLink(val){
jQuery.cookie(val, null);
}
**
How can I create a delete function and what parameter will I pass to it?
got a correct answer ...
in this i will replace cookie and delete inner html
function backLinks(stringValueAndName, patientName, patientDOB){
var pathname = window.location;
var cookieTimeVal = jQuery.cookie('PCC_Back_Button');
if( cookieTimeVal== null){
cookieTimeVal ="";
}
var time = new Date();
var spanId = time.getTime();
// for wright in Cookie
var stringCookie = "<span id ="+spanId+"> <img src='../images/deleteImg.png' class='backLinkDeleteButton' onClick='deleteBackLink("+spanId+")'/><a class='backLinkText' href=\""+pathname+"\">"+stringValueAndName +patientName+' ('+patientDOB +')'+"\</a></span>"+cookieTimeVal;
jQuery.cookie('PCC_Back_Button', stringCookie , { expires: 1 });
// read Cookie and set in HTML
jQuery('#backButtonSpan').append(
jQuery('<div>').attr({style:'padding-top:-10px;' }).append(cookieTimeVal)
);
}
function deleteBackLink(val){
jQuery('#'+val).remove();
var stringCookie = jQuery('#backButtonSpan div').html();
jQuery.cookie('PCC_Back_Button', stringCookie , { expires: 1 });
}
To delete a cookie with jQuery, set the value to null:
jQuery.cookie("name", null);
So your function will work - just pass the cookie name as a parameter:
deleteBackLink("name");
It doesn't. A cookie is a cookie.
The closest it comes is the HTTP Only flag, which allows a cookie to be hidden from JavaScript(mean client side). (This provides a little defence against XSS cookie theft).
A cookie is a cookie. (Again, client side code can't touch an HTTP only cookie)
Im taking the domain from the HTML of the page using jQuery:
domainUrl = $("p.domain").text();
for the purposes of testing:
<p class="domain">.vl3.co.uk</p>
Which is also the domain Im testing the script on.
This then give an alert containing the correct domain:
alert(domainUrl);
I want to the use that variable to set the domain in a cookie:
set_cookie('visible', 'no', 2020, 1, 1, '/', '+domainUrl+');
Here is the set cookie function:
function set_cookie ( name, value, exp_y, exp_m, exp_d, path, domain, secure ) {
var cookie_string = name + "=" + escape ( value );
if ( exp_y ) {
var expires = new Date ( exp_y, exp_m, exp_d );
cookie_string += "; expires=" + expires.toGMTString();
}
if ( path )
cookie_string += "; path=" + escape ( path );
if ( domain )
cookie_string += "; domain=" + escape ( domain );
if ( secure )
cookie_string += "; secure";
document.cookie = cookie_string;
}
Why doesnt the cookie domain get set?
I think the problem is how im using the domainUrl variable when setting the cookie?
It should be:
set_cookie('visible', 'no', 2020, 1, 1, '/', domainUrl);
Pls, try this extension, it works, it comprises all that:
http://plugins.jquery.com/project/Cookie
Then you only have to write:
$.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com' });
Use jquery Annex library
I think this is the best way to get and set cookies using jQuery:
// cookie [writes and reads cookies]
//set cookie
$.cookie('kittencookie', 'fluffy', {expires : 7});
//get cookie
var kittenCookieValue = $.cookie('kittencookie');
For more details see documentation.