simple dijit widget fail to initiliaze with AMD programming - javascript

I am trying to accomplish simple tasks with dojo's new AMD feature, and I don't get an error on the screen neither the result is being displayed....
I wanted to rewrite the first programmatic example dijit.Tree mentioned in the dojo reference guide:
<script type="text/javascript">
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.Tree");
dojo.ready(function(){
var store = new dojo.data.ItemFileReadStore({
url: "{{dataUrl}}/dijit/tests/_data/countries.json"
});
var treeModel = new dijit.tree.ForestStoreModel({
store: store,
query: {"type": "continent"},
rootId: "root",
rootLabel: "Continents",
childrenAttrs: ["children"]
});
new dijit.Tree({
model: treeModel
}, "treeOne");
});
</script>
to the AMD version:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<link rel="stylesheet" href="js/dojo/dijit/themes/claro/claro.css" />
<script src="js/dojo/dojo/dojo.js" data-dojo-config="async: true"></script>
<script language="JavaScript">
var param = new Array(null,["dojo/dom","dijit/tree","dojo/data/ItemFileReadStore","dijit/tree/ForestStoreModel","dojo/domReady!"]);
require(param[1],function(dom,dtree,ifrs,fsm)
{
var store = new ifrs({url: "js/countries.json"});
var treeModel = new fsm({store: store,query: {"type": "continent"},rootId: "root",rootLabel: "Continents",childrenAttrs: ["children"]});
new dtree({model:treeModel},"treeOne");
});
</script>
</head>
<body class="claro">
<div id="treeOne">
</div>
</body>
</html>
Firebug doesn't whow me an runtime error, or doesn't tell me that something is missing. The page just stays empty. What did I make wrong?!

The main problem is how you build the param array and only use the first value in the array.
Also, dojo.ready is not the same as dojo/domReady!
require(["dojo/dom", "dijit/tree", "dojo/data/ItemFileReadStore",
"dijit/tree/ForestStoreModel", "dojo/ready"],
function(dom, dtree, ifrs, fsm, ready) {
ready(function() {
...
});
});

Related

Handlebars not displaying the content

So I am starting with Handlebars.js and I don't really know the ins and outs. Please be patient with me.
I have three files, test.html, test.js and data.js. I want test.html to display the data in data.js, through the Handlebars in test.js. However, no content can be seen. I think the solution probably lies in calling a function somewhere, but I don't know what function, nor where.
Here are the codes:
test.html
<head>
<script src="js/jquery.js">
</script>
<script src="js/handlebars-v3.0.3.js">
</script>
<script src="test.js">
</script>
<script src="data.js">
</script>
<script src="js/bootstrap.js">
</script>
<link href="css/bootstrap.css" rel="stylesheet">
<link href="css/gallery.css" rel="stylesheet">
</head>
<body>
<script id="image-templatexxx" type="text/x-handlebars-template">
{{name}}</br>
{{author}}</br>
<img style="height:600" src="{{src}}" />
</script>
<div id="test-content">
</div>
</body>
data.js
var testdata = {
src: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/The_Earth_seen_from_Apollo_17.jpg/600px-The_Earth_seen_from_Apollo_17.jpg ",
name: "The Earth seen from Apollo 17",
author: "Ed g2s"
};
test.js
var source = $("#image-templatexxx").html();
var testtemplate = Handlebars.compile(source);
var testhtml = testtemplate(testdata);
$('#test-content').html(testhtml);
Thanks a lot for this.
Please include data.js before test.js. Otherwise testdata is undefined at the time of generating the html string using handlebars. The below code
$(document).ready(function() {
var testdata = {
src: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/The_Earth_seen_from_Apollo_17.jpg/600px-The_Earth_seen_from_Apollo_17.jpg ",
name: "The Earth seen from Apollo 17",
author: "Ed g2s"
};
var source = $("#image-templatexxx").html();
var testtemplate = Handlebars.compile(source);
var testhtml = testtemplate(testdata);
$('#test-content').html(testhtml);
});
Works for me.

How could I pack all js files, CSS , embedded scripts into a js plugin

I wrote a JS plugin to client's website can load comments from our database via CORS method.
My goal is to wrapper my whole code into an easily embeddable plugin.
Just like the facebook js plugin, Google Analytics plugin. They are easy to install on a website.
My plugin depends on other libraries, such as jquery, underscore, backbone, handlebars, and also my scripts and CSS.
I studied Require.js it seems suitable to do this job for me.
I need to generate an all-in-one javascript plugin, e.g.,. "awesome-comments.min.js".
Some articles suggest me to put all the dependent js files with require.config.
But I'm having no idea how could I do other stuff such as my js scripts with require.js.
Is there any similar application or tutorial has the same function. Thanks.
sample_with_requireJS.html
<html>
<head>
<script src="js/require.js" data-main="js/main"></script>
</head>
<body>
<div id="load_awesome_comments"></div>
</body>
</html>
js/main.js
  require.config({
    baseUrl: "http://mywebsite/assets/",
    paths: {
      "jquery": "jquery-9e7b5a8e0157d7776b987d8963c9c786.js?body=1",
      "underscor": "~~~",
...
    }
  });
sample-without-requireJS.html (This is my current workable html sample, mixed with js, css and html DOM)
<html>
<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"/>
<script src="http://localhost:3001/assets/jquery-9e7b5a8e0157d7776b987d8963c9c786.js?body=1" data-turbolinks-track="true"></script>
<style>
body {
/*background-color: linen;*/
}
</style>
<script type="text/javascript">
$(document).ready(function() {
$(document).on('click','.show-more',function () {
var $this = $(this);
....
});
});
window.onload = function(){
.....
}
Handlebars.registerHelper('if_even', function(conditional, options) {
....
});
</script>
<!-- Setup our templates -->
</head>
<body>
<div id="load_awesome_comments"></div>
<script type="text/javascript">
$(document).ready(function() {
function hideFurtherComments(){
.....
}
var Comment = Backbone.Model.extend({
....
});
var Comments = Backbone.Collection.extend({
model: Comment,
url: fetch_comments_url,
initialize: function() {
....
},
deferred: Function.constructor.prototype,
fetchSuccess: function(collection, response) {
collection.deferred.resolve();
},
});
var comments = new Comments();
var CommentView = Backbone.View.extend({
el: $("#comments_section"),
render: function() {
....
},
});
var EmptyCommentView = Backbone.View.extend({
el: $("#empty_comments_list"),
render: function() {
....
},
});
var commentView = new CommentView({
collection: comments
});
var emptyCommentView = new EmptyCommentView({
collection: comments
});
comments.deferred.done(function() {
....
});
});
var og_url = $("meta[property='og:url']").attr("content");
$("#original_news_article_link").attr("href", og_url)
</script>
<script src="js/require.js" defer async="true" ></script>
</body>
</html>
Give a look at https://webpack.github.io and http://browserify.org/. Their purpose is to do exactly what you need. You pack all of your Javascript code, Javascript dependencies and CSS in one sole JavaScript file.
The advantage of this method is that users can make use of your module just by including a single JavaScript file; no need to worry about dependencies.
The drawback is that, given that the dependencies are all included in the single file, if in a page you have three modules packed this way that use jQuery, for example, the jQuery code will be downloaded three times.

Backbone.js: Run and display api results on keydown event

I am programming with Backbone.js I am trying to run an API request when the user types in a query in the search box. However nothing happens when I type in a query.
Here is my JAVASCRIPT:
$(function(){
var SearchList = Backbone.Collection.extend({
url: "https://api.nutritionix.com/v1_1/search/taco?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c",
initialize: function(){
this.bind("reset", function(model, options){
console.log("Inside event");
console.log(model);
});
},
//** 1. Function "parse" is a Backbone function to parse the response properly
parse:function(response){
//** return the array inside response, when returning the array
//** we left to Backone populate this collection
return response.hits;
}
});
// The main view of the application
var App = Backbone.View.extend({
initialize: function () {
this.model = new SearchList();
this.list = $('#listing');
},
el: 'document',
events: {
"keydown" : "prepCollection"
},
prepCollection: function(){
var name = $('input').val();
var newUrl = "https://api.nutritionix.com/v1_1/search/" + name + "?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c";
this.model.set("url", newUrl);
this.model.fetch({
success: function (response, xhr) {
console.log("Inside success");
console.log(response.toJSON());
},
ERROR: function (errorResponse) {
console.log(errorResponse)
}
});
this.listenTo(this.model, 'sync', this.render);
},
render: function(){
var terms = this.model;
terms.each(function (term) {
this.list.append("<li>" + term.get('field')["brand_name"] + "</li>")
}, this);
}
});
var app = new App();
});
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Interactive Food Guide</h1>
<div>
<input type="text" id="searchBox"> <br/><br/>
</div>
<ul id="listing"></ul>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Backbone and Underscore -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<!-- apps functionality -->
<script src="js/app.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
url is a property of the model, not an attribute. Think of attributes as things you might persist to the server.
Change:
this.model.set("url", newUrl);
To:
this.model.url = newUrl;
Note that url can also be a function which returns a string, and that there is a default function already there which works for some more typical REST cases: http://backbonejs.org/#Model-url
Also JS variables and object keys are case-sensitive, so your key should be error nor ERROR.
After running the project I noticed a couple of other things wrong:
el: 'document' - This is the whole document including the head, Backbone works with the body or things within it. Fix this by changing it to el: 'body'
You were trying to access the field attribute - it is actually called fields and you can access it like so term.get('fields').brand_name
Other bonus fixes: Clear the list before appending new results, _.throttle prepCollection so that if letters are typed fast then it will only do 2 searches (one at the beginning and one at the end of the input). Change to _.debounce to only do one search at the end of the input.
Fiddle: http://jsfiddle.net/ferahl/2nLezvmg/1/

backbone.js View event handling

I just started playing around with backbone.js and am enjoying the quirks of using it.
However am trying to use it for handling events in views for a site am working on.
Am also using namespaces to organise my code
var App = App || {};
App.Views = App.Views || {};
App.Views.Sidebar = Backbone.View.extend({
el: '#app-wrapper',
events : {
"click #rf":"test"
; },
test: function(e) {
alert("testing");
}
})
}
});
Heres the html, its just a skeleton of the site
<html>
<head>
<title>Shopping List</title>
<script type="text/javascript" src="jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="underscore.js"></script>
<script type="text/javascript" src="backbone.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript">
App.Views.Sidebar;
</script>
</head>
<body>
<div id="app-wrapper">
<div id="app-header">
<ul>
<li id="rf">Test</li>
</ul>
</div>
</div>
</body>
</html>
However this snippet doesn't seem to work, the test() method is not called when click the #rf element.
Am doing something wrong, am pretty new to this.
You have not instantiated your view. Try something like this:
var myView = new App.Views.Sidebar();
(instead of: App.Views.Sidebar; )
Also don't forget to instantiate your views once the document has been loaded. Something like this (if you use JQuery):
$(function() {
// Initialize Backbone views.
var myView = new App.Views.Sidebar();
});

Multiple google maps on a single page -- can only load one at a time

I'm very new to HTML and Javascript (less than a week of experience) and am stuck in the following situation. I created 6 google map visualizations using the googleVis package for R (simple stuff--just markers on a map). I've extracted the Javascript out of the googleVis objects in R and have included them in a simple site that contains 6 divs for each of the 6 different maps.
Each Javascript file includes a function to create a JSON object, a function to draw the map, and a function to display the map:
//define JSON
function gvisDataWest ()
{
var data = new google.visualization.DataTable();
var datajson =
[
[
33.5313,
-112.1774,
"<p>2005-2009 Poverty Rate: 40.7%</p> <p>2000 Poverty Rate: 34.3%</p> <p>Significant difference: 0.0 points </p>"
],
... many rows of data ...
];
data.addColumn('number','Latitude');
data.addColumn('number','Longitude');
data.addColumn('string','tip');
data.addRows(datajson);
return(data);
}
//draw chart
function drawChartWest() {
var data = gvisDataWest();
var options = {};
options["showTip"] = true;
options["enableScrollWheel"] = true;
options["width"] = 400;
var chart = new google.visualization.Map(
document.getElementById('West')
);
chart.draw(data,options);
}
//display chart
function displayChartWest()
{
google.load("visualization", "1", { packages:["map"] });
google.setOnLoadCallback(drawChartWest);
}
Each javascript file includes functions and data for a different region of the country (e.g. there would be definitions for gvisDataMidwest(), givsDataSouthEast(), etc.).
Here's roughly what my HTML looks like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta content="text/xml; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script src="../povscripts/map1.js" type="text/javascript"></script>
<script src="../povscripts/map2.js" type="text/javascript"></script>
<script src="../povscripts/map3.js" type="text/javascript"></script>
<script src="../povscripts/map4.js" type="text/javascript"></script>
<script src="../povscripts/map5.js" type="text/javascript"></script>
<script src="../povscripts/map6.js" type="text/javascript"></script>
</head>
<body>
...a bunch of divs, headers, <p>'s, etc...
...then six divs like this, each with an appropriate id:
<div class="anncdiv">
<div class="bannertitle">
<p class="btxt">West</p>
</div>
<div class="anncdivIn" id="West">
<script type="text/javascript"> displayChartWest() </script>
</div>
</div>
<div class="anncdiv">
<div class="bannertitle">
<p class="btxt">Midwest</p>
</div>
<div class="anncdivIn" id="Midwest">
<script type="text/javascript"> displayChartMidwest() </script>
</div>
</div>
THE PROBLEM: With the way I've currently cobbled this site together, if there are two dsplayChart**() functions being called anywhere on the site (as in this example, with displayChartWest() and displayChartMidwest()) all divs appear blank. But, if I were to just include one of these function calls, then the map displays fine in the appropriate div. Somehow calling two or more of these functions results in a conflict, though I just don't know why. Your help is GREATLY appreciated. Cheers, AR
I think you might need to wait until the DOM is loaded before firing up your charts. Without using a library like jQuery, you could do it using the body onload event:
<body onload="displayCharts()">
...page source...
<script type="text/javascript">
function displayCharts() {
displayChartWest();
displayChartMidwest();
}
</script>
</body>
Instead of doing this:
google.load("visualization", "1", { packages:["map"] });
google.setOnLoadCallback(drawChartWest);
try this instead:
google.load("visualization", "1", { packages:["map"],callback: drawChartWest});

Categories