Is there a way when Page change location to keep some HTML Element's.
Like a div that will not be re-rendered but keep it's state.
You can find and example like that at Facebook Chat ,you can see that the Chat window does not change it's location or InnerHtml when you navigate to another page.
PS : I have no clue where to start so any documentation would be appreciated.And it would be nice if solution would be XHTML not HTML5
I don't know exactly how facebook chat works, but I do know all chat messages are stored in a database, so you can access them later via messages.
My assumption would be that a Session variable is set letting facebook's UI know what chats you have open, or perhaps its stored in the database as well. In either case, you'd have to use some outside script in order to do this. For sake of ease lets say you'll use PHP, and you'll store the data in a SESSION variable.
/* Storing the variable */
$users = array('user123', 'user456', 'user789');
$_SESSION['chat_windows_open'] = $users;
/* Retrieving the values */
foreach($_SESSION['chat_windows_open'] as $chat) {
/* Use $chat to get the username, query the DB for
the message content, and echo it in whatever form you
wish. */
}
When window.location changes, the page is automaticaly, entirely re-rendered. So, from this point of view, the answer is no. However, this effect can be obtained by using AJAX. Use ajax to make requests to the server while the page does not reload or changes location(window.location is always the same). Here's a good link to start with AJAX:
http://www.w3schools.com/ajax/default.asp
If you still want the page to change it's location, after you've made your ajax request and updated the content on the page, you can use javascript's history.pushState function. However you will have to find a way to make it cross browser(aka. make it work in IE).
Related
I have a website and when a user follows an internal link I would like to pass some extra information to a new page, so JavaScript on the destination page could do some useful highlighting.
There is an option to pass that information via the link parameters (GET), but it will generate lots of virtually duplicate pages and break pretty URLs concept. Another way is to make a webapp using AJAX, but it will also bound content to a single URL.
How can I transparently pass some information to the new page during navigation w/o messing with site's URL structure?
You could store the data in local storage or session storage, and retrieve it again on the destination page.
So you have a few options.
Form Submission
First option post a form with the data. Add a hidden form, on the anchor click capture the click event, set the hidden fields with the values you want to send to the next page, and submit the form. On the next page, read the post parameters in the backend and update the page.
Local Storage
On click of the anchor, set localStorage to the values you want to appear on the next page. When the next page loads, read the localStorage values and update the page. Note: The server will not have access to the values
Ajax with pushState
Use Ajax to submit the form. When the Ajax call returns, use window.history.pushState to update the url with whatever url you want to be displayed to the user.
One of the options not mentioned is to create a dirty URL:
/destination/param1/value1/...
then strip additional parameters at server-side and redirect:
/destination
keeping additional values stored at server-side (e.g. via sessions). I still prefer using sessionStorage in a real application, but it worth mentioning anyway.
What do you mean it will "bind content to a single url"? AJAX request is the first thing that comes to my mind as the solution to this problem. You dont have to use the url of the page to make the ajax request, you can build the url inside your javascript based on whatever conditions exist in your application.
Besides AJAX and passing parameters in the URL, the only other thing I can think of is to use Cookies. That of course runs into problems if the user has cookies disabled. I think an Ajax call to your server is the most robust way of handling the problem.
I've been trying to figure this out on my own, but I can't seem to get it sorted.
I'm building an accessibility section on a client site, and i've got two buttons, the buttons add a class to the body, one is font-size the other is greyscale.
I need these classes to stay on the body until clicked again to remove, as users don't want to have to keep clicking the buttons to be able to see the site.
I want to store these classes with a session or cookie, but having done some reading, sessions store cookies anyway, so whichever is the best option.
I'm using wordpress for the site, so if there's something I can use function wise, that'd be useful to know!
Can anyone help me out?
If you want to use localStorage you can use this code.
// Check if localStorage is supported
if ('localStorage' in window && typeof localStorage == 'object') {
$(document).ready(function() {
// Set the class if greyscale is set
// Note that localStorage saves everything as strings
if (localStorage["greyscale"] == "1") {
$('body').addClass('greyscale');
}
// Register click listener for the button
$('#button').click(function() {
// Toggle greyscale on and off
if (localStorage["greyscale"] != "1") {
$('body').addClass('greyscale');
localStorage["greyscale"] = "1";
}
else {
$('body').removeClass('greyscale');
localStorage["greyscale"] = "0";
}
}); // - button click
}); // - doc ready
}
JSFiddle
Session is usually using cookies but data is stored on server side and cookie is only used to identify it.
Assuming you have no reason to know if user is using gray scale on server side you can do this entirely in JS.
For example using some neat jQuery plugin for cookies https://github.com/carhartl/jquery-cookie
//set cookie and add class on button click
$('#button').click(function(){
$.cookie('greyscale', true);
$('body').addClass('greyscale');
});
//check for cookie on document load
$(function(){
if($.cookie("greyscale")){
$('body').addClass('greyscale');
}
});
Also please have in mind that this cookie will be sent to server and back over and over again so if you don't need this on server side you should use some more modern solution like HTML5 localStorage. There are few libraries that can be used to keep data on client side. They use modern features and fallback to old ones(like cookies) on older browsers. Please check http://pablotron.org/software/persist-js/ for example.
As mentioned in this answer:
The main difference being that session data is stored on the server, while cookie data is stored on the client. Therefore, a client can easily modify the cookie contents, but will have to work way harder to modify the session contents.
There are a couple ways to approach this
1) Keep the information in $_SESSION.
2) Keep the information in cookie.
Based on your case and on the data you want to store (which are not critical), I'd suggest you store it in a cookie and not bother the server to keep track for every user.
You could easily store information in a cookie via javascript.
Here is a javascript cookie reference for you:
http://www.w3schools.com/js/js_cookies.asp
After storing your info inside a cookie you could retrieve the info stored inside a cookie via javascript or php.
Keep in mind:
Javascript = client side (server wont be bothered) & after your dom is ready you will have to add the according class to your body.
PHP = server side, meaning that you wont have to add a class after the dom is ready and print your html with the appropriate class already set on the element.
PHP cookie references:
http://www.w3schools.com/php/php_cookies.asp
http://davidwalsh.name/php-cookies
Store it in a cookie.
Using cookies you can choose when will the cookie expire, when using sessions - when session is destroyed information is lost eg. when user logs off.
User will have to manually delete your cookie to delete the "body class information"
This code toggles the color of an element whenever you click on it. But how can I send a GET request with query string ?toggle=True on the first toggle and ?toggle=False on the second one?
Ow, I can see it appearing in Firebug, but not in the url of the page. Any idea why?
Making a request and changing the URI in the address bar are two different things unless you cause the browser to load a completely new page.
If you want to do that, then you should forget about using client side JavaScript and move your logic server side and use a regular link.
In the server side logic, the value of the query string argument would be used to determine the class of the div (which is used to set the style) and the href of the link (i.e. if it has True or False in the query string).
If you want to avoid loading a new page, then you are looking at two separate steps.
The first one you already have (the changing of the style using JS).
The rest gets more complicated…
First you need server side logic so that True/False in the query string will set up the initial state of the page correctly. This will be the same as the logic described for the previous method.
Then you need to update the URI so that it matches the one that would load the page in the state you are altering the current page into. This is done using the History API (pushState and friends). There are more details on the subject on this question.
If you want to notify the server of the change, then you'll need to use jQuery.get, as well as updating the page and changing the URI in the address bar. To be efficient, you should probably add an additional query string argument (so you can tell if it from Ajax from that a normal page load) and have the server return a simple acknowledgement rather than the whole HTML document when it sees that argument.
Just use jQuery's get method to do so or do it yourself in your toggle functions.
A pragmatic yet pretty basic solution may be to use a local variable as a counter.. If the counter is even, send True, if odd, send False.
Increment counter on each click :)
I have a page that dynamically loads content based on a user pushing a button:
${document).ready(function)
{
$("#myButton").click(function()
{
$("#dynamicDiv").load("www.example.com");
});
}
The dynamic content works fine, I can fetch pages all day long. But after you follow a link to another page, then press the browser back button to come back to the page, the page is completely reset as though no dynamic content had ever been loaded.
I swear I've seen different behavior before, but maybe I'm insane. Shouldn't the browser preserve the state of the page, rather than re-rendering it?
EDIT:
By the way, I'm using Play! framework, if that has any bearing on this.
The browser loads the page as it was first received. Any DOM modifications done via javascript will not be preserved.
If you want to preserve the modifications you will have to do some extra work. After you modify the DOM, update the url hash with an identifier that you can later parse and recreate the modification. Whenever the page is loaded you need to check for the presence of a hash and do the DOM modifications based on the identifier.
For example if you are displaying user information dynamically. Every time you display one you would change the url hash to something like this: "#/user/john". Whenever the page loads you need to check if the hash exists (window.location.hash), parse it, and load the user information.
Implementing browser back functionality is hard.
It gets easier when you use a plugin like jquery.history.js.
http://tkyk.github.com/jquery-history-plugin/
A technique I use for this is to serialize state to JSON, store it in the hash string, and then read it back when the page is navigated back to. This has been tested in IE10+, Firefox, Chrome.
Example:
// On state change or at least before navigating away from the page, serialize and encode the state
// data you want to retain into the hash string
window.location.hash = encodeURIComponent(JSON.stringify(myData));
// If navigating away using Javascript, be sure to use window.location.href over window.location.replace
window.location.href = '/another-page-url'
....
// On page load (e.g. in an init function), if there is data in the #hash, overwrite initial state data
// by decoding and parsing the JSON string
if (window.location.hash) {
// Read the hash string omitting the # prefix
var hashJson = window.location.hash.substring(1);
// Restore the deserialized data to memory
myData = JSON.parse(decodeURIComponent(hashJson));
}
epignosisx and Malcolm are both right. It's also known as "deep linking". We used the JQuery Address Plugin to deal with this in a recent Play application.
http://www.asual.com/jquery/address/
Is there a way to hide the url in the address bar with Grails application. Now users of the web application can see and change the request parameter values from the address bar and they see the record id in the show page.
Is there a way in Javascript or Groovy (URL Mapping) or Grails (.gsp) or HTML or Tomcat (server.xml or conf.xml or in web.xml inside application in the webapps)
ex(http://www.example.com/hide/show /) i want to avoid this url and always see (http://www.example.com) or (http://www.example.com/hide/show) without the record id
Is there a way to prevent this?
No, most browsers doesn't let you hide the address field, even if you open a new window using window.open. This is a security feature, so that one site can't easily pretend to be another.
Your application should have security checks so that one user can't access data that only another user should see. Just hiding the URL would not be safe anyway, you can easily get around that using tools built into the browser, or readily available addons.
It's part of the restful URL pattern implemented by grails.
Your best bet to hide the URL would be using an iframe within the page you want the user to see in their address bar.
Not quite sure what you mean, but I would change the default root URL mapping in UrlMappings.groovy so it looks a bit like this:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
//Change it here!!!!
"/"(controller: 'controllerName', action: 'actionName')
Where 'actionName' and 'controllerName' are what you want them to be - 'hide', 'show' in your example?
Than pass all parameters via a post instead of a get, just change the <g:form> method.
You will still obviously need to implement any security checking required in the controller as stated by other posters.
Thanks,
Jim.
You can probably handle this using a variation of Post/Redirect/Get:
http://en.wikipedia.org/wiki/Post/Redirect/Get
At our Grails site we have a lot of search fields. When a user clicked a pagination link all those search fields ended up in the URL which created ugly URL:s with a higher risk that users bookmarked those addresses which could mean future problems.
We solved this by saving not only all POST but also GET with parameters into the session, redirect to GET without parameters and append those again in the controller. This not only creates nice URL:s but also a memory so that if a user goes back to an earlier menu, then selected details within that menu are redisplayed.
For your specific request to hide the id in "show/42" you can probably handle that likewise or possibly configure Grails to use "show?id=42" instead, but we don't have that requirement so I haven't looked further into that issue. Good luck!
Forgot to mention: this won't add much to security since links will still contain ids, it will only clean up the address bar.
Here's some sample code that should work. If show?id=42 is called, it saves id=42 in the session, then redirects to just show and id=42 is added to params before further processing. It does what you want, but as commented it might not always be a wise thing to do.
def show = {
if (request.method == 'GET' && !request.queryString) {
if (session[controllerName]) {
params.putAll(session[controllerName])
// Add the typical code for show here...
}
} else {
session[controllerName] = extractParams(params)
redirect(action: 'show')
return
}