How can I swap a div based on a cookie using Javascript? - javascript

I'm updating a wordpress site for a customer. I've had to turn on server side caching because the site is so slow due to so many plugins. There is nothing I can do about this and can't disable the plugins.
One of the plugins requires the user to enter an email to download a file. If the plugin sees a valid email, it sets a session variable. Then the page reloads. If that session variable is set, the site displays a download button rather than the enter email form field and button.
Since server side caching is enabled, this functionality is lost. So, what I want to do is set a cookie instead, then check that cookie client side, and swap the content of the div ( id="download" ). I don't do much with Javascript and am having trouble getting this working.
I've set the cookie like this in PHP:
setcookie( 'show_download', 1 );
I've set the new content of the div ( dynamically generated ) like this:
setcookie( 'new_content', '<div class="btn-ss-downloads"><a target="_blank" href="/wp-content/plugins/ss-downloads/services/getfile.php?file=4v-zR6fc6f/9vaROBr/dTJd/Tg/D 0-dT.vBx">Download Series 20 Datasheet</a></div>' );
I've got a function to read the cookie in Javascript that I got from another post:
<script type="text/javascript">
function readCookie(name) {
var ca = document.cookie.split(';');
var nameEQ = name + "=";
for(var i=0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1, c.length); //delete spaces
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return "";
}
</script>
The functionality that seems correct is to call readCookie( 'show_download' );. If the value = 1, swap the content of <div id="download"></div> with the content stored in the new_content cookie.
How do I make this work in Javascript given the pieces I have presented here? I'd like to just add a javascript function to my Wordpress header if that will work here. It seems that I could just run this function after the page has rendered / loaded. I'm not terribly familiar with the order of operations with the browser and javascript. Please help.

Is this what you're looking for?
(<head>)
<script type='text/javascript'>
var showDownload = localStorage.getItem("showDownload") //or readCookie()
if (showDownload == 1) {
$(document).ready(function(){
$("div.btn-ss-downloads").html("<a target='_blank'...</a>")
)};
}
</script>
(</head>)
See http://api.jquery.com/html/ and https://developer.mozilla.org/en/DOM/Storage#localStorage
This uses jQuery, which you can include using:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
(This is one of the few times I'd advocate using jQuery for something so simple, because $(document).ready is so nice!)

Why are you not considering AJAX?
If the requirement is to check validity of an address and then do certain server actions to display a button back, it looks like a good place to use AJAX.
$.post("downloader.php", { eml: mail_id })
.done(function(data){
if(data != "")
$("div.btn-ss-downloads").html('Download');
});
This assumes the downloader.php does the necessary checks and returns the download URL. You can separate this logic (which seems to be part of the main page now) into downloader.php

Related

Issue with GTM and firing Facebook Pixel in a cross-domain setup

I am trying to track Facebook ad results using the Facebook Pixel during appropriate events (page views, lead generation, order form view, purchase). I can do all of this for GA using GTM with no problem, but on Facebook I only have partial success.
The main issue is I have a cross domain setup as shown below:
domain1.com/offer - landing page (FB Page View Pixel should fire)
domain1.com/ordergate - request email before showing order form page (FB Page View Pixel should fire)
crm.com/formsubmission - the actual form submits to my crm (FB Lead Pixel should fire)
crm.com/orderform - order form (FB order form view pixel should fire)
domain1.com/thankyou - the thank you page (FB order pixel should fire)
So my trigger on GTM to fire FB pixel was the "referrer" containing "facebook". However, because of the multi-step process, the referrer is lost by the time the order form or sale is completed.
I have since then learned I need to do the following:
User lands from facebook, write cookie with an appropriately short expiration time that stores this information on domaiin1.com.
When the user clicks a link and is redirected to crm.com, check if the user has the cookie, and if they do, add something like ?reffacebook=true to the redirect URL.
On crm.com, if the URL has ?reffacebook=true write the same cookie you wrote on (1) with an equally short expiration time.
UPDATE
So I have figured out step 2 using the following script on page view when the Facebook cookie is set:
function updateLinks(parameter, value)
{
var links = document.getElementsByTagName('a');
var includeDomains = self.location.host;
for (var i=0;i<links.length;i++)
{
if(links[i].href != "#" && links[i].href != "/" && links[i].href != "" && links[i].href != window.location) //Ignore links with empty src attribute, linking to site root, or anchor tags (#)
{
var updateLink = true;
if(links[i].href.toLowerCase().indexOf(includeDomains.toLowerCase()) != -1) //Domain of current link is included i the includeDomains array. Update Required...
{
updateLink = false;
}
if(!updateLink)
{
//Do nothing - link is internal
}
else
{
var queryStringComplete = "";
var paramCount = 0;
var linkParts = links[i].href.split("?");
if(linkParts.length > 1) // Has Query String Params
{
queryStringComplete = "?";
var fullQString = linkParts[1];
var paramArray = fullQString.split("&");
var found = false;
for (j=0;j<paramArray.length;j++)
{
var currentParameter = paramArray[j].split("=");
if(paramCount > 0)
queryStringComplete = queryStringComplete + "&";
if(currentParameter[0] == parameter) //Parameter exists in url, refresh value
{
queryStringComplete = queryStringComplete + parameter + "=" + value;
found = true;
}
else
{
queryStringComplete = queryStringComplete + paramArray[j]; //Not related parameter - re-include in url
}
paramCount++;
}
if(!found) //Add new param to end of query string
queryStringComplete = queryStringComplete + "&" + parameter + "=" + value;
}
else
{
queryStringComplete = "?" + parameter + "=" + value;
}
links[i].href = links[i].href.split("?")[0] + queryStringComplete;
}
}
else
{
//Do nothing
}
}
}
So with this code I can now properly attribute people with the facebook referral across domains...
...but I still have a problem with form submits.
So when the contact gets to step 4, it is a redirect from the form submission. It does not carry any cookie or query string, so neither of the FB pixels (order form view or order) is being fired.
I'm not sure how I would handle this. My first thought is to pass a hidden field into the form submission (say reffacebook=true). Then somehow expose that in the url in a form of a query string so that it can be detected by GTM.
This seems to be somewhat complicated though, as I would have to edit all my forms to have this variable, edit my CRM so it knows to receive it, and then edit the form landing page to expose that variable in the url.
Hey I hope that I understood what is this all about. Here you want to track traffic between cross domains right? I am not into any coding or anything like that to achieve such a tracking. Because I don't know any coding seriously (I apologies my self for not even trying to learn. I realize my self is that knowing Java script have a lot of benefits in advanced marketing). Ok Here is my point. If we want to track traffic between domains and retarget them later, wouldn't it be done by Facebook itself just by using the same pixel in both domains? This is what I used to believe in the case of multiple domains while doing Facebook ads. Here the important Thing is the audience should be the same from domain A to domain B (In your case it looks like yes the audience is same there for there is no issue for doing that I think). But not sure whether Facebook will track the traffic between domains successfully or not just by placing same FB Pixel in both domains.
Thank you.
#SalihKp, I think you have a point however the issue is that i believe facebook does cross domain with third party cookies which are not working optimally now adays
#David Avellan actually since the user returns to the landing domain for the thank you page, then the final conversion should work using 1st party cookies, but what you want in between might be an issue.
i am looking at now a case where they user lands on a.com and convert

JavaScript modifying a variable in one file and reading it in another

Is there any way to modify a global var within a function and then using it in another page? Let me explain better my situation: I have two HTML files, "Index.html" and "character.html". In Index, I have related this JS code:
var pcharacter = "initialValue";
document.getElementById("barbarianClass").onclick = function(event){
event.preventDefault();
pcharacter = "barbarian"; // the important line here...
location.href = "pages/character.html";
}
The element "barbarianClass" is a link, that's why I blocked the default behavior with preventDefault() until I have given a value to my pcharacter var. Now, I have character.html, that has the following one single JS line code attached:
alert(pcharacter);
In character.html, I have both JS files related, how it should be done:
<script type="text/javascript" src="indexCode.js"></script>
<script type="text/javascript" src="charsCode.js"></script>
The problem is that when I click the link "barbarianClass" and my character.html page shows, the var pcharacter showed in the alert is "initialValue", even when I said it to have the value "barbarian" inside the event attached to the link before opening the page. Of course, I have plans for that variable, but for the question, the alert is easier. Could someone, please, tell me why the initialValue is kept? Is there any obscure rule in JS that says that when you load a JS document, global vars can't be changed anymore or something like that? I doesn't make any sense...
Ummmmmmm...well....banking problems aside :-)
To answer your question - the answer is both yes and no. If what you are going to do is to directly load in a new web page then no - your global variables will disappear like cotton candy at a carny show.
BUT! If instead, you use jQuery's getScript() function, then you can load in a new web page and keep your global variables. All you have to do is to convert your incoming web page into hexadecimal so all of the different letters like the less than sign, single, and double quotes don't muck things up, unconvert it once you have it, and then replace your web page or insert your web page/part as you wish.
To convert it to hex all you need is the bin2hex() function in PHP. To unhex something in Javascript you can go and get my toHex() and fromHex() functions on GitHub.
Also, you might want to think about sending everything back to the server in hex as well so script kiddies have a bit harder time giving themselves a +1000 weapon. Just a thought. It won't slow them down a lot - but every little bit helps. :-)
You can save data in cookie
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;
}
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 "";
}
http://www.w3schools.com/js/js_cookies.asp
your code will be
/*save data*/
document.getElementById("barbarianClass").onclick = function(event){
event.preventDefault();
setCookie('pcharacter', 'barbarian', 1)
location.href = "pages/character.html";
}
/*get data*/
alert(getCookie('pcharacter'));
What you are trying to do is simply not possible with variables alone , as for the reason highlighted by someone in your comments
Lets assume this is possible - would you want the page that has your bank details being accessed via javascript variables on a different page?
You should use cookies (client-side) or sessions(server-side) to accomplish this task. This is how you set a cookie in javascript:
document.cookie = "pcharacter=barbarian"
and then you can access this cookie in all other pages by this simple function :
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 "";
}
console.log(getCookie("pcharacter"));
You can also set an expiry time for your cookies .
You can use localStorage to pass data from one file to another. The basic syntax is:
if (typeof(Storage) !== "undefined") {
// Code for localStorage/sessionStorage.
} else {
// Sorry! No Web Storage support..
}
Setting a value:
localStorage.setItem('myObj', 'My Object');
And getting a value:
localStorage.getItem('myObj');
If localStorage is not supported, you can always fall back to one of the cookies or URL rewriting.
otherwise you can use window.name also

pre-select html select option after window.location redirect

I have problem where after the page is redirected, I want the select to have the previously selected option as the selected choice after the page has been redirected.
here I have an onchange for my select which will redirect the user depending on their selection(refresh page basically), however after the page refresh the selected option gets reset and the first option in the list get selected.
$("#reportTypes").change(function () {
var reportTypeID = $(this).val();
var deviceTypeID = $('#hDeviceTypeID').val();
window.location.href = "http://127.0.0.1:6543/new_device/" + deviceTypeID + "/" + reportTypeID;
$('#reportTypes').val(reportTypeID);//tried to select the previous option but this doesn't seem to work
});
How can I get my select to display the chosen option without getting reset after the page load?
This is your second question regarding the same problem and I have a strong feeling you don't have a clear picture of what happens where and when. I wish I could give you a link to some "how the Web works" intro, but unfortunately I don't know any. No offense, just saying...
Very briefly, in the context of a Pyramid app, things happen in the following order:
Browser sends a request to the server, which is basically a blob of text
Pyramid application receives and parses the request, and finds a view function to invoke to handle the request.
The view function does some useful stuff, for example it queries data from database and returns a Python dictionary, which Pyramid then passes to the template engine (Jinja2 in your case)
Template engine uses a template (a text blob) and the data returned by your view function to generate another text blob, which represents your rendered HTML page. That blob is then sent to the browser, along with HTTP headers etc. Note that for Pyramid there's actually no HTML, DOM, JavaScript variables or anything like that. Like any web application, your Pyramid app is just a program to receive text blobs and generate other text blobs in response.
Browser receives the server response and interprets it - for example, it may decide that this is an HTML page with some inline <script /> tags. The browser then renders the HTML, loads images and stylesheets, executes scripts etc.
The moment you click on a link or change window.location (let's ignore various AJAX scenarios for the moment) - the moment you do that, the browser abandons your current page and sends another HTTP request (see #1 above). It then waits for the server response and render a completely new page which has absolutely no "memory of" the previous page. This is why HTTP is called "stateless protocol".
My point is: the moment you do
window.location.href = "http://127.0.0.1:6543/new_device/" + deviceTypeID + "/" + reportTypeID;
it makes absolutely no sense to do
$('#reportTypes').val(reportTypeID);//tried to select the previous option but this doesn't seem to work
because the current page is going to be abandoned, a new text blob will be sent from the server and rendered as a new web page.
Now, after this theoretical background, you can see that one of the options to solve your problem would be to send some parameter to the server which would tell it "please give me the same page only with this new reportTypeID pre-selected".
It looks like you already have access to deviceTypeID and reportTypeID in your view function. Now you need to pass them to the template and use them to render selected="selected" attribute on the option which should be pre-selected. In pseudocode it would look something like
%for report_type in all_report_types:
%if report.id == report_type_id:
<option value="${report_type.id}" selected="selected">${report_type.name}</option>
%else:
<option value="${report_type.id}">${report_type.name}</option>
%endif
%endfor
If you are sending the parameters to the same page as GET request parameters and causing a page reload, then you could use JavaScript to parse the url parameters and then set the dropdown to the specified value upon page load.
Taking the function specified by #BrunoLM here for url param parsing: How can I get query string values in JavaScript?
var urlParams = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
Now we execute this function upon page load to grab the values:
//$(function {}); is a shorthand for $(document).ready(function() {});
$(function() {
//execute this code to grab the url params
var urlParams = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
//now we check to see if the parameter was passed and if so, set the dropdown value
if (urlParams['reportTypeId']) {
$('#reportTypes').val(urlParams['reportTypeId']);
}
});
This all assumes that you pass an HTTP GET parameter called reportTypeId like so: "reportTypeId=203"

Re-Direct with document.url.match

My goal is to redirect my website to (/2012/index.php)
ONLY IF the user goes to ( http://www.neonblackmag.com )
ELSE IF
the user goes to ( http://neonblackmag.com.s73231.gridserver.com ) they will not be re-directed... ( this way i can still work on my website and view it from this url ( the temp url )
I have tried the following script and variations, i have been unsuccessful in getting this to work thus far....
<script language="javascript">
if (document.URL.match("http://www.neonblackmag.com/")); {
location.replace("http://www.neonblackmag.com/2012"); }
</script>
This should work:
<script type="text/javascript">
if(location.href.match(/www.neonblackmag.com/)){
location.replace("http://www.neonblackmag.com/2012");
}
</script>
You should use regular expression as an argument of match (if you're not using https you can drop match for http://...
In your solution the semicolon after if should be removed - and I think that's it, mine is using location.href instead of document.URL.
You can also match subfolders using location.href.match(/www.neonblackmag.com\/subfolder/) etc
Cheers
G.
document.url doesn't appear to be settable, afaict. You probably want window.location
<script type="text/javascript">
if (window.location.hostname === "www.neonblackmag.com") {
window.location.pathname = '/2012';
}
</script>
(Don't use language="javascript". It's deprecated.)
Anyone at any time can disable JavaScript and continue viewing your site. There are better ways to do this, mostly on the server side.
To directly answer your questions, this code will do what you want. Here's a fiddle for it.
var the_url = window.location.href;
document.write(the_url);
// This is our pretend URL
// Remove this next line in production
var the_url = 'http://www.neonblackmag.com/';
if (the_url.indexOf('http://www.neonblackmag.com/') !== -1)
window.location.href = 'http://www.neonblackmag.com/2012/index.php';
else
alert('Welcome');
As I said, this can be easily bypassed. It'd be enough to stop a person who can check email and do basic Google searches.
On the server side is where you really have power. In your PHP code you can limit requests to only coming from your IP, or only any other variable factor, and no one can get in. If you don't like the request, send them somewhere else instead of giving them the page.
header('Location: /2012/index.php'); // PHP code for a redirect
There are plenty of other ways to do it, but this is one of the simpler. Others include, redirecting the entire domain, or creating a test sub domain and only allow requests to that.

How to detect external urls using Javascript

My objective is simple, I'm kind of surprised that i can't find an answer to this in other posts, i apologize in advance if i missed it....
I have a textarea input. I want to make sure users don't post links to external sites.
I prefer to do this client side and simply prevent submission if external link is present.
I have seen numerous posts on how to find urls and make them into href's. I suppose i can use the same logic to simply remove them, but that will not prevent the users from proceeding, what i want to do is specifically stop them for submitting if external links are present.
I also need to allow for links within the same domain, so the actual url of detected links must be compared as well. I've seen ways to do this once i have the url in a string on its own, but right now, it is somwhere in the middle of a parapraph of text.
<script type="text/javascript">
function validate() {
var noExternalURLs = true;
var currentDomain = window.location.protocol + '//' + window.location.host;
var links = new Array();
var re = new RegExp('^'+currentDomain,"gi");
// Get protocol & domain of URLs in text
links = document.getElementById('mytextbox').value.match(/(https?:\/\/[\w\d.-]+)/gi);
// Loop over links. If protocol & domain in URL doesn't match current protocol & domain then flag
for(var i=0; i<links.length; i++)
{
if( links[i].match(re) == null )
{
noExternalURLs = false;
}
}
return noExternalURLs; // prevent submit if noExternalURLs==false
}
</script>
<form id="myform" action="index.php" onsubmit="return validate();">
<textarea id="mytextbox"></textarea>
<input type="submit" />
</form>
Do not do this client side only. You must check server side too. Client side checks are only for improving the user experience. Any business logic MUST be handled on he server side.
It is trivial to do this as post or get:
http://url.com?textareainput=http://urltoverybadsite
You can make it nicer for your users by doing a quick regex:
<script>
function checkLinks()
{
var links = document.getElementById('textareainput').value.match("/http:\/\//")
if (!links)
{
window.alert("Links not allowed!")
return false;
}
return true;
}
</script>
<form onsubmit="checkLinks()"><textarea id='textareainput'></textarea></form>

Categories