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.
Related
In my application, I'm using an OnDemandGrid, backed by a Request + Trackable dstore, to display my data to the user.
The server sends notifications to the client via websocket to add new entries to the grid. To add the new entries to the grid, the store is emiting an 'add' event, something like the following piece of code:
function _emitAddEvent(store, entity) {
store.emit('add', {
target: entity,
id: entity.id
});
}
Until here, it's all good. The application receives the new entry from the server to be added to the grid, and adds it (without refreshing the grid). The problem is if there are too many notifications being sent by the server during a small time interval. The store emits all the events to the dgrid, but the grid tooks some time to render all the rows. Because there are too many entries to be added, the application goes unresponsive. If the server stops sending data to the client, after some time the application recovers and render all the rows correctly. Now comes the second (but minor) issue.
The second issue is that, after the grid renders all the new rows, it does not destroy the rows that are too far. I've set the farOffRemoval attribute, but it seems to only handle cases where a scroll happens and new data is requested to the server. I would like to know if there is a workaround, that does not rely on scroll, to destroy nodes that are too distant from the user current position on the grid.
Well, I've managed to code a workaround to the first issue. Since the application was becoming unresponsive because there were a lot of notifications being received by the client in short period of time, I opted for adding the events on a queue and emit them at a maximum of one per second. dojo/throttle along with setInterval were enough for that.
The second isue, related to the farOffRemoval attribute, I wasn't able to solve. After some testing, I noticed that the browser can have a lot of DOM nodes without losing significant performance (of course, it depends on the user machine), so I just left the grid untouched.
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
I created a table that receives data from a SQL database to a PHP script that parse this back though my AJAX to the HTML page.
With this information I create the table.
It works and the beauty of it: every time the data changes the table changes.
BUT: it reloads the whole table with new data.
What I want is to have it only reload the part that's been updates and then "mark" it until you mouse over it.
Is there any function in JS that allows to compare 2 JSON encoded strings and then only update the part that's not similar?
I have use jQuery but haven't found anything as of yet.I apologies for not showing any code but it's protected from sharing
You have to poll AJAX request to the server after every few seconds or minutes and see if there's any update. If so, you receive that update with say the id or index number of the data which you can replace with the new one. That way you won't have to update the entire thing.
I have a requirement for a multi-part form which I want to apply some clever submission logic. Here's the idea, the form has 3 steps:
Personal Contact Details
Quote Details
Final Comments
As any good marketer I don't want to lose any data in the event that the user does not complete ALL the steps this (somewhat long) form.
As a result, what I would like to do is to have the form submit as each step is completed. So that in the event the user drops off we still capture the details on the completed steps.
Ideally I don't actually want to have the form submit 3 time as, if it was going to a simple email script, we'd get 3 results through for each 'complete' submission.
So I'm trying to find some clever way to store the data and submit it after a certain period of time or something along those lines.
I intend to be building this in HTML & JavaScrip (& if need be in PHP). Can anyone suggest the best route to achieve this (from past experience etc) before I get my feet wet!!!
Thanks for your time & any suggestions
The best way to achieve this is to have three separate forms, one for each page. Upon the submission of each form make a post() request to a PHP page on the server using jQuery, containing the serialized() form data. This PHP page then stores the contents of the form in a database for retrieval later.
If the ajax request is successful, show the next page of the form, otherwise display an error telling the user what happened.
Further reading on .post() and .serialize()
You need server support to store survey's temporary result. When user submits next part, you will simple append new answers to the query. The trick is in detecting abandoned queries, but I think if the survey will not be completed in 24h, you can safely assume that user closed browser and will not append any future data.
You must implement persistance on server, SQL database is the best option for PHP - millions of examples.
If I understand your question correctly then you are trying to have the behavior of Wizard in the same page, in that case you can use have three forms .
After completion of one section do an ajax call and save the filled in data in some temp database table, finally when user completes the form you can collate the temp table data and persist in your main table.
In case user doesn't complete all the steps then you can clean up your temp table after certain period of time or you can move it in some 'not-complete' table just in case you want to do some BI over the data.
I would serialize the response and store it in a database {id, stage1 data,stage2 data, last_entry_timestamp}.
Assuming that validation is done at each stage before storing the data,
Stage 1 I would check if an entry exists, and if not create a new entry, and store the serialized stage1 info and set timestamp, else retrieve stage 1 info. (back/forward)
Stage 2 If not set, I would update the created entry with the serialized stage2 info and set timestamp, otherwise retrieve and than update.
Stage 3 I would retrieve stage 1 and stage 2 info, and submit. I would then delete that entry.
Finally I would setup a cron job to look at all entries that are over X hours old, submit them, and delete the entry.
I have been finding ways around this for a long time but think it's time I addressed it.
If I have a page that has a dropdown menu, is there anyway I can select a value which will subsequently load other values further down.
Can this be done without a page reload?
I will give you an example.
Say I was making some tools for an admin panel, but first of all they needed to select a member to work with.
They would select the member and then below, the fields about that member would be populated based on what was selected in the first menu.
As I have already asked, can this be done without a page reload?
Thanks for reading.
Yes it can be done without AJAX. When the page is rendered pass all the collections that will be used by the dropdown lists as JSON objects into the HTML:
var collection = [{ id: 1, name: 'John' }, { id: 2, name: 'Smith' }];
...
Then register for the change event of the first drop down and based on the selected value go and fetch the data from the other collections. Of course if you have lots of data this might not be practical as your pages will become very large and in this case AJAX woulld be more appropriate.
Answer YES it can be done.
Firstly you'll need an event, in this case you need to take action on the onChange event for the selectBox. So when an item changes you run a function.
Now you have 2 choices. You can do this using AJAX or NOT, it really depends on the complexity / security of your application.
In the following I refer to
Users : those using the application
Hidden Client Side Data : Data sent to the client during page load, but not visible to all users, however using view source, or downloading JS files, the Data is not secured.
Method 1 - NO AJAX
Basics: You send all the possible display options down initially when the page is first loaded, but display only the sections relevant to the user during selectbox onchange events.
Recommended when: No security condiderations if hidden client side data is detected (or won't be detected, or you simply trust your audience to use the app in the intended manner). Lastly when your total view permutations are low.
Method 2 - AJAX
Basics: You send down initially only the page skeleton, when the user changes the value of the select box, you then do an AJAX request to the server - grab the new view info thats relevant to that user, send it back down to a script which will inject that user data into the DOM.
Recommended when: You have a public site, or a site where security is a consideration. Where you have lots of view permutations or want more customizations per user than in scenario 1.
As you see both methods do not require a repost - method 1 ships everything upfront, method 2 uses AJAX to fill in data when required. Both methods are valid depending on your requirement.
Yes. Ajax is mainly used for that i.e. (without a page reload)
You have to use following step to achieve
Create a link and call a JavaScript function on it's onchange function
In the JavaScript function you have to call Ajax request.
Update the div in your ajax response.