Suppose I am writing a simple single-page web application in JavaScript. The application just displays employee records. User enters search parameters, the application fetches employees records from the server using AJAX and displays them in the web page.
The application state is search params and employees. How to store them in the application? I see two options:
just use DOM to store the state implicitly.
create data structures for search params and employees and synch them with the DOM.
Does it make sense? What are the pros and cons of these two options?
If you are targeting modern browsers, Web Storage would be a good option for you to look into.
Good write up here: http://sixrevisions.com/html/introduction-web-storage/
That way all load would be kept within the client and data would persist between requests and if user leaves and comes back to application.
The options you mentioned which I'm guessing means you would store data within hidden DOM elements would be easy to develop however you will lose all persistence. If you're going to go down this path, why not just store the data directly in javascript objects?
Another good read: http://diveintohtml5.info/storage.html
Definitely the latter. The DOM was never designed as a data structure. On the other hand, creating an architecture to keep the DOM in sync with your custom data structure can be a pain.
Luckily, there are frameworks that can help you with this. Most of these follow an MVC- (or MV*)-like design pattern. Examples include Backbone.js, AngularJS, Spine, Agility.js, JavaScriptMVC and many others. Have a look around.
Also check out this project: TodoMVC. It might help you decide whether to use a framework like this and, if so, which one.
If you want them to be persistant, you can't use the DOM, and you shouldn't. HTML is for your user interface and linking everything together, not for data storage of your app. You have a couple of options. You can use global variables in your JavaScript, but you have to remember that they will not persist between visits to your page. If this is what you want, go ahead.
Another option is to use HTML5's Local Storage, which is persistant and designed for storing data.
Your last option, which is important if you don't want to store the data locally but do want to persist it, is to use HTTP AJAX GET and POST with a servlet or something on the client side that gets and sets the data, respectively.
If you want to go the old way, you could also use cookies instead of Web Storage. I definitely suggest the later though.
In this case, you can trigger a change in your hash when user applies a filter. For example:
http://www.mydomain.com/index.html#name=abc&department=def . Your app listens for changes in the hash to update accordingly. Libraries like: crossroads.js, sammy.js allow you to to that. This approach on client side borrows the routing concept on server side.
Using this approach, you can send the url to your friends to "jump" directly to a specific state of your application and you can also reuse it, store it anywhere.
You might consider using this kind of leverage if you use HTML 5 :
http://www.jstorage.info/
Related
I always find it difficult to decide if I should render my HTML server-side or build it client-side.
Let's say I want to render a dynamic HTML dropdown with following requirements:
Shows records from a database table at page load
Must stay up-to-date (users can add/remove records from the database table using the website)
I can't decide between
Option 1
Render template with empty dropdown server-side
Populate dropdown client-side using ajax requests (JSON)
Update dropdown client-side using ajax requests (JSON)
Concern: Rendering empty elements before populating feels ugly to me
Option 2
Render populated dropdown server-side
Update dropdown client-side using ajax requests (JSON)
Concern: Why would you render server-side if you are still updating it client-side?
What solution is more commonly used in web development? Feel free to share different approaches.
This is a little opinion bases. There are schools for the server-side, and other schools for the client-side. The main reason for the later is utilizing the client machine (which are free for you) to free the server resources (which you pay for). This also makes your app more scalable.
The example that you gave is not detailed enough, and it is only one aspect. I usually use these general rules:
If there are dynamic parts of your page (e.g. dropdown, grid, popup form, etc), I use Ajax to avoid reloading the entire page.
If the HTML is very simple and/or requires further processing on the client-side, then just send JSON data from the server and build the HTML on the client-side. For example, I usually do not send error message from the server. Instead, I only send status codes (e.g. Successful, AccessDenied, Error, etc...) and I inspect those codes on the client and display the associated message. This is specially useful when different messages are displayed in different colors and styles or contain other HTML tags like links.
If it is a complex popup form or grid of data, then I send the HTML from the server. It is usually much easier and more flexible to build complex HTML on the server. Also when there are sensitive information used to build the HTML, it is usually much easier to build it on the server, otherwise you'll have to send some flags from the server or, better, you need to split your HTML building process to sections depending on permissions.
As for that very specific example in your question, I would go with the first approach (all client-side), mainly for the DRY concept (Don't Repeat Yourself). You don't want to have two pieces of code doing the exact same thing, and have to remember to update both every time you need change something.
Note though, that you don't have to send empty drop-down if you don't like it. Instead of only updating options like your example is suggesting, you can actually rebuild the entire dropdown every time. I don't particularly like this approach, especially if there are event listeners and other references attached to the dropdown, but I just wanted to say other ways to do it. This method can be useful on some scenarios, especially if the dropdown is part of a bigger section of the page that this whole section requires updating (rebuilding) every time, in which case I usually opt for sending the HTML from the server.
Your concerns are valid, each case has its advantages and disadvantages as you mentioned.
I would, personally, go with the first approach (all client-side); mainly for code maintainability. With this approach, you only have to update the HTML client-side instead of both client-side and server-side.
However, there is an argument to be made for saving that one request by server-side rendering the values. Even though it might be insignificant, there is a small performance optimization.
That depends. are you worrying about SEO?
Are you using any kind of client-side framework? I will assume that you don't, since JavaScript frameworks have there own way to do this, if you want you can read more about angular/react/vuejs which is the hottest JavaScript frameworks those days that will solve this issue.
Client-side frameworks render HTML on client-side only, and use only Ajax API to receive data from the server.
But if you don't want to use any client-side framework and do it in the "classic" way, both ways are appreciated. I tend to like the first way, this is almost how client-side frameworks do it and makes the most sense, yes you render empty table but you only render the "container" of your data, if you're bothered by how it looks visually (Showing empty list before data is fetched) you can just show loading bar or hide the table till the data is fetched.
I did my homework and read through this mini series about pushstate:
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/
From what understand the hard part of implementing push state is making sure that my server side is going to serve the actual pages for the corresponding urls.
I feel like this is going to be a HUGE task, previously I was just sending a simple jade page as simple as:
body
header
section
div#main
footer.site-footer
div.footer-icons.footer-element
div.footer-element
span.footer-link Contact Us
span.footer-link Terms of Service
script(src='/javascripts/lib/require.js', data-main='/javascripts/application.js')
and I was doing all the rendering with my Marionette Layouts and Composite Views, and to be honest it was a bit complicated.
So from what I understand I need to replicate all that complicated nesting/rendering using jade on the server side for pushState to work properly?
I used underscore templates in the client-side, what is an easy way to re-use them on the server side?
I depends on what you want to do...
To "just" use pushState, the only requirement is that your server returns a valid page for each URL that can be reached by your app. However, the content returned by the server does NOT have to match what will get rendered client side. In other words, you could use a "catch all" route on the server side that always returns the page you have above, and then let Backbone/Marionette trigger its route to handle the rendering and display.
That said, if you want to use pushState for SEO, you likely want to have the static HTML sent by the server on the first call, then have the Marionette app start to enhance the interactivity. In this case, it is much more complex and you might want to experiment with using options to trigger the proper behavior (e.g. using attachView when enhancing existing HTML, showing views normally after that initial case).
Push state can work properly WITHOUT your server actually serving your application in the way that is suggested.
Push state is merely an alternative to hashbang url's, and it is supported in modern browsers. Check out the history docs here, you will see there is no mention of having your site serve your application statically at the url's for your application (but bear in mind it is opt-in).
What the article you reference is saying, is that for good SEO, you should do this. That's because you cannot guarantee when a search engine crawls your site, that it will execute your javascript, and pick up your routes etc. So serving the site statically is simply to give the search engine a way to get your content without executing any javascript.
Like you say, by doing this you are essentially building two sites in parallel, and it does literally double the amount of work you need to do. This may be ok if you're building a relatively simple site filled with static content, but if you are creating a complicated application, then it is probably too much in most situations.
Although I would add, if you are building an application, then SEO doesn't really matter, so it's a null point.
I've made a very simple to-do list. The user can enter some information, click submit and it is added to an unordered HTML list.
However, the obvious problem is that the information is not saved. On a simple browser refresh, all the information is gone.
Can Javascript save this new information next time I visit the page? (Would it be AJAX, or will I have to start learning some PHP?)
There are several options for persisting data locally in JavaScript: cookies, localStorage, webStorage, and indexed DB. The first two are pretty much universally supported in modern browsers; the last two not quite as well supported. There's a nice article about the first three here. You can also consider keeping data on the server. See, e.g., this thread. There are also third-party packages like persistence.js that provide a higher-level interface to storage that can be either local or web-based.
It is possible to use java script as a server side language but it's not recommended! It's not very appropriate for this operations. May be you should try to learn PHP or JSP etc.
I want to develop a relatively simple application that calculates some value based on several inputs. I dont want a backend, all the calculation can be done in the browser.
Im a little new to JavaScript and WebApps and I came across Backbone.js.
I really like the MVC design, however, they mention a backend a lot. My question:
Is a backend server absolutely required?
Is a backend server optional but without one there isn't much point in backbone.
Or will backbone will really help me out?
Backend is not required.
Backbone can fully work without any backend if your application doesn't require one.
That depends on your application. If you want to retrieve value of some inputs and calculate a result then Backbone won't do that for you - it will help you structure your code. If you app is simple and don't need support for models, views and collections or routing, then there is no point in using Backbone. Hard to answer this question.
For example: Classic todo example application doesn't use any backend.
Backbone.js implements fetch(), save(), destroy() etc. methods on models automatically performing appropriate AJAX requests and parsing response. So it has a strong support for backend via REST services, but it is optional.
You can still use models, views, routers and events without any server-side code. Just don't call REST methods (or override them at your wish).
You can use localStorage for persistence (you'd have to implement this yourself or find it on the web, like here) but if you don't even need that then you don't need to use any of the persistence methods in backbone.
Backbone is meant to help you structure a medium-large sized application (js-wise), so it doesn't become unmaintainable jQuery spaghetti. With short applications (js-wise) it's really an overkill unless you are trying to learn how backbone works.
Note with js-wise I mean the client side code, if you had a huge backend but the only js would be something that focuses some form, it would not even count as a short application (js-wise).
You can use backbone.js without a backend. However you obviously won't be able to store or retrieve data. Backbone may still be useful for keeping your code organized, however it really shines when you want to separate presentation logic from logic that manipulates your data, which is a goal of the MVC pattern. Generally your data will be stored on and retrieved from a backend.
If you want to play around with data persistence, try out backlift.com. [disclosure, I work on backlift.com] We've tried to make it easy to get a backbone app up-and-running without having to setup a server or deal with compiling templates.
I have heard a lot about backbone.js and quite frankly I don't understand its concept. Does it require that all the elements should be in single page to work out with its animations and effects ? Or it can grab items from server and load it with transition or i mean different pages but make look like a single page. I didn't understand its concept well, so that's why i am asking. What i am looking for is to combine backbone or any other javascript framework to work with a rails project, that could give some ease transition across pages and can give native application look.
Backbone is also here to give you structure by being MVC, and it allows to communicate in a really simple way with the server. You'll be able to update / fetch / save your data (your rails models for example) on the server. So you'll need it if you want your user to work on an Ajax page without having to reload the page.
For example, you'll fetch all your data from the server when the page loads and then you'll have access to all attributes of your models and will be able to modify it and save it to the server.
Moreover, if you want your models to appear with transition, as Backbone is MVC, you'll be able to make that easily. As you have to choose when and where your views will appear on the DOM, you'll be able to put transition at that time.
By the way, Backbone works really great with Rails!
Backbone.js is all about data to be used in some way from your users, think about it as ActiveRecord plus Sinatra (or rails) on a browser, infact, the framework will give you a way to handle your data inside a browser instead of the server.
If you are looking for a simple way to add transitions to your existing app/website you could use a jquery plugin like Pagify (it rely on $.getHtml()) modifying it to get a fragment of the subpages like my (buggy) fork.