Link to home
Start Free TrialLog in
Avatar of sharingsunshine
sharingsunshineFlag for United States of America

asked on

In jQuery How Do You Do "If Test" On Cookie?

I am trying to have jquery write a cookie and test for its presence.  If if is present write a message in the order_comments box of Woo Commerce.  Here is an answer using jquery to write in the order_comments box.

https://www.experts-exchange.com/questions/29114316/Need-Javascript-JQuery-Button-Update-Woo-Commerce-Order-Notes.html

Open in new window


Here is my present jquery code

<script type="text/javascript">

jQuery(function() {
		jQuery('#cook').click(function(e) {
		e.preventDefault();
		document.cookie = "wantmembership=1; path=/";
              jQuery(this).css('background-color','green');
              jQuery(this).text("I Now Have A Membership!");
			});
	
		
	});

</script>

Open in new window


This creates the code.  I just need help knowing how to read the presence of the cookie and then write the message in the order_comments box.

Thanks,
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

From here https://www.w3schools.com/js/js_cookies.asp
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 "";
}

Open in new window


Writing to the order comments box - do you want to overwrite or append to?
Is this a form control or normal element
Normal element

Overwrite
$('#order_comments').text(value_you_want_to_write);

Open in new window

Append
var val = $('#order_comments').text() + value_you_want_to_write;
$('#order_comments').text(val);

Open in new window


Form control
Overwrite
$('#order_comments').val(value_you_want_to_write);

Open in new window

Append
var val = $('#order_comments').val() + value_you_want_to_write;
$('#order_comments').val(val);

Open in new window

Avatar of sharingsunshine

ASKER

Using your code above and some others I get getCookie isn't defined.  

<script type="text/javascript">

jQuery(function() {
		jQuery('#cook').click(function(e) {
		e.preventDefault();
		document.cookie = "wantmembership=1; path=/";
              jQuery(this).css('background-color','green');
              jQuery(this).text("I Now Have A Membership!");
			});
	
		
	});

jQuery(function getCookie(cname) {
  var name = cname + "=";
  var ca = document.cookie.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 "";
});

jQuery(function checkCookie() {
  var username = getCookie("wantmembership");
  if (username!= "") {
   alert("Welcome again " + username);
  } else {
    username = prompt("Please enter your name:", "");
    if (username != "" && username != null) {
      setCookie("username", username, 365);
    }
  }
});
</script>

Open in new window


I am just trying to keep this simple, initially.  Meaning, I just want the alert's to show up.  However, they aren't.  Do you have any suggestions?
I don't understand what you are doing here
jQuery(function checkCookie() {
  var username = getCookie("wantmembership");
  if (username!= "") {
   alert("Welcome again " + username);
  } else {
    username = prompt("Please enter your name:", "");
    if (username != "" && username != null) {
      setCookie("username", username, 365);
    }
  }

Open in new window

This will run at document load - so it is going to fetch the cookie before you have set it - I don't understand your intention here?
Apparently, I didn't either.  I now think that I have to call the 2 functions after the onclick event.  However, I am not clear how to do that.  Here is what I have put together but WordPress won't permit me to save the code because it says error.  Nothing else just the word error.  Xampp isn't showing anything in the logs either.

jQuery(function() {
		jQuery('#cook').click(function(e) {
		e.preventDefault();
		document.cookie = "wantmembership=1; path=/";
              jQuery(this).css('background-color','green');
              jQuery(this).text("I Now Have A Membership!");
			getCookie(cname);
			checkCookie();
			});
});
	
		jQuery(function getCookie(cname) {
  var name = cname + "=";
  var ca = document.cookie.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 "";
});

jQuery(function checkCookie() {
  var username = getCookie("wantmembership");
  if (username!= "") {
   alert("Welcome again " + username);
  } 
  });

Open in new window


Please show me the correct syntax.
Hasn't really changed.

jQuery(function getCookie(cname) {

Open in new window


What is this doing?

That is going to run getCookie on document load - because you are passing it to the jQuery() function. Same with checkCookie()

Not sure why you want to do that.

Why are you wrapping your functions in a call to jQuery - that is going to result in lines 7-8 erroring out because it can't find the functions.

Just explain in words what you want this code to do.
I want the code to create the cookie by a button (which it does.)  Then if the cookie is present I want it to write the message in the Order Comments box.

When the order is submitted I want it to delete the cookie, which in turn will remove the message from the Order Comments box.

I thought I had to tie the other 2 functions to the button click.  That's why I put line 7 and 8 there.

I was just trying to keep checkCookie very simple by using the alert.  I know it won't write to the box like I need.

To get what I want for this question, I just need to have the onclick fire those functions when the button is pressed.
 That's why I put line 7 and 8 there.

Open in new window

Thtat's fine (sort of) but they are not going to work because you put your function declaration inside a jQuery() function call - which is really just passing a function to jQuery - which then runs the function on document load.

I don't understand why it must fire both on the page?

I thought the point of the cookie was to set a flag to say the user wants membership - and then on a DIFFERENT page check that flag to see if it is set and only then update the form.
your understanding is correct but I don't know how to do it on a different page.
I don't understand - what is the issue
// first page
$(function() {
   $('#wantmembership').click(function() {
      // setcookie here
   });
});

Open in new window


// second page
$(function() {
   // getCookie();
   // Update content
});

Open in new window

The issue is when I put the code in the actual page it becomes surrounded by <p> tags.  So, I found this script

/* Enqueue scripts (and related stylesheets) */
    add_action( 'after_setup_theme', 'my_nifty_scripts' );
	//add_action('wp_enqueue_scripts', 'my_nifty_scripts');
/**
 * Registers scripts for the theme and enqueue those used site wide.
 *
 * @since 0.1.0.
 */

function my_nifty_scripts() {
    wp_register_script('myown', get_stylesheet_directory_uri() . 'js/myown.js', false, null, true);
if (is_checkout()){
    wp_enqueue_script('myown'); 
}
}

Open in new window


I put my code in the js folder and it is  set up in this fashion

https://gyazo.com/d7eca1387ad05223b90b7a863ecfe2e4

Open in new window


but when I access the page the code isn't there.

Lastly, I am not clear how to put the code on the checkout page it is created by a shortcode.

https://gyazo.com/9142ba3d4e7675f9dfd137c5e46811df

Open in new window


Because this is on an XAMPP install this isn't a valid url.
For now just enqueue the script for all pages remove lines 12 and 14.

Can you post your final script here.
Here is my script to read the cookie and write the message.
	
jQuery(function getCookie(cname) {
			
  var name = cname + "=";
  var ca = document.cookie.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 "";
});

jQuery(function checkCookie() {
  var username = getCookie("wantmembership");
	echo 'username';
  if (username=== "wantmembership") {
   jQuery('#order_comments').val(I Want Membership);
  } 
  });

Open in new window


This is found in js/myown.js and it does show up in the source code.

IAs you can see, I  wrapped the other functions in a jQuery wrapper so they would load at document ready.  Ideally they need to only be firing on the checkout page.

I put the cookie create code in the page where the button is supposed to be in this manner.

<script type="text/javascript">
jQuery(function() {
		jQuery('#cook').click(function(e) {
		e.preventDefault();
		document.cookie = "wantmembership=1; path=/";
              jQuery(this).css('background-color','green');
              jQuery(this).text("I Now Have A Membership!");
			});
});
</script>

Open in new window


This does create the cookie and change the button after it is pushed.

As it is no text is written and I have tried text and val both.  Also, my echo never shows any output.
We are going in circles.

Why are you doing this
jQuery(function getCookie(cname) {

Open in new window

What is it you think this code doing?
What is it you are wanting to do?
I thought the function checkCookie was using the getCookie function to see if the cookie exists and the getCookie function was being supplied the cname since it was calling the getCookie function with the name of the cookie.

I am wanting it to find the cookie "wantmembership" and when it does write the message in the order comments box.  I put the echo statement in there to test if I was close and it seems I am not.  Additionally, it should load this only on the checkout page.

I wrapped it in jQuery so it would execute once the document loaded.
I thought the function checkCookie was using the getCookie function to see if the cookie exists and the getCookie function was being supplied the cname since it was calling the getCookie function with the name of the cookie.
Yes - but why are you invoking getCookie inside a jQuery function - it does nothing. getCookie must be called by some other code with a cookie name as a parameter. By putting it inside a jQuery function you are making it anonymous - it won't exist anywhere by the name getCookie so when you invoke it in checkCookie - it won't exist. In this case when it does run (on document load) the name parameter will be the jQuery object.

You need to understand two things
1. lambda functions = functions that are passed as parameters. In this case the getCookie.
Usually when we pass a function we don't name it we just declare it like this
someOtherFunction(function() {
  alert('boo');
});

Open in new window

So in your case what you are doing is invoking a function on document load that runs and then dies which is not what you want. You want to declare the function so that you can call it from checkCookie.

2. Scoping
$(function() {
   function getCookie(name) {
     alert(name);
   }
});
$(function() {
   // getCookie is not defined in this scope
   getCookie('test');
});

Open in new window

By placing your function in different jQuery calls (setting aside that the getCookie() was not a declaration but an anonymous function that was executed on document load - assuming you had declared it correctly) you isolated their scope from each other - so even if you declared your getCookie() function correctly (instead of invoking it) your code would not work because the function is not visible to your checkCookie function
Here is an example of how you should be doing it.
jQuery(function($) {
    // Invoke checkCookie on document load
    checkCookie();

    // Function definition
    function getCookie(name) {
       // ...
    }
    function checkCookie() {
        var cookie = getCookie('wantmembership');
    }
})

Open in new window


While you are learning about scope you can also learn about hoisting - the process by scope globals are "hoisted" to the top of their scope so they can be used before they are declared.
That helped a lot to understand what is going on.  I decided to remove the jQuery tags now to do some troubleshooting.

I can get the first two document writes to display but there seems to be a problem with testing for the cookie.

[woocommerce_checkout]

	<script type="text/JavaScript">
<!--
function getCookie(cname) {
			
  var name = cname + "=";
  var ca = document.cookie.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 "";
}

function checkCookie() {
document.write("Print this in the function");
  var username = getCookie("wantmembership");
document.write("Print this after the get");
	  if (username== "wantmembership") {
document.write("Print this after the if test");
   jQuery('#order_comments').val('I Want Membership');
  } 
  }
//-->
</script>
<script type="text/JavaScript">
<!--
checkCookie();
//-->
</script>

Open in new window


I have all of this on the checkout page inline.  I know that is not ideal and once I can get this to work.  I'll post another question on putting the scripts external because they don't work external on my localhost.

Can you see any problem with my logic.  Console isn't showing any errors?
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks for the code but not using the comment tags it puts <p>'s around the script.

https://gyazo.com/5a2334fc02a555fe0ab50fe96dd84667

Putting the comments back doesn't work either.
Thanks for the help.  It took me a while because the document.write statements locked up the system.  Once I commented those out the page came back.  Then I realized line 31 needs a semi-colon at the end.

However, I only mention those items if someone looks at the code in the future.

I certainly couldn't have completed the project without your help.

Thank again,
You are welcome.