Lazy load json data from template engine (handlebars) - javascript

I am trying to lazy load content that I am getting from a json file using handlebars.js as a template engine.
I want to lazy load each .projects-list div on scroll.
Here is my code.
HTML:
<div class="projects-list">
<script id="projects-template" type="text/x-handlebars-template">​
{{#each this}}
<h1>{{name}}</h1>
<img class="lazy" src="{{image.small}}" height="130" alt="{{name}}"/>
<img class="lazy" data-src="{{image.small}}" height="130" alt="{{name}}"/>
{{/each}}
</script>
</div>
JS:
$(function () {
// Get project data from json file.
$.getJSON("projects.json", function (data) {
// Write the data into our global variable.
projects = data;
// Call a function to create HTML for all the products.
generateAllProjectsHTML(projects);
});
// It fills up the projects list via a handlebars template.
function generateAllProjectsHTML(data) {
var list = $('.projects-list');
var theTemplateScript = $("#projects-template").html();
//Compile the template​
var theTemplate = Handlebars.compile(theTemplateScript);
list.append(theTemplate(data));
}
$('.lazy').lazy({
effect: "fadeIn",
effectTime: 5000,
threshold: 0
});
});
JSON:
[
{
"id": 1,
"name": "Example Name 1",
"image": {
"small": "assets/images/example1.jpg",
"large": "assets/images/example2.jpg"
}
},
{
"id": 2,
"name": "Example Name 2",
"image": {
"small": "assets/images/example3.jpg",
"large": "assets/images/example4.jpg"
}
}
]
I am trying to use this plugin: http://jquery.eisbehr.de/lazy/ but I am open to any suggestions.
Thanks for taking the time to look, any help is greatly appreciated!

The problem seems to be the order of your script and the timings. It would be a race-condition. You should initialize Lazy right after the template has been loaded. That should solve the behavior.
You can even compress your script. And remove the jQuery ready states in the script, it is not needed here.
So the result would look like this:
$.getJSON("projects.json", function(data) {
var theTemplateScript = $("#projects-template").html();
var theTemplate = Handlebars.compile(theTemplateScript);
$("#projects-list").append(theTemplate(data));
$(".lazy").lazy({
effect: "fadeIn",
effectTime: 5000,
threshold: 0
});
});

Related

Add script to inside of vue template

I need insert script like this
<div data-player-id="912d05c">
<script src="//cdn.flowplayer.com/players/7/flowplayer.async.js">
{
"src": "https://s3.amazonaws.com/69693f173770c49cbb5.mp4"
}
</script>
</div>
to inside of html under the vue.
So I found that I need to generate script tag by js but I'm not sure how to add
{
"src": "https://s3.amazonaws.com/69693f173770c49cbb5.mp4"
}
to this script tag
Code what I have (simplified):
<div id="app">
<div id="videocontent"></div>
</div>
el: "#app",
data: {},
created: function() {
let playerContainer = document.createElement('div');
playerContainer.setAttribute('data-player-id','912d05c');
let flowplayerScript = document.createElement('script');
flowplayerScript.setAttribute('src', '//cdn.flowplayer.com/players/7/flowplayer.async.js');
flowplayerScript.innerText = {"src": "https://s3.amazonaws.com/productionadgate_video/eceae5886caaf69693f173770c49cbb5.mp4"};
playerContainer.append(flowplayerScript);
let container = document.getElementById('videocontent');
container.append(playerContainer);
}
and flowplayerScript.innerText = {"src": "https://s3.amazonaws.com/productionadgate_video/eceae5886caaf69693f173770c49cbb5.mp4"}; is not correclty injected and player is always loading but not showing videos. Also I was tried tu use:
flowplayerScript.onload = function(){
return {
"src": "https://s3.amazonaws.com/productionadgate_video/eceae5886caaf69693f173770c49cbb5.mp4"
}
};
but still not working :( and I'm getting the error like:
SyntaxError: Unexpected token $ in JSON at position 0 flowplayer.async.js:2
You can use pure JavaScript installation, then init flowplayer in 'mounted' method.
new Vue({
el: "#app",
mounted: function() {
this.$nextTick(function() {
// select the above element as player container
let containerEl = document.getElementById("videocontent")
// install flowplayer into selected container
flowplayer(containerEl, {
clip: {
sources: [
{ type: "application/x-mpegurl",
src: "//mydomain.com/video.m3u8" },
{ type: "video/mp4",
src: "//mydomain.com/video.mp4" }
]
}
})
})
}
})
jsfiddle

JSDOM not loading script files in Node

I am trying to do a test of loading up an html page in jsdom which will eventually generate graphs. I cannot overcome the first hurdle of just loading the html page and having the javascript execute.
Below is my html page which I am trying to load which doesnt take any parameters and just renders a simple graph.
<html>
<head>
<script src="http://code.jquery.com/jquery.min.js"/>
<script src="http://static.fusioncharts.com/code/latest/fusioncharts.js"/>
<script src="http://static.fusioncharts.com/code/latest/fusioncharts.charts.js"/>
<script src="http://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js"/>
<script>
var testVar = true;
function test(){
testVar = false;
};
</script>
<script>
$(document).ready(function(){
FusionCharts.ready(function () {
var revenueChart = new FusionCharts({
type: 'column2d',
renderAt: 'container',
width: '400',
height: '200',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Split of Revenue by Product Categories",
"subCaption": "2014",
"numberPrefix": "$",
"theme": "fint",
"captionFontSize": "13",
"subcaptionFontSize": "12",
"subcaptionFontBold": "0",
"showValues": "0"
},
"data": [{
"label": "Food",
"value": "28504"
}, {
"label": "Apparels",
"value": "14633"
}, {
"label": "Electronics",
"value": "10507"
}, {
"label": "Household",
"value": "4910"
}]
}
}).render();
});
var svg = $('#container').html();
});
</script>
<head>
<body>
<div id="container">Charts will render here</div>
</body>
Here is the code in node where I am trying to load this page..
var config = {
file: path.join(__dirname, "chart.html"),
features:{
FetchExternalResources: ["script"],
ProcessExternalResources: ["script"],
MutationEvents: '2.0'
},
scripts:[
"http://code.jquery.com/jquery.min.js",
"http://static.fusioncharts.com/code/latest/fusioncharts.js",
'http://static.fusioncharts.com/code/latest/fusioncharts.charts.js',
"http://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js"
],
onload: function(err, window) {
console.log('*******onload')
},
created: function(err, window) {
console.log('*******created')
},
done: function(err, window) {
console.log('*******done')
if(err){
console.log('*****got err ' + err.message);
callback(err);
}
global.window = window;
console.log('inside done ----------')
var $ = window.jQuery || window.$,
FusionCharts = window.FusionCharts,
document = window.document;
if(typeof FusionCharts == 'undefined')
console.log('FusionCharts NOT LOADED')
else
console.log('FusionCharts LOADED')
if(typeof $ == 'undefined')
console.log('JQUERY NOT LOADED')
else
console.log('JQUERY LOADED')
console.log('testVar ' + window.testVar)
console.log(window.test())
console.log('testVar ' + window.testVar)
console.log('svg is ' + window.svg);
console.log($('#container').html());
window.close();
}
}
jsdom.env(config);
The strange thing here is that if i do not include scripts in the config object, it will not load them and make them available in the done callback even thought it is there on the html page.
Also, testVar is never defined in the callback even thought it is present in the page, the same with window.test(), even though its in the html page it just does not seem to be available in the callback.
I have tried all different variations of creating the jsdom object, but none of them allows the page to load the scripts rather than me passing it into the config object, and none of the different versions allow me to access variables and functions defined in the script tags.
Is there something I am missing ?
Change your script elements so that they are correct HTML:
<script src="http://code.jquery.com/jquery.min.js"></script>
If you do that everything will load fine and you won't have to use scripts in your configuration.

How can we consume JSON data using OPENUI5/SAPUI5?

I am new to SAPUI5/OPENUI5.
I am trying out a sample program to consume json data from a domain and display it in my openui5 table. I have tried two methods to get the data and bind it to table control.But I am not able to generate the table with the json data.
Please let me know my mistake in the code.
And also please refer me some links to understand the concept in a better way.
Thanks in advance.
Please find the two approaches below :
JSON Data :
[
{
"name": "Rajesh"
},
{
"name": "Kunal Jauhari"
},
{
"name": "Ashish Singh"
},
{
"name": "Ansuman Parhi"
},
{
"name": "Arup Kumar"
},
{
"name": "Deepak Malviya"
},
{
"name": "Seshu"
},
{
"name": "Ankush Datey"
},
{
"name": "Tapesh Syawaria"
},
{
"name": "Mahesh"
},
{
"name": "Vinay Joshi"
},
{
"name": "Ardhendu Karna"
},
{
"name": "Abhishek Shukla"
},
{
"name": "Kashim"
},
{
"name": "Vinayak"
}
]
Approach 1 : I am using a php file to echo the JSON data and use it in my ui5 screen.
When I access the run the php file individually, it generates the data and prints the data on screen.
Error I get is getJSON is not called.
Code :
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.commons,sap.ui.table"
data-sap-ui-theme="sap_bluecrystal">
</script>
<!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required -->
<script>
var json_url = "http://mydomain/teamdetails_ui5.php?t=6";
$.ajax({
url : json_url,
jsonpCallback : 'getJSON',
contentType : "application/json",
dataType: 'jsonp',
success: function(data,textStatus,jqXHR) {
oModel.setData({data: data});
sap.ui.getCore().setModel(oModel);
var oTable1 = new sap.ui.table.Table({
title : "Players List",
visibleRowCount : 3,
selectionMode : sap.ui.table.SelectionMode.Single,
navigationMode : sap.ui.table.NavigationMode.Paginator,
});
//Define the columns and the control templates to be used
oTable1.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({
text : "Player Name"
}),
template : new sap.ui.commons.TextView().bindProperty(
"text", "name"),
width : "10px"
}));
oTable1.setModel(oModel);
oTable1.bindRows("/oModel");
oTable1.placeAt('table_cont');
},
error : function(jqXHR,textStatus,errorThrown) {
alert("Oh no, an error occurred");
alert(jqXHR);
alert(textStatus);
alert(errorThrown);
}
});
</script>
</head>
<body class="sapUiBody" role="application">
<div id="table_cont"></div>
</body>
</html>
Approach 2 : I am trying to access the JSON file directly on my domain and access the data.
Code is the same as above except url.
Url is used for this approach is (mydomain/players.json) where players.json contain the above json data.
Please help me in understanding the concept of JSON data handling.
Regards,
Rajan
First of all: SAPUI5 is built onto jQuery, yes. But there should be no need to use jQuery inside your SAPUI5 Application.
Use a JSONModel to load JSON-Data. Also the JSONModel can load the data from URL.
See the Documentation
this will look like:
// create a "json" Model
var oModel = new sap.ui.model.json.JSONModel();
// load data from URL
oModel.loadData('http://mydomain/teamdetails_ui5.php?t=6');
after this you can register this model in your sap.ui.core with:
sap.ui.getCore().setModel(oModel);
after this line every control can use the data from this model by simple binding-syntax.
Now lets create the table:
// create your table
var oTable1 = new sap.ui.table.Table({
title : "Players List",
visibleRowCount : 3,
selectionMode : sap.ui.table.SelectionMode.Single,
navigationMode : sap.ui.table.NavigationMode.Paginator,
// bind the core-model to this table by aggregating player-Array
rows: '{/player}'
});
beware of the part with "rows: '{/player}'". This is the only thing that has to be done to get the data from the model inside your table.
now finish the demo by adding the column and add the table to the DOM:
// define the columns and the control templates to be used
oTable1.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({
text : "Player Name"
}),
template : new sap.ui.commons.TextView({
text: '{name}'
}),
width : "10px"
}));
//place at DOM
oTable1.placeAt('content');
Thats it. If it doesn't work, here is a running DEMO.

Change Jquery animimation dynamically

I am trying to change kernburns slideshow after the page loading, for example after pressing a button.
This is the code of http://jsfiddle.net/s4C5K/1/
HTML CODE:
<div id="kenburns-slideshow"></div>
<div id="kenburns-description">
<h1 id="status">Loading Images..</h1>
<h1 id="slide-title"></h1>
<h1 class="title"><a href="http://www.github.com/toymakerlabs/kenburns/" target="blank">Kenburns.js
</a></h1>
<p>Kenburns.js is a lightweight and flexible Jquery gallery plugin that loads images and features an animated, pan-and-zoom, Ken Burns style effect. Grab the source from my Github</p>
</div>
<button onclick="slidechange()">New slide</button>
JS CODE:
the code simply initiate the slideshow. The function slidechange() empties the div and change the "images" variable and redo the operations:
var titles = ["Epic Day at Refugio",
"Colors of Spring",
"First Flowers",
"Magic Hour at Sands Beach",
"Coal Oil Point",
"Hope Ranch Views"];
$(document).ready(function() {
$('#kenburns-slideshow').Kenburns({
images: [
"http://www.toymakerlabs.com/kenburns/images/image0.jpg",
"http://www.toymakerlabs.com/kenburns/images/image1.jpg",
"http://www.toymakerlabs.com/kenburns/images/image2.jpg",
"http://www.toymakerlabs.com/kenburns/images/image3.jpg",
"http://www.toymakerlabs.com/kenburns/images/image4.jpg",
"http://www.toymakerlabs.com/kenburns/images/image5.jpg" ],
scale:0.75,
duration:8000,
fadeSpeed:1200,
ease3d:'cubic-bezier(0.445, 0.050, 0.550, 0.950)',
onSlideComplete: function(){
$('#slide-title').html(titles[this.getSlideIndex()]);
},
onLoadingComplete: function(){
$('#status').html("Loading Complete");
}
});
});
function slidechange() {
$('#kenburns-slideshow').empty();
$('#kenburns-slideshow').Kenburns({
images: [
"http://static2.wikia.nocookie.net/__cb20070903093660/nonciclopedia/images/thumb/c/cf/Fini.jpg/200px-Fini.jpg",
"http://www.caffettieragiornaliera.it/wp-content/gallery/signor-boh/boh-facebook.gif",
"http://www.lanostratv.it/wp-content/uploads/2013/01/rai-boh-flop-facchinetti.jpg",
],
scale:0.75,
duration:8000,
fadeSpeed:1200,
ease3d:'cubic-bezier(0.445, 0.050, 0.550, 0.950)',
onSlideComplete: function(){
$('#slide-title').html(titles[this.getSlideIndex()]);
},
onLoadingComplete: function(){
$('#status').html("Loading Complete");
}
});
};
It does not work without errors.
<div id="kenburns-slideshow"><div id='foo'></div></div>
Inserted new div inside. Leaving his parent as placeholder.
Then on button click
Completley remove old div.
$('#foo').remove();
Then create same element and attach Kenburns library to it.
$("<div></div>").attr("id","foo").appendTo("#kenburns-slideshow").Kenburns({});
(with your settings in example)
As Marius wrote:
var titles = ["Epic Day at Refugio",
"Colors of Spring",
"First Flowers",
"Magic Hour at Sands Beach",
"Coal Oil Point",
"Hope Ranch Views"];
$(document).ready(function() {
$("<div></div>").attr("id","newdiv").appendTo("#kenburns-slideshow").Kenburns({
images: [
"http://www.toymakerlabs.com/kenburns/images/image0.jpg",
"http://www.toymakerlabs.com/kenburns/images/image1.jpg",
"http://www.toymakerlabs.com/kenburns/images/image2.jpg",
"http://www.toymakerlabs.com/kenburns/images/image3.jpg",
"http://www.toymakerlabs.com/kenburns/images/image4.jpg",
"http://www.toymakerlabs.com/kenburns/images/image5.jpg" ],
scale:0.75,
duration:8000,
fadeSpeed:1200,
ease3d:'cubic-bezier(0.445, 0.050, 0.550, 0.950)',
onSlideComplete: function(){
$('#slide-title').html(titles[this.getSlideIndex()]);
},
onLoadingComplete: function(){
$('#status').html("Loading Complete");
}
});
$('#mybutton').click(slidechange);
function slidechange() {
$('#kenburns-slideshow #newdiv').remove();
$("<div></div>").attr("id","newdiv").appendTo("#kenburns-slideshow").Kenburns({
images: [
"http://static2.wikia.nocookie.net/__cb20070903093660/nonciclopedia/images/thumb/c/cf/Fini.jpg/200px-Fini.jpg",
"http://www.caffettieragiornaliera.it/wp-content/gallery/signor-boh/boh-facebook.gif",
"http://www.lanostratv.it/wp-content/uploads/2013/01/rai-boh-flop-facchinetti.jpg",
],
scale:0.75,
duration:8000,
fadeSpeed:1200,
ease3d:'cubic-bezier(0.445, 0.050, 0.550, 0.950)',
onSlideComplete: function(){
$('#slide-title').html(titles[this.getSlideIndex()]);
},
onLoadingComplete: function(){
$('#status').html("Loading Complete");
}
});
};
});
See the above solution at: http://jsfiddle.net/s4C5K/3/

Backbone JS multiple level navigation example

I'm trying to construct a solid Backbone JS experiment, where I have a local JSON data file which contains my pages (a project I'm doing has this sort of requirement anyhow). And I've coded this example so I can have endless nested subpages in the pages data. It seems to be working great. But when it comes to the URLs, I'm a little stuck.
How do I approach giving this multiple level navigation example totally dynamic URLs? What I mean is, correctly using the url property of the models and collections to construct the right URLs for all the top level and nested elements. Is it even possible? I just can't think how to do it.
See a live demo of where I am now:
http://littlejim.co.uk/code/backbone/multiple-level-navigation-experiment/
Just so it's easier, the source code is below...
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Multiple Level Navigation Experiment</title>
<script type="text/javascript" src="../../media/scripts/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="../../media/scripts/underscore-min.js"></script>
<script type="text/javascript" src="../../media/scripts/backbone-min.js"></script>
<script type="text/javascript" src="application.js"></script>
<script type="text/javascript">
// wait for the DOM to load
$(document).ready(function() {
App.initialize();
});
</script>
</head>
<body>
<div id="header">
<h1>Multiple Level Navigation Experiment</h1>
<p>Want to get this page structure pulled from JSON locally and have a fully functional multiple level nested navigation with correct anchors.</p>
</div>
<div id="article">
<!-- dynamic content here -->
</div>
</body>
</html>
content.json
{
"pages": [
{
"id": 1,
"title": "Home",
"slug": "home"
},
{
"id": 2,
"title": "Services",
"slug": "services",
"subpages": [
{
"id": 1,
"title": "Details",
"slug": "details",
"subpages": [
{
"id": 1,
"title": "This",
"slug": "this"
},
{
"id": 2,
"title": "That",
"slug": "that"
}
]
},
{
"id": 2,
"title": "Honest Service",
"slug": "honest-service"
},
{
"id": 3,
"title": "What We Do",
"slug": "what-we-do"
}
]
},
{
"id": 3,
"title": "Contact Us",
"slug": "contact-us"
}
]
}
application.js
// global app class
window.App = {
Data: {},
Controller: {},
Model: {},
Collection: {},
View: {},
initialize : function () {
$.ajax({
url: "data/content.json",
dataType: "json",
success: function(json) {
App.Data.Pages = json.pages;
new App.Controller.Main();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
}
// main controller class
// when called it should have 'data' in JSON format passed to it
App.Controller.Main = Backbone.Controller.extend({
initialize: function() {
var pagesCollection = new App.Collection.Pages(App.Data.Pages);
var pagesView = new App.View.Pages({collection: pagesCollection});
$('#article').html(pagesView.render().el);
}
});
// pages model class
App.Model.Page = Backbone.Model.extend({
initialize: function() {
if (!_.isUndefined(this.get("subpages"))) {
this.subpages = new App.Collection.Pages(this.get("subpages"));
} // end if
this.view = new App.View.Page({model: this});
},
});
// page collection class
App.Collection.Pages = Backbone.Collection.extend({
model: App.Model.Page
});
// single page view class
App.View.Page = Backbone.View.extend({
tagName: "li",
initialize: function() {
_.bindAll(this, "render");
},
render: function() {
$(this.el).html(_.template("<%=title%>", {title: this.model.get("title")}));
return this;
}
});
// multiple pages view class
App.View.Pages = Backbone.View.extend({
tagName: "ul",
initialize: function() {
_.bindAll(this, "render");
},
render: function() {
var that = this;
this.collection.each(function(page) {
$(that.el).append(page.view.render().el);
if (!_.isUndefined(page.subpages)) {
var subpagesView = new App.View.Pages({collection: page.subpages});
$(that.el).append(subpagesView.render().el);
} // end if
});
return that;
}
});
I'm just needing so right direction on how to do the URLs properly. The idea I'm wanting is that I can setup my controller for routes so it can expect any page of any nested level. The models, collections and nested collections should be able to generate their URLs on their own, but the hash URL must reflect the level.
Ideally, this navigation would go to URLs like these:
http://example.com/#pages/services
http://example.com/#pages/services/details
http://example.com/#pages/services/details/this
...the URLs using the "slug" from the content.json data. Does any of this make sense? I'm pretty new to Backbone JS and just want to do things right.
Thanks, James
Here's my favorite solution to this problem: use PathJS !
Why not just parse out the slug?
So you can have a single route in the Backbone.Controller that looks like this:
'pages/:id' : showPage
And then showPage looks like:
showPage(id) : function(id) {
parse out the string 'services/details/etc'
look up the slug data based on that IE pages['services']['details']['etc']
}
or if the pages actually need to be processed differently, you can setup multiple routes, ever more granular like this:
'pages/:id' : showPage
'pages/:id/:nest' : showNestedPage
'pages/:id/:nest/:more' : showNestedMorePage

Categories