I have a simple JavaScript file which takes care of the translation on the page. So if user wants to see a page in e.g. English, he clicks on it and the page translates itself. Everything works great except when user goes to another page.
Now my JavaScript is re-loaded again, and default language kicks in. Which is undesirable - I want my JavaScript to remember what language user has specified.
Here is my JavaScript code to show what I am doing
//translations
var language = "en";
$(function () {
translatePage();
$("#PageLanguages li").on("click", function (attr) {
var selLang = $(this).data("language");
if (selLang) {
language = selLang;
}
translatePage();
});
function translatePage() {
$.ajax({
url: 'languages.xml',
success: function (xml) {
$(xml).find('translation').each(function () {
var id = $(this).attr('id');
var text = $(this).find(language).text();
$("#" + id).text(text);
});
},
error: function (err) {
var x = err;
}
});
};
});
As you can see, I am storing language (the one user has specified) in my language variable at the top.
What do I need to do, when I would like to website to share a variable among all pages (such as in this case) ?
My advice here is browser based , using local storage with the modern browsers
localStorage.setItem('language', 'eng');
// Retrieve the object from storage
var retrievedLanguage = localStorage.getItem('language');
console.log(retrievedLanguage); /// prints eng
If target browsers are html5 compliant , try local storage :
//set data
localStorage.setItem("language", language);
// get data
var language = localStorage.getItem("language");
will be available for all pages.
There are several ways you can go about doing this. But I'll list just three. If you want the JavaScript approach (which relies on JavaScript being enabled/supported by the browser):
var language = localStorage.getItem("language") || "";
if(language !== "")
{
// Set the language for content in here
}
else
{
// Store the language in LocalStorage here.
localStorage.setItem("language", "en-us");
}
Alternatively, you could store stuff like this in your Database (server-side), but I would advise against storing such things in your own database unless you absolutely need to ensure that value will exist when you need it.
Another option is appending something like language=en-us to your query string when they click on a hyperlink or button. And you could then use JavaScript or a server-side language on the next page to get this data from the query string.
There is different way to keep the language variable in all pages.
1) Use the language string in URL itself ex :
https://www.paypal.com/ar/webapps/mpp/home
2) Call server to know the language.
3) Store in cookie as specified by uzaif
4) Using localStorage
Related
I'm working on a client's website and they want it to be bilangual. It's based on wordpress and I purchase WPML plugin. Now, I want to add a language switch button but I can't do this while still being able to customize and insert it wherever I want so I came up with a solution:
The page render with content translated only when the url meet the parameter "?lang=en" so if the url is "www.website.com/page" it will be normally rendered and if the url is "www.website.com/page?lang=en" it's content will be in english.
I came up with the solution of make the custom switch buttons with the href according to this scheme. However, once he choose a language I want it to maintain while browsing through the website.
Now, how can I make the website to work in that way that if his current page containt "?lang=en" in url, when he access another page to pass this parameter? So far, I was able to check if a page containt this parameter and now I don't know how to pass it (I'm talking of doing that in javascript with jquery).
Storing it in a session variable would probably be best but since you asked you can parse the query string generically like below. If you have anything after the # you may want to split() that off as well (queryStr = queryStr.split('#')[0];).
function parseQuery(url) {
var queryStr = url ? url.split('?')[1] : location.search.slice(1),
query = {};
if (queryStr !== '') {
var params = queryStr.split('&');
for (var i = 0; i < params.length; i++) {
var param = params[i].split('=');
query[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || '');
}
}
return query;
}
For a website I am working on, I am trying to keep information on how many items you buy to be shown across html pages. Researching how to do this has led me to believe that Html sessionStorage is the best way to do this (if there is a better/easier way please let me know). Yet, whenever I refresh the html page or go to another page the data resets.
Here is my code:
function initialize(name, val) {
if(localStorage.getItem(name) === null) {
localStorage.setItem(name, val);
}
}
initialize("subCost", 0);
initialize("quantity", 0);
initialize("hasProduct", false);
Then since the storage only stores strings, I convert these into integers and boolean
var $quantity = parseInt(localStorage.quantity);
var $subCost = parseInt(localStorage.subCost);
var $hasProduct = localStorage.hasProduct == "true";
Before without the initialize function, I made the local storages items like this
localStorage.setItem("subCost", 0);
localStorage.setItem("quantity", 0);
localStorage.setItem("hasProduct", false);
and still converted these into those variable but they never saved with each refresh. How do I get these to save changes I make to them with each refresh.
The .setItem() method on localStorage doesn't only "sets" a "memory placeholder" for a value... It also overwrites it, if it already exist.
To save the user generated values, the best "moment" to save a "change" is the change event.
Use the same .setItem() method as in your initialize() function.
$("input").on("change",function(){
// Get id and value.
var id = $(this).attr("id");
var value = $(this).val();
// Save!
localStorage.setItem(id,value);
});
CodePen
Just as a hint...
This method to save values locally is ephemeral...
Values are kept until user closes the browser.
Not just closing the page, but closing the browser completely.
So to keep some values between pages navigated, this is the optimal use.
To store values for a longer run (like 6 months or longer), use cookies.
Have a look at jQuery Cookie plugin.
I need to be able to retrieve the list of request URLs that are displayed in the browser console, i.e: GET http://mydomain.com/index.php?p=1&curr=GBP&cat=Food. 200. Users can click around my app and apply different filters and scrolls through pages and I need some way of tracking this so that I always know what data has already been loaded for that users session.
I had thought about using PHPs $_SERVER['REQUEST_URI'] and saving them in a session but then I don't know how I would access this session from my JQuery as its JQuery that constructs the URLs.
Has anyone any idea how I can access this data from the console? Is this possible? If not can anyone suggest a workaround?
The PHP / JQuery mess I have so far:
<?php
session_start();
//keep track of requests.
if (!isset($_SESSION['requests'])) {
$_SESSION['requests'] = array();
} else {
if (!in_array( $_SERVER['REQUEST_URI'], $_SESSION['requests'])) {
$_SESSION['requests'][] = $_SERVER['REQUEST_URI'];
}
}
$requests = json_encode($_SESSION['requests']);
print_r($_SESSION['requests']);
print_r($requests); //these both have values
?>
//further down the page is the javascript
$('.filter a').click(function(e) {
var $this = $(this);
var $optionSet = $this.parents('.option-set');
var group = $optionSet.attr('data-filter-group');
filters[ group ] = $this.attr('data-filter-value');
//***more code for filtering etc******/
var paginate_url = $('.paginate a').attr('href');
//THIS IS PART I CANNOT GET WORKING
var visited_urls= <?=$requests?>;
//console.log($.parseJSON(visited_urls));
console.log(visited_urls); //is always empty
var pageno = ''; //somehow check to see if the URL that has been clicked exists int he requests array, if so get the page number and increment.
var next_url = UpdateQueryString(paginate_url, pageno, group, encodeURIComponent(filter_qry));
I'm not completely sure what you're trying to do but I think you can skip the PHP and just use JavaScript and sessionStorage: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#sessionStorage or localStorage: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#localStorage (depending on how persistent you want the data to be)
For example if I want to listen for all clicks on 'a' tags and track whether those hrefs have been visited (and how many times)
$(document).ready(function() {
// store an empty object in session storage when the page loads
sessionStorage.visited = JSON.stringify({});
});
$('a').on('click', function() {
var storage = JSON.parse(sessionStorage.visited),
href = $(this).attr('href');
// when we get a click check to see if this has been clicked before
if (!storage[href]) {
// if not save it and set the count to 1
storage[href] = 1;
} else {
// otherwise increment the count
storage[href]++;
}
sessionStorage.visited = JSON.stringify(storage);
});
If you want to save the urls from your ajax calls the same principle applies but listen for the ajaxSuccess event and store the url from the request in the callback: http://api.jquery.com/ajaxSuccess/
This is my suggestion:
PHP + Javascript Implementation:
In PHP, use $_GET['curr'] and $_GET['cat'] to retrieve the arguements from the URL.
Use $_SESSION['curr'] = $_GET['curr']; to save them per the session.
On your Javascript/jQuery use var curr = "<?php echo $_SESSION['curr']; ?>" to make the PHP session variables available to your Javascript.
Basically the key to have a good PHP/Javascript persistent memory is that you can set PHP content into a Javascript variable by using:
var x = <?php echo '123';?>;
console.log(x); //output '123' to Javascript console
If you need to have a list of all visited urls, you can save them in a PHP array and transfer it to Javascript as well.
On PHP side:
if (!isset($_SESSION['visited'])) $_SESSION['visited'] = array();//initialize the array if doesn't exist
if (!inarray( $_SERVER['REQUEST_URI'], $_SESSION['visited']) { //check if current URL is not in array
$_SESSION['visited'][] = $_SERVER['REQUEST_URI'];//push it to the array
}
On Client side:
//this will convert the PHP array to a Javascript array using json_encode
var visited_urls= <?php echo json_encode($_SESSION['visited']); ?>;
Don't forget to use session_start() on every page you need the session variables.
Javascript Only Implementation:
Use localStorage and keep everything on the client side.
EDIT: Note that localStorage is only supported in IE8 and up, so if versions prior to IE8 must be supported, you will need to use Cookies instead of localStorage.
$(document).ready(function() {
var urls = JSON.parse(localStorage["visited"]) || [];//get the visited urls from local storage or initialize the array
if (urls.indexOf(document.URL) == -1) {//if current url does not exist in the array
urls.push(document.URL);//add it to the array
localStorage["visited"] = JSON.stringify(urls);//save a stringifyed version of the array to local storage
}
});
Hope this helps!
It's unclear what you want to achieve with this feature. You state:
Users can click around my app and apply different filters and scrolls through pages and I need some way of tracking this so that I always know what data has already been loaded for that users session.
What do you want to achieve with this, why isn't the browser's cache enough for you?
My idea for a solution would be to sync server session array with an object inside the Browser via some sort of WebSocket (http://en.wikipedia.org/wiki/WebSocket).
UPDATE2:
It is possible to use localStorage as cache storage as Abel Melquiades Callejo suggests and then read from it bypassing HTTP requests. I would choose what content to save to that cache differently, no server involved:
add a custom attribute data-* to every HTML element you want cached (http://html5doctor.com/html5-custom-data-attributes/);
make a querySelectorAll (https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll) for all HTML elements with that attribute;
storing and retrieving documents from localStorage should be easy now, you need a convention for naming files for easy finding;
storing images implies doing a base64 transformation which increases the size of the data by 34% (image with 64kb will take 86kb in localStorage).
you need a way to find when data in localStorage is obsolete and you need to make requests to the server (perhaps another data-age attribute to specify when should it expire).
However, this localStorage solution is limited to a small amount of data, see this issue https://github.com/RemoteStorage/remoteStorage.js/issues/144. So, although I now see that what you are asking is possible, because of this size limitation to localStorage, I strongly recommend the solutions in my UPDATE1, below.
UPDATE1: The point is that caching mechanisms are incredibly complex. A better alternative would be to use the default browser caching mechanisms:
1. HTML5 cache manifest
Go offline with application cache
http://html5doctor.com/go-offline-with-application-cache/
LET’S TAKE THIS OFFLINE http://diveintohtml5.info/offline.html
Using the application cache
https://developer.mozilla.org/en/docs/HTML/Using_the_application_cache
A Beginner's Guide to Using the Application Cache http://www.html5rocks.com/en/tutorials/appcache/beginner/
2. Server's response headers to HTTP requests
Optimize caching - Leverage browser caching
https://developers.google.com/speed/docs/best-practices/caching#LeverageBrowserCaching
HTTP Caching FAQ https://developer.mozilla.org/en/docs/HTTP_Caching_FAQ
I have an EnhancedGrid that users regularly use complex filters on. Is there a way to allow users to save or bookmark a filter so they can easily re-apply it in future? I know I can programmatically set a filter, but I can't predict what filters my users will want.
Thank you!
edit: made some progress myself... using grid.getFilter() to return a JSON representation of the filter, then json.stringify(jsonRepresentation) to convert it into a string. Now I'm considering my options for how to store, load and convert that string. Would loading a string into a json object then applying it as my filter open me up to XSS vulnerabilities? If I want to have filters specified as arguments in the url, can I compress the string to reduce the character count?
Right off the bat, here are the two three approaches I see:
Store the filter in a URL (Okay)
Simply get the window.location and parse out the query string using dojo/io-query::queryToObject():
require(['dojo/io-query'], function (ioQuery) {
var uri = window.location.href;
var query = uri.substring(uri.indexOf("?") + 1, uri.length);
query = ioQuery.queryToObject(query);
});
(Documentation for dojo/io-query)
Store the filter in a cookie (Better)
The dojo/cookie module makes this very, very easy:
require(['dojo/cookie', 'dojo/json'], function (cookie, json) {
var filter = { ... };
cookie("myFilter", json.stringify(filter)); //store the cookie
// json.parse(cookie("myFilter"));
// ^-- returns the cookie as a JS object
});
(Documentation for dojo/cookie)
Obviously, the user must have cookies enabled for this to work, but it's much cleaner than storing a bunch of variables in a URL for them to bookmark.
Use HTML5 Local Storage as suggested by Dimitri M: (Even better)
Check to see if the user's agent supports Local Storage, and if so, use that global variable to hold on to the filter:
require(['dojo/json'], function(json) {
function supportsLocalStorage() {
return ('localStorage' in window) && window['localStorage'] !== null;
}
var filter = { ... };
if(supportsLocalStorage()) {
localStorage.setItem("myFilter", json.stringify(filter));
}
// json.parse(localStorage.getItem("myFilter"))
// ^-- returns the filter as a JS object
});
An advantage in using web storage is that you can store much more data than cookies can.
You could conceivably use cookies as a fallback for browsers that don't support Local Storage, (i.e. when supportsLocalStorage() returns false) at the cost of adding a touch more overhead to your design, so ultimately it's your call, depending on what browsers you want to support.
Browser Compatibility for Web Storage
How about cookies?
The grid widget has a cookie plugin(link), but id doesn't save the filter. Maybe extending the plugin or the grid could be an option.
Passing the filter properties as string also sounds like an option. Knowing the conditions, and the values that can be used, or their type, you can easily validate the filter before applying it to the grid.
I have this fiddle: http://jsfiddle.net/y8Uju/5/
I am trying to save the numbers, because, when I submit, the list of numbers gets erased. I am a little new to JavaScript so am not quite familiar to what is available. In PHP I would use sessions to save the list, but what can I do in JavaScript to do this?
Here is the JavaScript code:
function bindName() {
var inputNames = document.getElementById("names").getElementsByTagName("input");
for (i = 0; i < inputNames.length; i++) {
inputNames[i].onkeydown = function() {
if (this.value == "") {
setTimeout(deletename(this), 1000);
}
}
}
}
document.getElementById("addName").onclick = function() {
var num1 = document.getElementById("name");
var myRegEx = /^[0-9]{10}$/;
var itemsToTest = num1.value;
if (myRegEx.test(itemsToTest)) {
var form1 = document.getElementById("names");
var nameOfnames = form1.getElementsByClassName("inputNames").length;
var newGuy1 = document.createElement("input");
newGuy1.setAttribute("class", "inputNames");
newGuy1.setAttribute("id", nameOfnames);
newGuy1.setAttribute("type", "text");
newGuy1.setAttribute("value", num1.value);
form1.appendChild(newGuy1);
num1.value = "";
bindName();
}
else {
alert('error');
}
};
function deletename(name) {
if (name.value == "") {
document.getElementById("names").removeChild(name);
}
}
You can use localStorage: http://jsfiddle.net/y8Uju/8/
Loading:
var saved = JSON.parse(localStorage["numbers"] || "[]");
for(var i = 0; i < saved.length; i++) {
document.getElementById("name").value = saved[i];
add(false);
}
Saving:
var saved = JSON.parse(localStorage["numbers"] || "[]");
saved.push(num1.value);
localStorage["numbers"] = JSON.stringify(saved);
And define the function of the addName button separately, so that you can call it when loading as well.
Edit: You have to execute a function when the page is loading to fetch the stored numbers, and add some code to save the entered number when one clicks the Add button.
For storing you can use localStorage, but this only accepts Strings. To convert an array (an array containing the entered numbers), you can use JSON.
When loading, you need to add the numbers just like happens when the user fills them in. So you can set the name input box value to the saved number for each element in the array, and then simulate a click on the Add button.
So you need an add function that is executed when:
User clicks Add button
Page is loaded
However, when simulating the click the numbers should not get stored again. You need to distinguish between a real click and a simulated one. You can accomplish this by adding an argument to the add function which represents whether or not to store.
Not entirely sure what the question is, but one problem I see with the code - id's can't be numbers, or start with numbers
var nameOfnames = form1.getElementsByClassName("inputNames").length;
//....
newGuy1.setAttribute("id", nameOfnames);
That might be slowing you down somewhat. Perhaps set id to 'newguy' + nameOfnames
Jeff, the reason that the page keeps getting erased is because the form submission triggers a page reload. You need to place a listener on the form submit event and then send the data through AJAX. This way the data is POSTed to "text.php" without reloading the page with the form.
You could place the values in a cookie but that is not ideal because you have a fairly limited amount of space to work with (4kb). I also get the feeling that you're trying to hand them off to some server side script so HTML5 local storge wouldnt be a good solution, not to mention that your eliminating over half of the people on the internet from using your site that way.
Since browsers are inconsistent in how they attach event listeners AND how they make AJAX requests. I think that most people would recommend that you use a library like jQuery, dojo, or prototype which abstract the process into one function that works in all browsers. (my personal fav is jQuery)
There are a few options available to you:
Save it client side using cookies (http://www.quirksmode.org/js/cookies.html)
Save it client side using HTML5 local storage (http://diveintohtml5.ep.io/storage.html)
Save it server-side using Ajax
The Ajax solution involves a server side page (in PHP for example) that reads a request (a POST request for example) and saves it into a database or other. You then query that page in JavaScript using XmlHTTPRequest or your favorite library.