I have a cookie that is being set by this function (page calendar.html):
function bookit(id){
document.cookie='eventid' + "=" + id;
document.location.href ="/sys/account.php";
}
After that the users is redirected to account.php so he can sign in and the id is used on that page and this is what I have on account.php:
function getCookieValue(key)
{
currentcookie = document.cookie;
if (currentcookie.length > 0)
{
firstidx = currentcookie.indexOf(key + "=");
if (firstidx != -1)
{
firstidx = firstidx + key.length + 1;
lastidx = currentcookie.indexOf(";",firstidx);
if (lastidx == -1)
{
lastidx = currentcookie.length;
}
return unescape(currentcookie.substring(firstidx, lastidx));
}
}
return "";
}
alert(getCookieValue("eventid"));
well the dilemma is : when I refresh calendar.html the alert returns 51 for example which is the value of that event, BUT when i refresh account.php it says: NULL
I have tried a jquery cookie plugin, same results so I went back to basic javascript, its driving me insane at this point I dont understand how to pass that value.
I figured using cookies would be the right method - but its not working.any suggestions please? I have a javascript debugger my code has no errors.
Related
I am trying to show a popup on mobile devices, only when the user has first visited a page on my web site. I tried doing this with document.referrer, similar to this. But it does not appear to work on the production site due to it using SSL.
Should I set a cookie when the visitor first comes to the site? Then check for it on subsequent visits? Any ideas? The end result is I need to set a config variable in the popup's javascript config, so that showonmobile: true or false.
I ended up using a cookie to solve this and it is working well:
function setCookie(key, value, expiry) {
var expires = new Date();
expires.setTime(expires.getTime() + (expiry * 60 * 60 * 1000));
document.cookie = key + '=' + value + ';expires=' + expires.toUTCString();
}
function getCookie(key) {
var keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
}
function onSiteAlready() {
if (getCookie('onSite') == 'true') {
return true;
}
else {
setCookie('onSite', 'true', 1)
return false;
}
}
// popup code
showOnMobile: onSiteAlready()
I'm having really strange problems with my code using localStorage...
I would post code either here or in jsfiddle but for it to work I need a bunch of resources and for some reason won't display correctly on jsfiddle.
For an example, you can view the webpage I have it hosted at: http://spedwards.cz.cc/new.html
When you check one (can be any value but lets say 1 for this purpose) of the checkboxes for any hero, click Generate (in the last section) and hit refresh, all of the heroes have their activity checked even though only the one that was checked prior to the refresh should remain checked.
When checking localStorage in the console, only the checked one will have true and all the others will be on false as well which makes it weird. If someone can explain why it's doing this and/or explain an error that I've obviously missed.
Below I will post some of the functions.
Storing everything:
function storage() {
var username = $('#username').val();
var password = $('#password').val();
if (typeof(Storage) != "undefined") {
// Store user's data
window.localStorage.setItem("username", username);
window.localStorage.setItem("password", password);
$.each(heroes, function(index,value){
window.localStorage.setItem("heroActive" + index, $('input#isActive' + index).is(':checked') );
window.localStorage.setItem("heroLevel" + index, $('input#level' + index).val() );
window.localStorage.setItem("heroPrestige" + index, $('input#prestige' + index).val() );
});
} else {
// Browser doesn't support
alertify.alert('<b>Your browser does not support WebStorage</b>');
}
}
Loading the values:
var username, password;
username = localStorage.getItem('username');
$('#username').val(username);
$.each(heroes, function(index,value){
if( localStorage.getItem('heroActive' + index) ){
$('input#isActive' + index).attr('checked', localStorage.getItem('heroActive' + index) );
} else {
$('input#isActive' + index).removeAttr('checked');
}
$('input#level' + index).val( localStorage.getItem('heroLevel' + index) );
$('input#prestige' + index).val( localStorage.getItem('heroPrestige' + index) );
});
The list that is causing problems:
var heroes = ["Black Panther","Black Widow","Cable","Captain America","Colossus","Cyclops","Daredevil","Deadpool",/*"Doctor Strange",*/"Emma Frost",
"Gambit","Ghost Rider","Hawkeye","Hulk","Human Torch","Iron Man","Jean Grey",/*"Juggernaut",*/"Loki","Luke Cage",/*"Magneto","Moon Knight",*/"Ms Marvel",
"Nightcrawler",/*"Nova","Psylocke",*/"Punisher","Rocket Raccoon",/*"Silver Surfer",*/"Scarlet Witch","Spider-Man","Squirrel Girl",/*"Star-Lord",*/"Storm",
/*"Sue Storm",*/"Thing","Thor","Wolverine"/*,"Venom"*/];
Additionally, the last entry (Wolverine) doesn't seem to be functioning correctly. For a starter clicking the label for its activity doesn't trigger the checkbox whereas all the others do. Other problems with this entry:
Doesn't trigger my errors.js file at all
errors.js:
$.each(heroes, function(index,value){
$('input#level' + index).change(function() {
var numbers = /^[0-9]+$/;
var val = $('input#level' + index).val();
if(val > 60) {
alertify.log("Hero " + value + " cannot be above Level 60!", "", 0);
$('#level' + index).addClass('error');
} else if( isNumeric(val) ) {
if( $('#level' + index).hasClass('error') ) {
$('#level' + index).removeClass('error');
}
} else {
alertify.log("Only numbers are accepted.");
$('#level' + index).addClass('error');
}
});
});
function isNumeric(num){
return !isNaN(num);
}
Anything stored in local storage returns as a string.
So if you stored fooo = false in local storage,
if(!fooo){
bar();
}
will never execute bar();
if(fooo){
bar();
}
will always execute bar(), since a string always is true, since the variable is not empty or false.
I've banged my head against this once as well. Kinda stupid, but hey. :)
I'm going to try to explain this as best I can, please feel free to ask for clarifications as required.
Using IE10, CRM Online with RU12.
I am playing about with subgrids and getting them to refresh. Consider the following script, which I have nicked wholesale from MSDN (and wrapped in a try/catch block)
function start() {
try {
var controls = Xrm.Page.ui.controls.get(isSubGrid);
if (controls.length > 0) {
var subGridNames = "";
for (var i in controls) {
controls[i].refresh();
subGridNames += (" - " + controls[i].getName() + "\n");
}
alert("The following subgrids were refreshed: \n" + subGridNames);
}
else {
alert("There are no subgrid controls on the current form.");
}
}
catch (ex) {
alert(ex);
}
}
function isSubGrid (control)
{
return control.getControlType() == "subgrid";
}
Nothing special going on there - get all controls of type subgrid (this returns 10 elements as expected) and call refresh() on them.
However this is consistently failing on the first call to refresh().
The exception details is fairly straightforward
TypeError: Unable to get property 'Refresh' of undefined or null reference
Which suggests that the control[i] is null when called in the loop at this point here
for (var i in controls) {
controls[i].refresh();//error thrown here - suggests controls[i] is null
subGridNames += (" - " + controls[i].getName() + "\n");
}
However I can see that it isn't null (and has the method refresh as expected).
I can make it work by using setInterval
function waitAndThenRefresh(gridname) {
var grid = Xrm.Page.ui.controls.get(gridname);
var intervalId = setInterval(function () {
if (grid === null || grid._control === null || grid._control._element === null) {
return;
}
if (grid._control._element.readyState === 'complete') {
window.clearInterval(intervalId);
if (grid != null) {
grid.refresh();
}
}
}, 1000);
}
But that is pretty hideous, not to mention does not explain with the SDK call doesn't work as expected.
So I guess the question is: has anyone else seen this issue? Or can you replicate it on another instance? Am I missing something? There is nothing in the SDK that suggests you need to defer calling refresh until the inner control's readyState is complete?
The code block you are using,
for (var i in controls) {
controls[i].refresh();
subGridNames += (" - " + controls[i].getName() + "\n");
}
should be replaced with the following:
for (var i in controls) {
i.refresh();
subGridNames += (" - " + i.getName() + "\n");
}
or:
for (var i = 0; i < controls.length; i++) {
controls[i].refresh();
subGridNames += (" - " + controls[i].getName() + "\n");
}
You are getting the exception because controls[i] is undefined in your case, i being the control (the element of the array controls).
I asked a CRM-buddy of mine. He said that the issue depends on the new refreshment Engine. According to him, it's sort of a bug but not really. If I got it right, the refresh has been reengineered to accommodate the new perpetual saving functionality.
I have the following to try to reload on a connection drop:
setInterval(window.location.reload(), 1000);
My concern with this is that it could continue forever, ddos'ing my application.
How can I update the above to try at max 20 times before giving up and breaking?
Thank you
This makes me feel dirty, but you could update/extract the window hash with each refresh:
function hack () {
var last = parseInt(location.hash.slice(1));
if (last < 20) {
window.location.hash = last + 1;
window.location.reload();
}
}
window.location.hash = 0;
setTimeout(hack, 1000);
You need to persist some counter state from one page load to the next so you can know when 20 reloads have been done. Your options are:
A hash value
A query parameter
A cookie value
Something stored in local storage
If you don't need this value to persist beyond just the reloads of this page, then options 1) and 2) are better as they are only as persistent as you need. A hash value will not be sent to your server, but could interfere with other uses of the hash value. A query parameter would be sent to the server, but any reasonable server will ignore query values it doesn't know and it won't interfere with anything else. I'd probably pick a query parameter and have actually used one to avoid infinite redirection loops in some of my code. You could implement option 2) like this:
function checkAutoReload() {
var currentCnt = 0;
var re = /(\?|&)(reloadCnt=)(\d+)/;
var param = window.location.search.match(re), newURL;
if (param) {
currentCnt = parseInt(param[3], 10);
newURL = window.location.href.replace(re, "$1$2" + (currentCnt + 1))
} else {
newURL = window.location.href;
newURL += window.location.search ? "&" : "?";
newURL += "reloadCnt=1";
}
if (currentCnt < 20) {
window.location.replace(newURL);
}
}
setTimeout(checkAutoReload, 1000);
Notice, there's no need for a setInterval() because a given page's code only runs once before it either reloads or finds that it is done reloading.
Store the reloadCount in localStorage
MDN DOM Storage
var maxReload = 20;
var reloadPage = function() {
if (typeof a !== "undefined" && a !== null) {
console.log(localStorage.reloadCount);
localStorage.reloadCount = 0;
};
var reloadCount = parseInt(localStorage.reloadCount, 10);
console.log(reloadCount);
if (reloadCount < maxReload) {
reloadCount += 1;
localStorage.reloadCount = reloadCount;
// RELOAD CODE HERE
};
};
// call reloadPage from your code
reloadPage();
I am trying to make a bookmarklet that when clicked will check the URL of the current tab/window to see if it contains 'char1' and/or 'char2' (a given character). If both chars are present it redirects to another URL, for the other two it will append the current URL respectively.
I believe there must be a more elegant way of stating this than the following (which has so far worked perfectly for me) but I don't have great knowledge of Javascript. My (unwieldy & repetitive) working code (apologies):
if (window.location.href.indexOf('char1') != -1 &&
window.location.href.indexOf('char2') != -1)
{
window.location="https://website.com/";
}
else if (window.location.href.indexOf('char1') != -1)
{
window.location.assign(window.location.href += 'append1');
}
else if (window.location.href.indexOf('char2') != -1)
{
window.location.assign(window.location.href += 'append2');
}
Does exactly what I need it to but, well... not very graceful to say the least.
Is there a simpler way to do this, perhaps with vars or a pseudo-object? Or better code?
A (sort-of) refactoring of dthorpe's suggestion:
var hasC1 = window.location.href.indexOf('char1')!=-1
var hasC2 = window.location.href.indexOf('char2')!=-1
var newLoc = hasC1
? hasC2 ? "https://website.com/" : window.location.href+'append1'
: hasC2 ? window.location.href+'append1' : '';
if (newLoc)
window.location = newLoc;
Calling assign is the same as assigning a value to window.location, you were doing both with the addition assignment += operator in the method anyway:
window.location.assign(window.location.href+='append2')
This would actually assign "append2" to the end of window.location.href before calling the assign method, making it redundant.
You could also reduce DOM lookups by setting window.location to a var.
The only reduction I can see is to pull out the redundant indexof calls into vars and then test the vars. It's not going to make any appreciable difference in performance though.
var hasChar1 = window.location.href.indexOf('char1') != -1;
var hasChar2 = window.location.href.indexOf('char2') != -1;
if (hasChar1)
{
if (hasChar2)
{
window.location="https://website.com/";
}
else
{
window.location.assign(window.location.href+='append1');
}
}
else if (hasChar2)
{
window.location.assign(window.location.href+='append2');
}
Kind of extendable code. Am i crazy?
var loc = window.location.href;
var arr = [{
url: "https://website.com/",
chars: ["char1", "char2"]
}, {
url: loc + "append1",
chars: ["char1"]
}, {
url: loc + "append2",
chars: ["char2"]
}];
function containsChars(str, chars)
{
var contains = true;
for(index in chars) {
if(str.indexOf(chars[index]) == -1) {
contains = false;
break;
}
}
return contains;
}
for(index in arr) {
var item = arr[index];
if(containsChars(loc, item.chars)) {
window.location.href = item.url;
break;
}
}
var location =window.location.href
if (location.indexOf('char1')!=-1 && location.indexOf('char2')!=-1)
{window.location="https://website.com/";}
else if (location.href.indexOf('char1')!=-1) {window.location.assign(location+='append1');}
else if (location.indexOf('char2')!=-1) {window.location.assign(location+='append2');}