How to get Twitter Bootstrap Twipsy to work with Backbone.js - backbone.js

I can't get twitter bootstrap's modal to work with backbone.js.
The backbone view works fine.
window.CaseView = Backbone.View.extend({
tagName: "tr",
render: function() {
var that = this;
var tmpl = $("#tmplCase").render(that.model.toJSON());
$(that.el).html(tmpl);
return this;
},
events: {
"hover #pp-12444" : "open"
},
open: function() {
//console.dir(this);
$('#pp-12444').twipsy('show');
},
...
The twitter bootstrap js modules have been correctly loaded.

Try to initialize twipsy first and only then show it:
$('#pp-12444').twipsy({'placement': 'above'}).twipsy('show');

Did you make sure to include the necessary attributes on your #pp-1244 element? In the twipsy bootstrap demo, the text to display is set in the data-original-title attribute on the element.

Related

Can't display Backbone/Underscore template in Jade view

I'm trying to link the template in my .jade view to my Backbone model, and it's just not displaying anything inside my template script.
My .jade view:
extends ../layout
block content
.page
script(type="text/template" id="createRecipeTemplate").
<div class="ingredients-pane">
<form id="ingredientForm">
*[form]*
</form>
*[etc.]*
</div>
script(src='/js/myBackboneFile.js')
myBackboneFile.js:
var Recipe = Backbone.Model.extend({
defaults: {*[defaults]*}
});
var Recipes = Backbone.Collection.extend({
url: '/api/recipes'
})
var recipes = new Recipes();
var RecipeView = Backbone.View.extend({
model: new Recipe(),
el: '.page',
initialize: function() {
this.template = _.template($('#createRecipeTemplate').html());
},
events: {
*[events]*
},
*[functions for my events]*,
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var RecipeView = new RecipeView();
Everything's linked up - if I type 'RecipeView' into the browser console, it gives me:
n {cid: "view2", $el: n.fn.init[1], el: div.page}
I've tried a few variations on the jade template syntax - putting pipes at the beginning of each line, using the dot after the script tag (as above), and just indenting normally (with the template in both standard HTML and Jade syntax each time), but no joy.
Am I missing something obvious?

Backbonejs with mustache template.

I want to do a simple application using backbonejs with mustache template. Can you give me a sample program??
New node file:
var Person = Backbone.Model.extend({
defaults: {
name: 'Guest Worker',
}
});
var PersonView = Backbone.View.extend({
tagName: 'li',
initialize: function(){
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
this.render();
},
render: function(){
var template1 = _.template("Hello {{ name }}!");
this.$el.html( this.template1(this.model.toJSON()));
}
});
This is my js code.
Mustache template engine doesn't work this way. Here's a small example from the documentation :
var view = {
title: "Joe",
calc: function () {
return 2 + 4;
}
};
// output will then contain processed html
var output = Mustache.render("{{title}} spends {{calc}}", view);
Anyway, i would recommend you using Handlebars (http://handlebarsjs.com/) instead of Mustache. It's almost the same syntax (and it has partials as Mustache does), but far more powerful thanks to its helpers.
Finally, you should use something to precompile your templates. You can either use handlebars's one (http://handlebarsjs.com/precompilation.html) or another one like Brunch, or Grunt.
[Edit] OK, let's try to elaborate a bit... I won't give you any complete example (i don't have one right now, and it wouldn't teach you anything), but the one i posted above should be sufficient to understand Mustache basics.
Now you have to find a way to precompile your templates, here's an answer with some clues : How to load templates with Hogan.JS from an external file?
While an underscore template is set like this in Backbone.js:
template: _.template(...)
A mustache template is set like this:
template: Mustache.render.bind(null,<template>)
//Mustache.render(template,view,[partials])
//a partial function is created because this.template should be a function
//<function>.bind() creates the partial function
don't do these:
template: Mustache.to_html(<template>) // deprecated
// or
template: Mustache.to_html.bind(null,<template>) // deprecated
// Use Mustache.render() and not Mustache.to_html()

How to render a backbone collection into two views

I am using twitter bootstrap link. When the user clicks the link a bootstrap modal appears.
Now because of some bootstrap technical difficulties in modal rendering i need to seperate the link and put the modal out the navbar div.
So consider i have two separate div
<div id="linkDiv">
</div>
and
<div id="modalDiv">
</div>
Now i have only one View which makes a call to the server to get the collection
app.View.FriendRequestListView = Backbone.View.extend( {
templateModalLink: _.template($('#link').html()),
templateModal: _.template($('#modal').html()),
tagName: 'div',
initialize: function(){
this.friendRequestCollection = new app.Collection.FriendRequestCollection();
this.friendRequestCollection.bind("reset", this.render, this);
this.friendRequestCollection.fetch();
},
render: function() {
$(this.el).html(this.templateModalLink({
friendRequestCollection: this.friendRequestCollection}));
return $(this.el);
},
});
Than i can render only one div like following
var list = new app.View.FriendRequestListView();
$('#linkDiv').html(list.$el);
My question is , Is it possible to render two templates at the same time and add the two templates to different DIV like for example in my case i want to get update
templateModalLink template to linkDiv and templateModal template to modalDiv with the collection I am getting from the server.
You have to instantiate the collection before app.View.FriendRequestListView(s) and pass app.View.FriendRequestListView(s) the collection:
var friendRequests = new app.Collection.FriendRequestCollection();
friendRequests.fetch(
success: function(collection, response, options) {
var list1 = new app.View.FriendRequestListView({collection: collection});
var list2 = new app.View.FriendRequestListView({collection: collection});
$('#linkDiv').html(list1.$el);
$('#modalDiv').html(list2.$el);
}
);

Tabs in Backbone

I'm new with Backbone and I'm making an example app in which I have to include tabs. The thing is that I have a collection of cities and I want to create one tab for each city (the collection fetchs from the server). I made a view called TabsView, which in the render function passes the collection to a template, and this one loops through the collection and renders the tabs.
What I want to do is that the first tab appears as 'active'. What I've done for the moment is that each tab has a href to a route in the router which changes it's class to active using jquery. Don't know if this is the best way to do this but it works. Maybe there's a better way. Also, when the user clicks a tab, I want to be able to render other view.
Hope I made myself clear. Thanks, cheers,
Martin
Ok I solved this problem doing something like the following:
var Tabs = Backbone.View.extend({
template: JST['tabs'],
events: {
'click li' : 'switchTab'
},
tagName: 'ul',
className: 'nav-tabs',
render: function() {
this.renderTabs();
return this;
},
renderTabs: function() {
this.$el.html(this.template({ cities: this.cities }));
this.$('li:first').addClass('active');
},
switchTab: function(event) {
var selectedTab = event.currentTarget;
this.$('li.active').removeClass('active');
this.$(selectedTab).addClass('active');
}
});
It works fine, maybe it can be improved.

Using Handlebars with Backbone

I am learning Backbone/Handlebars/Require. I have looked all over online and on SO - are there any tutorials or websites that you can direct me to that would provide helpful information for using using handlebars instead of underscore?
Using handlebars.js instead of underscore templating is pretty straightforward. Check out this example:
https://cdnjs.com/libraries/backbone.js/tutorials/what-is-a-view
(scroll to the "Loading a Template" section)
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
// Compile the template using underscore
var template = _.template( $("#search_template").html(), {} );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
}
});
Basically, the convention in backbone is to build your html in a render function. The use of templating engine is left completely up to you (which I like about Backbone). So you'd just change it to:
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
// Compile the template using Handlebars
var template = Handlebars.compile( $("#search_template").html() );
// Load the compiled HTML into the Backbone "el"
this.el.html( template );
}
});
Since you're using require.js, you can make Handlebars a dependency at the top of your module. I'm pretty new to this, but it sounds like the learning to focus on would be Backbone.js patterns and require.js usage.
I would prefer to compile the template once (during initialize), that way you avoid to recompile the template with every render. Also, you need to pass the model to the compilated template in order to generate the HTML:
SearchView = Backbone.View.extend({
initialize: function(){
// Compile the template just once
this.template = Handlebars.compile($("#search_template").html());
this.render();
},
render: function(){
// Render the HTML from the template
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
If you are using require.js you wont be able to use the current Handlebars file. I used the following Handlebars Plugin and it seems to be kept up to date with the current version. Just replace your Handlebars file with the plugin above if Handlebars is returning null in your module.
define(["app", "handlebars",
"text!apps/templates/menu.tpl"
], function (app, Handlebars, template) {
return {
index: Marionette.ItemView.extend({
template: Handlebars.compile(template),
events: {
'click .admin-menu-ref': 'goToMenuItem'
},
goToMenuItem: function (e) {
//......
}
})
}
});
new view.index({model: models});

Resources