I have setup a Node.js server to render a simple d3 circle.
app.get('/circles',function(req, res) {
res.render('circles');
});
The view engine is jade. Here is the jade template. I refer my java script libraries which are present in the public folder.
doctype html
html
head
title Enterprise dashboard
h1 Welcome to Visualization
link(rel='stylesheet', href='/stylesheets/style.css')
script(src='/javascripts/jquery-1.8.2.min.js')
script(src='/javascripts/d3.min.js')
script(src='/javascripts/d3circles.js')
body(id='idofbody')
div(id='circle')
div(id='circle1')
When I access this from a browser, everything works fine. The d3 visualization works rendering the single circle.
I am trying to make ajax call to the '/circles' from a qlikview extension. But the page returned shows only the static part like h1 tag. The SVG that was made with the script in d3 call circles is not rendered.
The fire bug output shows this. As you can notice, the first GET is the call I made from qlikview extension. The second call is unexpected. When rendering the page, it makes a GET call to the script library with a wrong url-url of the Origin. The url refers the origin and hence becomes unsuccesful I beleive.
note:I can't post the full output from firebug(with all GET calls) as screenshot due to lesser points in my side.
GET http://25.25.80.63:8765/circles 200 OK
3.49s QvAjax.js (line 23)
GET http://25.25.80.63/javascripts/jquery-1.8.2.min.js 404 Not Found 151ms QvAjax.js (line 23)
But the problem occurs only within qlikview. When I do the same ajax call, from a page in a different node server, the script and css libraries are referred with the correct url - the url of the HOST.
Please suggest how to render D3 components into qlikview from the node server.
Related
Ok, this idea might seem quite a bit crazy and it kindo' is (at least for me at my level).
I have a fairly standarad rails app (some content pages, a blog, a news block, some authentication). And I want to make it into a single page app.
What I want to accomplish is:
All the pages are fetched through AJAX like when using turbolinks, except that the AJAX returns only the view part (the yield part in the layout) withought the layout itself, which stays the same (less data in the responces, quicker render and load time).
The pages are mostly just static html with AngularJS markup so not much to process.
All the actual data is loaded separately through JSON and populated in the view.
Also the url and the page title get changed accordingly.
I've been thinking about this concept for quite a while and I just can't seem to come up with a solution. At this point I've got to some ideas on how this actualy might be done along with some problems I can't pass. Any ideas or solutions are greatly appreciated. Or might be I've just gone crazy and 3 small requests to load a page are worse then I big that needs all the rendering done on server side.
So, here's my idea and known problems.
When user first visits the app, the view template with angular markup is rendered regularly and the second request comes from the Angular Resource.
Then on ngClick on any link that adress is sent to ngInclude of the content wrapper.
How do I bind that onClick on any link and how can I exclude certain links from that bind (e.g. links to external authentication services)?
How do I tell the server not to render the layout if the request is comming from Angular? I though about adding a parameter to the request, but there might be a better idea.
When ngInclude gets the requested template, it fires the ngInit functions of the controllers (usually a single one) in that template and gets the data from the server as JSON (along with the proper page title).
Angular populates the template with the received data, sets the browser url to the url of the link and sets the page title to what it just got.
How do I change the page title and the page url? The title can be changed using jQuery, but is there a way through Angular itself?
Again, I keep thinking about some kind of animation to make this change more fancy.
Profit!
So. What do you guys think?
OK, in case enyone ever finds this idea worth thinking about.
The key can be solved as follows.
Server-side decision of whether to render the view or not.
Use a param in the ngInclude and set the layout: false in the controller if that param is present.
Have not found an easier way.
Client-side binding all links except those that have a particular class no-ajax
Here's a directive that does it.
App.directive('allClicks', function($parse) {
return {
restrict: 'A',
transclude: true,
replace: true,
link: function(scope, element, attrs) {
var $a = element.find('a').not($('a.no-ajax')),
fn = $parse(attrs['allLinks']);
$a.on('click', function(event) {
event.preventDefault();
scope.$apply(function() {
var $this = angular.element(event.target);
fn(scope, {
$event: event,
$href: $this.attr('href'),
$link: $this
});
});
});
}
};
})
And then use it on some wrapper div or body tag like <body ng-controller="WrapperCtrl" all-links="ajaxLink($href)"> and then in your content div do <div id="content" ng-include="current_page_template">
In your angular controller set the current_page template to the document.URL and implement that ajaxLink function.
$scope.ajaxLink = function(path) {
$scope.current_page_template = path+"?nolayout=true";
}
And then when you get your JSON with your data from the server don't forget to use history.pushState to set the url line and document.title = to setr the title.
For a website, which doesn't use AJAX I'm using OnDocumentComplete event to know when the page loading is complete.
My question is, how can I detect when website, which uses AJAX requests is ready (e.g. when a website which is fetching some search results by using AJAX finished its work) ?
Ok here is a trick i developed my self.
1-in your html page make a div and set its text to "false".
2-in you server side put a javascript at the end of your returning code. for example your site returns following text upon an ajax call.
a
b
c
d
e
so after this text put a javascript code that will change the text of div from "false" to "true"
so what will happen is that once you receive all the data from ajax call you will also receive the javascript code and that code will run and set the value of div.
so in your page once all data is received you will see the indicator div. and you will know that you have received all data. you can also run functions in similar way upon completion of data.
Imagine I define video-type node, which displays for example a title and description, along with the video itself. And imagine I have a block of video teasers, where each teaser links to one such video node. And imagine this block is added to the bottom of any page displaying a video-type node: when the user clicks on one of the video teasers, the page reloads with a new video-type node.
Finally, imagine all of the above but without having to reload the full page.
If you go to http://whitehouse.gov/video, you will see what I am trying to accomplish. When you click on one of the video teasers, the url changes to the url for the new node, but the full page does not reload. Only the top section of the page, displaying the new node, gets reloaded.
My question: How do they do this?? How can I load the node content into a particular div on page, without reloading the entire page?
You can use hook_menu to implement a MENU_CALLBACK to it's own handler function in Drupal. You would return JSON or XML or an HTML fragment or whatever you want with the HTML for the new video. Then use JS to update the DOM with the new content received from the server. Updating the URL can be done with JS as well.
So basically you are going to handle video clicks on the client side with JS. The JS would make a request to your MENU_CALLBACK and you would receive whatever data you choose to implement back from the server. JS takes the data and updates the DOM.
With something like jQuery, you could use the $.get method and use the success attribute to update the window history in modern browsers.
This is probably going to get a resounding no, but I am wondering if it possible to have the URl change dynamically with using hashing, and without invoking a http request from the browser?
My client is keen on using AJAX for main navigation. This is fine, when the end user goes to the front page first, but when they want to use the deep linking, despite it working, it forces an extra load time as the page loads the front page, then invokes the AJAX from the hash.
UPDATE: Could it be possible, given that what I want to avoid is the page reload (the reason is that it looks bad) to stem the reload by catching the hash with PHP before the headers are sent, and redirecting before the page load. This way only one page loads, and the redirect is all but invisible to the user. Not sure how to do this, but seems like it is possible?
Yes, this is possible. I often do this to store state in the hash part of the URL. The result is that the page doesn't reload, but if the user does reload, they're taken to the right page.
Using this method, the URL will look like: "/index#page=home" or "/index#page=about"
You'll need to write a JavaScript function that handles navigation, and you'll need a containing div that gets rewritten with the contents fetched from AJAX.
Home
About
Questions
<div id="content"></div>
<script type="text/javascript">
function link(page) {
location.hash = "page="+page;
loadPage(page);
}
// NOTE: This is using MooTools. Use the AJAX method in whatever
// JavaScript framework you're using.
function loadPage(page) {
new Request.HTML({
url: "/ajax/"+page+".html",
onSuccess: function(tree, elements, html) {
document.id('content').setProperty('html', html);
}
}).get();
}
</script>
Now, you'll also need to have something that checks the hash on page load to load the right content initially. Again, this is using MooTools, but use whatever onLoad method your JavaScript framework provides.
<script type="text/javascript">
document.addEvent('domready', function() {
parts = location.hash.split('=');
loadPage(parts[1]);
}
</script>
Ok, the problem is that opening an AJAX link of the form http://example.com/#xyz results in a full page being downloaded to the browser, and then the AJAX-altered content is changed once the page has loaded and checked the hash part of its URL. The user has a diconcerting experience.
You can hugely improve this by making a page that just contains the static elements - menus, etc. - and a loading GIF in the content area. This page checks its URL upon loading and dynamically fetches the content specified by the hash part. The page can have any URL you want; we'll use http://example.com/a. Links to this page (http://example.com/a#xyz) now provide a good user experience for users with scripting enabled.
However, new users won't come to the site by fetching http://example.com/a; they'll fetch http://example.com. This is fine - serve the full page, including the home page content and links that don't require scripting to work (e.g., http://example.com/xyz). A script run on loading this page should alter the href of AJAXable links to their AJAX form (http://example.com/a#xyz); thus the first link a user clicks on will result in a full page load but subsequent ones won't.
The only remaining problem is is a no-script user gets sent an AJAX link. You can add a noscript block to the AJAX page that contains a message explaining the problem and provides a link back to the homepage; you could include instructions on how to enable scripting or even how to modify the link by removing a# and pressing enter.
It's not a great answer, but you can offer a different link in the page itself; e.g., if the address bar shows /#xyz you include a link to /xyz somewhere in the page. You could also add a link or button that uses script to bookmark the page, which would again use the non-AJAX form of the link.
I have a page where a user can upload a file along with some other input. Because I wanted this to be AJAX-like, I resorted to using an iFrame to accomplish this.
After the file is uploaded and an iFrame is loaded with a response page, I need to update a DIV outside of the iFrame with an AJAX call. The reason for separate updates, is that the result of the outside DIV depends on the input that the user provided with the file input.
Can this be done? Am I approaching this the wrong way?
Thank you!
UPD: Can the returned client code from within the iFrame "see" elements outside that iFrame?
Write your code in the onload event of the page loaded into the iframe. Then top will give you the top frame or parent will give you the parent frame.
Yes , it can be done. But you can do away with,the need for an AJAX-call , to update the outside the div.
Have your, servlet(assuming you are using JSP/servlets) that accepts the mutlipart request(the servlet that accepts the upload), return the intended response (to be shown on the refreshed iFrame), and ALONG WITH IT, the necessary information from the file input. This way you have all the necessary details on the client, in one response. A simple javascript function can achieve , updating the outer div with the information from the file input.