Jump to content

info bar, close on click, set cookie, don't show again [SOLVED]


onjegolders
 Share

Recommended Posts

Sorry about the somewhat confusing title!

I'm trying to set up an "info bar" where the client can add a bit of information right at the top of the screen which can be closed using jQuery. Despite my awful jQuery skills, I've managed that part.

I'm just a bit confused as to the best way to handle subsequent pages.

Could I do this in PW alone using cookies or session?

Or would I need to trigger something else in JS when the close button is pressed?

Also is there any acceptable CSS fallback for closing the info bar if there's no JS (I'm guessing maybe just refresh the page?)

Thanks in advance if anyone has any ideas how they'd handle this.

Screenshot attached :)post-502-0-47683300-1354537042_thumb.png

Link to comment
Share on other sites

I've done this before using a textarea field attached to the homepage. I've put the $homepage->this_field in right under <body> in my main.inc (the file which holds most html). Then I check IF cookie value (i.e. noshow+something_unique = 1) exists and IF message content exists. You have to make sure you set an unique cookie, otherwise the next message might not be shown.

Link to comment
Share on other sites

Thanks Arjen

This thread has got it working

Basically setting a session if the user has already visited the/a page. It works nicely but not sure, maybe I should use a cookie instead...

Do you remember how you handled closing the div if user has no js? Or did you just leave it until page refresh?

Link to comment
Share on other sites

Also wondering if there's a way of resetting it so that if the field is changed, then the message will show again but I don't think field->modified is accesible.

Perhaps I could set a cookie with the value of the message and then if that message changes then the cookie will no longer be valid?

Link to comment
Share on other sites

Cheers Arjen, that's a good point. Think I have it though with cookies

At top:

<?php $settings = $pages->get("template=settings"); 
$info_bar = "";
if ($settings->info_bar) {
$info_bar = $settings->info_bar;
setcookie("InfoBar", $info_bar, time()+3600);  /* expire in 1 hour */
}
?>

To output

<?php if ($settings->info_bar) { 
if ($input->cookie->InfoBar == $settings->info_bar) {
} else { ?>
<div id="info_bar">
<div class="container">
<?php echo $settings->info_bar; ?>
<a class="close" href="javascript:void(0)">x</a>
</div>
</div>
<?php }  
} ?>

Am sure there's a million ways to improve that but it seems to be working for now...

  • Like 1
Link to comment
Share on other sites

Actually, it turns out after a while, randomly some pages will start showing the info bar again. It was well within the cookie timeframe which I changed to 30 days. But I couldn't figure out which pages were triggering the infobar to show up again.

I'm now trying with

At the top:

<?php $settings = $pages->get("template=settings"); 

if ($settings->info_bar && $input->cookie->InfoBar == "") {
setcookie("InfoBar", $settings->info_bar, time()+3600*24*30);
}
?>

To output:

<?php if ($settings->info_bar) { ?>
<?php if ($input->cookie->InfoBar == $settings->info_bar) {
// do nothing
} else { ?>
<div id="info_bar">
<div class="container">
<?php echo $settings->info_bar; ?>
<a class="close" href="javascript:void(0)">x</a>
</div>
</div>
<?php } ?>
<?php } ?>

But for some reason, the infobar keeps re-appearing. Any ideas?

Link to comment
Share on other sites

Do you have template caching turned on? That would negate the use of any cookies set from PHP. When I need cookies and caching, I use Javascript-based cookies instead, since they are client-side and still happen regardless of server side caching.

Link to comment
Share on other sites

Do you have template caching turned on? That would negate the use of any cookies set from PHP. When I need cookies and caching, I use Javascript-based cookies instead, since they are client-side and still happen regardless of server side caching.

Thanks Ryan, I haven't turned any caching on, unless it's on be default?

I'm a bit confused as the cookie seems to set then at some point get reset to nothing? I'm not sure where each part of the cookie needs to get checked or why it's resetting when my if condition seems logical enough.

If I don't have caching on, would it be best to set them in PHP? Any idea where I'm going wrong with my code? Sorry, just pulling my hair out a bit, all I want to do is to check whether their cookie if they have already had it set, matches the field and if not set it.

Thanks again, and congrats on the award!

Link to comment
Share on other sites

Caching isn't on by default (Templates > edit template > cache). So if you aren't using cache, I'm not sure what the issue could be. You might try replacing $input->cookie->InfoBar with $_COOKIE['InfoBar'], just to see if there's any difference (just in case, since you are on the dev branch). Cookies are stored at the client side, so it's always worth considering that too (something interfering with cookies?).

Link to comment
Share on other sites

I did what I should always do when I have a problem like this: strip everything back, I created a new mamp site folder with simple PHP and echoed out words to help me understand what was going on on each page reload. Then I adapted it to my PW installation, all seems OK now. The putting it into words thing is surprisingly handy - helps me understand much better!

At top:

<?php
$settings = $pages->get("template=settings");
$info_bar = $settings->info_bar;
$out = "";
if ($info_bar) {
if (!isset($input->cookie->InfoBar) && $info_bar) {
setcookie("InfoBar", $info_bar, time()+3600*24*30);
$out = "Field exists and cookie wasn't set so cookie set anew!";
} elseif (isset($input->cookie->InfoBar) && $input->cookie->InfoBar !== $info_bar) {
setcookie("InfoBar", $info_bar, time()+3600*24*30);
$out = "Cookie existed but content didn't match, so cookie reset!";
} else {
$out = "Field has contents but cookie matches so nothing needed to be done";
}
} else {
$out = "Field is empty!";
}
?>

At output:

<?php if ($settings->info_bar && $input->cookie->InfoBar) {
if ($input->cookie->InfoBar !== $settings->info_bar) { ?>
<div id="info_bar">
<div class="container">
<?php echo $settings->info_bar; ?>
<a class="close" href="javascript:void(0)">x</a>
</div>
</div>
<?php }
} ?>

May help people out if they're stuck too :)

  • Like 1
Link to comment
Share on other sites

That stripping everything back and creating a specific test case is always a good way to solve problems. Usually kind of fun too. :) I'm not yet clear on why it wasn't working the first time around though?

Link to comment
Share on other sites

That stripping everything back and creating a specific test case is always a good way to solve problems. Usually kind of fun too. :) I'm not yet clear on why it wasn't working the first time around though?

You and me both! I think it was probably me reloading the page and without seeing the words I later created, failing to understand why the logic wasn't working and probably fiddling rather than going through it properly!

Link to comment
Share on other sites

Aghhhh, don't you just hate it when for no apparent reason something stops working?!

I've literally no idea what's happened but the cookie is now getting emptied randomly on certain page loads.

So if content changes, the cookie will reset and the info bar will show, on next page reload it will disappear as the field will once again match the cookie contents but if I then go to another page, the cookie will be an old one and won't match, or it will be empty altogether.

I have no idea how this is happening, could it be a caching issue? Though I don't think so as I haven't turned on caching on any pages.

My setcookie code is the first thing in my header include and my infobar itself is the first thing inside body.

Am pretty at a loose end now, so if anyone could lend a hand it would be MUCH appreciated!

Or even a better way to accomplish the same thing?

Thanks if you can help!

On a small scale test version, outside of PW all seems to work ok. Here is the code I set up:

header.inc

<?php
$info_bar = "Here is my really, really, really important message";
$out = "";
// first check field isn't empty
if ($info_bar) {
// if cookie doesn't exist, set it
if (!isset($_COOKIE["InfoBar"]) && $info_bar) {
setcookie("InfoBar", $info_bar, time()+3600);
$out = "Field exists and cookie wasn't set so cookie set anew!";
// if it exists but doesn't match the field, reset it
} elseif (isset($_COOKIE["InfoBar"]) && $_COOKIE["InfoBar"] !== $info_bar) {
setcookie("InfoBar", $info_bar, time()+3600);
$out = "Cookie existed but content didn't match, so cookie reset!";
// if it's set and matches, do nothing.
} else {
$out = "Field has contents but cookie matches so nothing needed to be done";
}
} // if field is empty
else {
$out = "Field has no contents!";
}
?>

index.php

<?php include("header.inc"); ?>

<!DOCTYPE HTML>

<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="description" content="">
<meta name="description" content="">

<title>Cookies Test</title>

<!-- scripts -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<style type="text/css">

* {
margin: 0;
padding: 0;
}

#info_bar {
width: 100%;
text-align: center;
padding: 10px 0;
background-color: #ecffa1;
color: #666;
margin-bottom: 80px;
}

</style>

</head>
<body>

<?php if ($info_bar) {
if ($_COOKIE["InfoBar"] !== $info_bar) { ?>
<div id="info_bar">
<div class="container">
<?php echo $info_bar; ?>
<a class="close" href="javascript:void(0)">x</a>
</div>
</div>
<?php }
} ?>

<h1>My Cookie Test site!</h1>
<h2>Homepage</h2>

<h3><?php echo $out; ?></h3>
<h3>Field contents: <?php echo $info_bar; ?></h3>
<h3>Cookie contents on last reload: <?php echo $_COOKIE["InfoBar"]; ?></h3>

<a href="about.php">About</a>

<script type="text/javascript">
$(document).ready(function() {
$("#info_bar a.close").click(function() {
$("#info_bar").slideUp(100);
});
});
</script>

</body>
</html>

about.php

<?php include("header.inc"); ?>

<!DOCTYPE HTML>

<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="description" content="">
<meta name="description" content="">

<title>Cookies Test</title>

<!-- scripts -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<style type="text/css">

* {
margin: 0;
padding: 0;
}

#info_bar {
width: 100%;
text-align: center;
padding: 10px 0;
background-color: #ecffa1;
color: #666;
margin-bottom: 80px;
}

</style>

</head>
<body>

<?php if ($info_bar) {
if ($_COOKIE["InfoBar"] !== $info_bar) { ?>
<div id="info_bar">
<div class="container">
<?php echo $info_bar; ?>
<a class="close" href="javascript:void(0)">x</a>
</div>
</div>
<?php }
} ?>

<h1>My Cookie Test site!</h1>
<h2>About page</h2>

<h3><?php echo $out; ?></h3>
<h3>Field contents: <?php echo $info_bar; ?></h3>
<h3>Cookie contents on last reload: <?php echo $_COOKIE["InfoBar"]; ?></h3>

<a href="index.php">Homepage</a>

<script type="text/javascript">
$(document).ready(function() {
$("#info_bar a.close").click(function() {
$("#info_bar").slideUp(100);
});
});
</script>

</body>
</html>

I made two different pages just in case it was a problem when going from one page to the next but the code seems to work fine.

Link to comment
Share on other sites

The best way to debug cookies is to watch them in your browser inspector. In Chrome thats View > Developer Tools > Resources > Cookies. In Firefox, FireBug makes it easily to track them as well. Locate the cookie and then keep your eye on the window and watch what changes it goes through as you navigate between pages.

Another thing to double check is that you don't have any output occurring before your setcookie(). That could very well prevent the cookie from being set. Even a little PHP notice that you didn't know was there could screw it up. So view the source on your page and see if you've got any error messages appearing above your <doctype>.

Link to comment
Share on other sites

Hmmm, think I have it.

Got the feeling it was to do with the path part of setcookie, Ryan's tip to have a look in Chrome was a good one, the path was getting set for that page only and just specifying "/" didn't work, I had to add null to the domain part as am on localhost

setcookie("InfoBar", $info_bar, time()+3600, "/", null);
  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...