I am using backbone.js and building a single page application, inspired by trello.com ..
I want to know how you show many pages on top of the original page. As in how you architect it.
How do you use Backbone routers to achieve this?
For example in trello
Basepage
And then now on top of the base page you have dynamic content
like a cards detail
like a boards details
How could i architecture something like this?
I've done a couple of approaches so far in projects with 50+ pages and they both scaled well. I did not use backbone.js but the approaches are straight forward and do not require a framework to learn other than I used jQuery for selectors.
Both of them have in common creating a single overlay window that you can pull in content into the window. I wrote mine from scratch but you could easily use jQuery UI dialog. The two approaches only differ in how the content is pulled. Also, using the information on the link is all you should need to pull in the "module" or overlay content as your rule. Do not need tons of scripts loaded in to start your app. Have the modules pull in the behavior for you.
Option 1) Use the jQuery load method to pull content from stand-alone web pages by using a placeholder variable like so:
var $ph = $('<div />');
$ph.load(URL); // loads gui of remote URL + executes any script that URL has
The $ph var now contains all the GUI loaded in from the external URL so you can use selector on it to extract the particular HTML and place it into your DOM or overlay as you need.
Here is an example of the stand-alone HTML output:
<div class="module">
<a class="link">click me</a>
</div>
<script>
(function(){
// put any private vars here
$('.module .link').click(function(){
// do something
});
})();
</script>
If you remove() or destroy the dom inside the overlay through jQuery, it will automatically remove all the events directly assigned aka "bind" and "unbind" them but using "live" or "delegate" you will need to worry about "die" and "undelegate" etc. just doing die('.namespace').live('click.namespace') will ensure is cleaned.
Here is an example of this on one of my websites -> http://www.kitgui.com/docs
But the better example is within the customer section as the docs is fairly simple using hash history.
2) Using an iframe inside your overlay and assigning it a URL.
This is the easiest option but is a little slower because each page called has to have a full standalone behavior and dependencies with the iframe. Also you must worry about sizing the frame etc. unless you have a fixed overlay window.
You must have a loader overlay your iframe while its loading then have the iframe talk the parent to tell it its done loading and hide the loader.
I did this for several sites but one of them is a site in development you can see here to get the code ->
http://dev.zipstory.com (sign in and go to my zipstory and click "group" settings etc to see this, just view source to see how I did this as its all there)
The thing about iframes is you should write some code on the parent that accepts standard messages from the iframe that you agree on as a typical set of behavior such as notifying its done loading or passing messages to update something on the parent etc. This can be added on the fly and refactored as you need as long as your aim is KISS approach.
Each of the 'dynamic content' pages should be a template (underscore.js gives you _.template()) rendered by a backbone view. The main page needs to have events that initialize new views and render the templates. Look at the todos app (http://documentcloud.github.com/backbone/docs/todos.html) to get a basic idea about the flow of a backbone app.
Related
I'm sure that this is a very simple problem, but I have multiple pages each with their own 'content' with page navigation at the bottom. Before I start coding a script to generate several different html files who all have head, body, and navigation footer code... how could I have only one instance of the navigation footer and have the links only update the content inside the 'content' div?
Very basic example of updating an element's content via JavaScript:
<div id="content"></div>
<script>
document.getElementById('content').innerHTML='<b>oh hai</b>';
</script>
To do it when someone clicks on a link, you'd attach a function to the onclick handler for that link that does the updating and then returns false so the link won't do it's usual navigation.
If you don't want to have all the content loaded into a single file, you can use AJAX to retrieve content dynamically. You may wish to use a library/framework like jQuery to simplify the coding of AJAX interactions.
You can do this with AJAX. An example with jQuery is using the load function:
http://api.jquery.com/load/
This will fetch a given URL and load its contents into an element matched by a selector.
This can be solved in a few different ways. You'll either need to load all possible contents at once (easy to access content after load, but slow initial load), or you can asynchronously request content as your user requires it.
1) Hardcode all content into one page
By doing this, you'd have a selection of content blocks hidden on your page:
<div class="content-blocks">
<div class="content" id="content1">...</div>
<div class="content" id="content2">...</div>
...
</div>
Then, each link would have an event handler to load the appropriate content into your main content element.
document.getElementById('content1-link').onclick = function() {
document.getElementById('content-box').innerHTML = document.getElementById('content1').innerHTML
}
2) Make AJAX requests for content
To do this, your various content blocks would be stored in external files, e.g. 'content1.html', 'content2.html', etc. I would highly recommend using a javascript library with AJAX support for this method, as they will handle differences in how browsers handle asynchronous requests. Some, like jQuery, also provide convenience functions to do such tasks:
$('#content1-link').on('click',function(){
$('#content-box').load('/path/to/content1.html');
});
3) Use include statements
This method has the ease of implementation of the first solution (doesn't rely on async requests), but it keeps your content in separate files, like the second solution. Basically, you utilize whatever type of include your server/language supports (e.g. SSI includes, PHP require, etc). You would then create the event handlers as in the first option.
Working on MVC5 asp.net website.
I have a "dashboard" page that allows the user to place pre-defined "widgets" on the page. These widgets are simply MVC 5 partial pages (Razor). I really wanted each widget to be "self-contained" so all references, scripts, etc... are within the widget's cshtml file. BUT, the main "dashboard" page also needs certain references to jQuery, bootstrap, etc...
Of course, doing this, I could encounter conflicts, duplicate references (one from main page, one from widget), etc....
Question: What is the preferred method for this scenario? Should references like jQuery and bootstrap be JUST on the main "dashboard" page? What about javascript or jQuery code that is in the widget itself? Should this remain in the widget? If so, will I encounter the issue where it doesn't have jQuery defined (because it's in the parent page), etc...?
Any thoughts on this would be appreciated?
Thanks!
**** UPDATE ****
TO further clarify: If I put the scripts, references, etc (specific to the widget) at the bottom of the widget, then when the partial page is rendered on the main page, the scripts, etc.. are not rendered at the bottom of the main page. This causes my code to act funny because of the order that things are rendered. This is one reason I ask this question. Hope this makes sense. Thanks.
Put the script code and references that are global to the application , that are used everywhere and that are not specific to a widget in the most outer page.
What i would do, is i would bundle all my script references in one place and add that bundle link to the dashboard page, this makes your code cleaner and your page will have less external references thus a better client side performance.
Considering that the mobile app is not native, but made with phonegap (or something simmilar), i am wondering if there is a javascript / jquery library that i can use to navigate from one html page to another one without the need to reload all ls and css resources.
More or less like jQuery Mobile does it.
One issue would be enhancing all the ui and js widgets on each page
Any ideas?
You can do an AJAX call to whatever the local URL is and wrap the entire response in something traversable via jQuery, like...
// on click link ->
$.get('myUrl.html', function(response) {
var new_body, traversable;
traversable = $('<div></div>', {
html: response
});
new_body = traversable.find('body').html();
// code to replace your content here ...
});
And if you have a lot of scripts/styles running per page, you could traverse through the list of traversable.find('link') and traversable.find('script') to compare what has and has not been used yet. Then append to the document after replacing your markup.
I think it is Phonegap you are talking about.
Yes, Jquery mobile is would be a solution to your problem because whenever we change the page in Jquery Mobile, instead of reloading the whole DOM, it only replaces/inserts (depends on if you enable caching) the new page div to be shown.
Thus, all resources you included initially would persist and be usable in all pages.
Depending on how your html and css are written, you could wrap your pages in divs and use css transforms to position them off screen, then scroll them into view when the user clicks a link.
jQuery mobile inside of phonegap is very, very slow.
I'm sure that this is a very simple problem, but I have multiple pages each with their own 'content' with page navigation at the bottom. Before I start coding a script to generate several different html files who all have head, body, and navigation footer code... how could I have only one instance of the navigation footer and have the links only update the content inside the 'content' div?
Very basic example of updating an element's content via JavaScript:
<div id="content"></div>
<script>
document.getElementById('content').innerHTML='<b>oh hai</b>';
</script>
To do it when someone clicks on a link, you'd attach a function to the onclick handler for that link that does the updating and then returns false so the link won't do it's usual navigation.
If you don't want to have all the content loaded into a single file, you can use AJAX to retrieve content dynamically. You may wish to use a library/framework like jQuery to simplify the coding of AJAX interactions.
You can do this with AJAX. An example with jQuery is using the load function:
http://api.jquery.com/load/
This will fetch a given URL and load its contents into an element matched by a selector.
This can be solved in a few different ways. You'll either need to load all possible contents at once (easy to access content after load, but slow initial load), or you can asynchronously request content as your user requires it.
1) Hardcode all content into one page
By doing this, you'd have a selection of content blocks hidden on your page:
<div class="content-blocks">
<div class="content" id="content1">...</div>
<div class="content" id="content2">...</div>
...
</div>
Then, each link would have an event handler to load the appropriate content into your main content element.
document.getElementById('content1-link').onclick = function() {
document.getElementById('content-box').innerHTML = document.getElementById('content1').innerHTML
}
2) Make AJAX requests for content
To do this, your various content blocks would be stored in external files, e.g. 'content1.html', 'content2.html', etc. I would highly recommend using a javascript library with AJAX support for this method, as they will handle differences in how browsers handle asynchronous requests. Some, like jQuery, also provide convenience functions to do such tasks:
$('#content1-link').on('click',function(){
$('#content-box').load('/path/to/content1.html');
});
3) Use include statements
This method has the ease of implementation of the first solution (doesn't rely on async requests), but it keeps your content in separate files, like the second solution. Basically, you utilize whatever type of include your server/language supports (e.g. SSI includes, PHP require, etc). You would then create the event handlers as in the first option.
Hiho,
There's an existing website that i need to include into another site which goes like this:
a.mysite.com
and i need to fetch content from this site in my
www.mysite.com
website...
As i need to access the content of the iframe the Same origin policy produces a problem here.
What i did was to configure mod_proxy on Apache to proxy pass all requests from
www.mysite.com/a
to
a.mysite.com
This will work fine...but my problem is that im not sure what the best way would be to include those pages.
1. Idea
As the content of the iframe is a full featured site with a top navigation...left navigation etc....i would need to change the page template to only show the content box to be able to integrate that page in the iframe.
2. Idea
I could just load the DIV where the content lies through JQuery.load() and integrate it into my site.
What is the best way to accomplish such a task? How bad is both ideas from the SEO point of view?
Unless it involves significant rework, the best solution is to combine the two into a single HTML page on the server side (using server-side includes).
Advantages:
No problems with SEO as it's delivered as a single page. Content in iFrames and content loaded via AJAX (with an associated link in the HTML) are traversed, but only the link, not the content itself is associated with the main page. See: http://www.straightupsearch.com/search-marketing/best-practices/seo_iframes_a_g/
Faster page load - either of your suggestions will cause the main page to be loaded first before the other content is loaded.
No reliance on Javascript - your second method will fail completely if javascript is not supported / turned on.
Include all JS and CSS only once - your first method will require these to be duplicated in the <head> of each page. This is more of a long term advantage if you wish to achieve full integration of site "a". However, it can be a disadvantage initially, see below.
Disadvantage:
May cause conflicts with scripts and CSS between the two pages. However, this same problem exists with your second method.
If you must choose between either of the two options you proposed, I would not select the second as others have suggested. Significant amounts of static content should never be loaded via Ajax, and in this scenario gives you no additional benefits. At least iFrames guarantee no JS and CSS conflicts.
Use the 2nd approach (jQuery.load) and if you're working with HTML5, for browsers that support the History API you can change the URL to whatever the content is for that div.
Check out https://github.com/blog/760-the-tree-slider for an example of how github did it for their tree slider.
EDIT:
I am not sure how using an iFrame whose src points to your own domain affects search rankings but at best it's a grey area. I would assume that possibly some pagerank would trickle from the parent to the child but I have no clue how it would work for instance if a blogger linked to your page with the iframe that pointed to another page. This would be a pretty good question to ask at the Webmaster Help Forum
Always say no to iframes. jQuery+Ajax all the way.