The rows of table are back to their places after refreshing page - javascript

I was making a feature with which you can swap the rows in table. It works great, but after refreshing the page, if I swapped some rows, the rows are back to the place, where they have been before swapping. I'd like to know, why is that happening and how to avoid that. This is the code of the feature, if someone needs it:
swapRows = function(rowTable) {
rowTable.find(".glyphicon-sort").click( function() {
row = $(this).closest("tr");
row.insertBefore( row.prev() );
} );
}

This is happening because after refreshing, your page returns to its initial state (from server, or cache), duh.
To retain the state, you have several options: AJAX (so that you don't have your page refreshed), or HTML5 history state manipulation, or local storage etc., all of which are beyond the scope of this question I'm afraid.

This is happening because jQuery is a client side technology and the data is not persisted between requests. When you refresh your page you make new request to the server, which in turn respond with a new page (.html) with a default state.
In order to save this data between requests you can use cookies.

Related

Refreshing html table after ajax success

When we perform destructive operations on database tables (insert/update/delete) using ajax, the DOM has to reflect this change. I see two commonly used approaches.
When the destructive database operation succeeds, manipulate the rows in the html table to reflect the change
When the destructive database operation succeeds, refresh the html table by making another ajax request
Suppose users A and B are accessing a table of 5 rows. Then A deletes the first row while B deletes the second row. With the DOM manipulation approach, A will not see that the second row is deleted while B will not see that the first row is deleted. This problem can be eliminated by the refresh approach, but both users can only see the full updates when they themselves perform an operation.
Which is the best approach?
The problem cannot be eliminated by simple "refresh" approach(option 2).
Let's say both A and B viewing the table. Now A deleted a row, if you refresh the page of A it'll be only updated on A's view window. But code running on B will not be aware at the moment of the fact that the row is deleted. He will see the update only after he delete one row as per option 2 or obviously make a browser refresh.
One quick solution is to refresh the table data by using Ajax request in a fixed interval. For ex: 5 seconds.
To make the table reflect truly real-time data of the database at any moment for every user you have to use websocket. For this you need both real-time server and client.
You can implement a portion or feature of your entire web application in something like Socket.IO to make that portion real-time while keeping the other portion as is using your existing technology stack.

What is the right way to call dynamic content (currently using ajax) inside a cached page?

We have a news website where we cache a complete article page.
There are 4 areas that need to continue to be dynamic on that page:
View Counter: We add +1 to view_counts of that article when page loads.
Header: On the header of the website we check if session->id exists or not if it does we display a Welcome [Name], My Profile / Logout and if not we show Register / Login.
Comments: We display the comments made for that article.
Track User Behavior: We track every single action made by users on the site
Now the only way we could think of doing this is through AJAX calls:
$('#usercheck').load(<?php echo "'" . base_url() . "ajax/check_header'"; ?>);
And so on.
This is creating a massive load on CPU, but what would be the right/alternative way of approaching this?
Please see attached:
First of all, you do not have to use AJAX for every possible dynamic content, especially in the case of comments, you may as well load them via an iframe.
That way, you are not relying on Javascript to make the request.
It may even work for the counter.
However, you problem is not Javascript, nor the database server, based on what I can see from your graph. It seems to me you have some heavy PHP controllers, maybe you are loading a heavy framework just to have $session->id checked.
Further, what do you mean by "we track every single action"? How do you track them? Are you sending an AJAX request from every little thing or are you debouncing them with JS and only sending them one every 30 seconds or so?
My advice is that you consider the size of the PHP code you are calling, and slim it down as much as you can, even to zero if it seems feasible (by leveraging localStorage to keep track of you user session after the first login), and maybe loading the counter and the comments in alternative ways.
For example, I infer you are only checking the counter once per page load, ignoring subsequent loads by other users while the current user is reading the article, so your counter may happen to be out-of-date once i a while, depending on your traffic.
I going to explain it better: your page has n views, so when I load it, you request for n and then display n+1 to me. While I'm reading, the same page gets requested and viewed x times by other users. Your counter on the server has been surely updated to n+x, but the counter on my page still says "n views".
So, what's the point in being picky and showing n+1 to me and the not updating it, thus being off by x?
So, first of all the counter controller should be as slim as possible, and what if you loaded it within an iframe, auto updating without AJAX?
How to refresh an iframe not using javascript?
That would keep the counter up-to-date, you may render it with PHP just once per page view, and then just statically serve the resulting HTML file.

How to keep the filters from DataTables after a Back/Forward or Refresh

We're using DataTables as our table, and we're having a problem/disagreement with somehow keeping the history of filters that were applied to the table before, so that users can back/forth and refresh through these.
Now, one solution that was proposed was that I keep the filters string in the URL, and pass it around as a GET request, which would work well with back/forth and refresh. But as I have very customized filtering options (nested groups of filters), the filter string gets quite long, actually too long to be able to pass it with the GET request because of the length limit.
So as GET is out of the question, the obvious solution would be a POST request, and this is what we can't agree upon.
First solution is to use the POST request, and get the "annoying" popup every time we try to go back/forth or refresh. We also break the POST/Redirect/GET pattern that we use throughout the site, since there will be no GET.
Pros:
Simple solution
No second requests to the server
No additional database request
No additional database data
Only save the filter to the database when you choose to, so that you can re-apply it whenever you want
Cons:
Breaks the POST/Redirect/GET pattern
Having to push POST data with pushState (history.js)
How to get refresh to work?
Second solution is to use the POST request, server side saves the data in the DB, gets an ID for requesting the saved data, returns it, and the client then does a GET request with this ID, which the server side matches back to the data, returning the right filter, thus retaining the POST/Redirect/GET pattern. This solution makes two requests and saves every filter that users use to the database. Each user would have only a limited number of 'history' filters saved in the database, the older ones getting removed as new ones are applied. Basically the server side would shorten your URL by saving the long data to the database, like an URL shortening site does.
Pros:
Keeps the POST/Redirect/GET pattern
No popup messages when going back/forth and refreshing the page due to the post data being sent again
Cons:
Complicated solution
Additional request to the server
Additional request to the database
A lot of data in the database that will not be used unless the user goes back/forth or refreshes the page
A third solution would be very welcome, or pick one of the above and ideally explain why.
This is a fleeting thought i just had...you can save state of length, filtering, pagination and sorting by using bStateSave http://datatables.net/examples/basic_init/state_save.html
My thought was, theoretically you could save the cookie generated by datatables.js into a database table, like you mention in the second solution, but the request only has to happen each time you want to overwrite the current filter, replacing the current cookie with the previous "history" cookie

How to keep HTML Element on Browser Location Change

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).

After appending element to page, going to another page, then back, the appended element is gone

This is a bit long to explain, so I'll try to keep it short:
I'm submitting a form and returning a list of users, then emptying a and repopulating it with the returned users. This works as expected until after I add a user and then browse to another page, then go back to the previous page, it's loading the list of users that was there before adding the new user. If I refresh, the user list is correctly displaying the list of users again.
Some pseudo code:
... function to add a user, then return success ...
$("ul#userTab").empty();
for(user in data['users']){
$("ul#userTab").append("<li>"+user+"</li>");
}
It seems as though the browser is caching the first page load once I use the back button, but I don't really know. Any help is appreciated.
EDIT: To clarify, I'm sending data to the server, saving it in the database, then returning the users from the database. I'm not just adding an arbitrary value to the page then reloading and wondering why it's not there.
The browser is not going to maintain the DOM which you manipulate between page redirects. You have to use any history management plugin or using iframe to maintain the state of the page between page redirects.
Take a look at some of the links below, these might help you
http://www.asual.com/jquery/address/
http://benalman.com/projects/jquery-bbq-plugin/
http://plugins.jquery.com/project/history
http://benalman.com/projects/jquery-hashchange-plugin/
http://code.google.com/p/reallysimplehistory/
A page is loaded with what the server sends to the browser, any changes made by javascript are done in the client browser only, and not on the server, so when the page is reloaded from the server it is the same as it was, what the server sends.
to make the change permanent, you will need to either send the change to the server using AJAX, or store it client side in session or cookies.
the obvious answer is that you're dynamically adding elements to the dom and not rewriting the page. If you want to preserve the results you should consider adding the results to a cookie and checking if the cookies exists on load, then display accordingly.
document.cookie ='users=html_results here; expires=Thu, 2 Aug 2001 20:47:11 UTC; path=/';

Categories