fetching data and show them in proper place in backbone - backbone.js

I have an issue in backbone, I want to render 100 rows of data from backend ( fetched by url) and show between of button element and pagination. I have created two templates, and have two views one for the whole page and the other for individual items. But when I fetch the data they do not go between the button and pagination div, all the 100 rows go under that. How can I put them in proper place? These are my templates:
the list template:
<div class="message-list-actions">
<div class="action">
<select>
<option value="0">Bulk Actions</option>
<option value="1">Delete</option>
<option value="2">Mark As Read</option>
</select>
<button class="grey">OK</button>
</div>
<div class="action">
<select>
<option value="0">All</option>
<option value="1">Unread Messages</option>
<option value="2">Read Messages</option>
</select>
<button class="grey">OK</button>
</div>
<div class="results right">
<form>
<label for="results">Results pr. page</label>
<select name="results">
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="500">500</option>
</select>
</form>
</div>
</div> <!-- message-list-actions -->
<div class="message-list">
<div class="message-list-header row">
<div class="left check">
<input type="checkbox" name="type"/>
<label for="type">CHECK ALL</label>
</div>
<div class="left date" >
<span class="sorter">Date</span>
</div>
<div class="large-9 columns" >
<span class="sorter">Message</span>
</div>
</div>
<section class="message-item row">
<div class="message-list"></div>
<div class="left check" >
<input type="checkbox" class="type">
</div>
<div class="left date" >
<div class="icon"></div>
</div>
<div class="large-9 columns" >
</div>
</section>
<section>
<ul class="pagination">
<li class="arrow unavailable">Previous</li>
<li class="current">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li class="unavailable">…</li>
<li>12</li>
<li>13</li>
<li class="arrow">Next</li>
</ul>
</section>
other template:
<div class="message-list">
<section class="message-item row">
<div class="left check" >
<input type="checkbox" class="type">
</div>
<div class="left date" >
<p><%= created !== undefined ? created : "not available" %></p>
<div class="icon"></div>
<div class="severity normal"><%= name %></div>
</div>
<div class="large-9 columns" >
<h4><%= title %></h4>
<p><%= id %></p>
</div>
<!-- Delete -->
</section>
</div> <!-- .main -->
//view for message:
define([
"jquery",
"underscore",
"backbone",
"js/collections/messagesCollection",
"js/models/messagesModel",
"text!templates/messageView.html",
"text!templates/messageList.html",
"text!templates/messageDetails.html"
], function($, _ , Backbone,
MessagesCollection,
MessagesModel,
UserEditTemplate, UserViewTemplate, UserSelfEditTemplate, ResetPasswordTemplate, ChangePasswordTemplate){
MessageViewTemplate, MessageListTemplate, MessageDetailsTemplate){
var MessageView = Backbone.View.extend({
tagName : "div",
messageViewTemplate : _.template(MessageViewTemplate),
messageDetailsTemplate : _.template(MessageDetailsTemplate),
template : _.template(MessageDetailsTemplate),
collection : MessagesCollection,
initialize : function(){
this.model.on("change", this.render, this);
this.model.on("update", this.render, this);
},
render : function(){
//this.$el.html(this.userTemplate(this.model.toJSON()));
this.$el.html(this.messageViewTemplate(this.model.toJSON()));
return this;
}
});
return MessageView;
});
View for list of message:
define([
"jquery",
"underscore",
"backbone",
"js/models/loggedInUserModel",
"js/models/currentTabModel",
"js/models/messagesModel",
"js/collections/messagesCollection",
"js/views/messageView",
"text!templates/messageList.html",
"text!templates/messageDetails.html",
"text!templates/header.html",
"text!templates/breadcrumbs.html",
"text!templates/footer.html"
], function($, _, Backbone,
MessagesModel,
MessagesCollection,
MessageView,
MessageListTemplate, MessageDetailsTemplate, HeaderTemplate, BreadCrumbTemplate, FooterTemplate
){
var MessagesView = Backbone.View.extend({
el : $("#maincontent"),
messageListTemplate : MessageListTemplate,
messageDetailsTemplate : _.template(MessageDetailsTemplate),
collection : MessagesCollection,
initialize : function(){
console.log("initialize messages");
this.collection = new MessagesCollection();
this.collection.on("add", this.renderMessage, this);
this.collection.on("reset", this.render, this);
this.collection.on("update", this.render, this);
if(this.options.selfEdit === false || _.isUndefined(this.options.selfEdit)){
this.start();
}
else{
console.log("options", this.options);
this.currentUserModel.fetch();
}
},
start : function(){
this.collection.fetch();
this.currentUserModel.fetch();
this.renderFooter();
},
render : function(){
this.$el.html(this.messageListTemplate);
_.each(this.collection.models, function(item){
this.renderMessage(item);
}, this);
},
renderMessage : function(item){
var messageView = new MessageView({
model : item
});
this.$el.append(messageView.render().el);
},
renderMessageDetails : function(item){
var messageView = new MessagesView({
model : item
});
this.$el.append(messageView.renderSelfView().el);
}
});
return MessagesView;
});
//Model
define([
"jquery",
"underscore",
"backbone"
], function($, _ , Backbone){
var MessagesModel = Backbone.Model.extend({
defaults : {
id : null,
created : null,
timestamp : null,
severity : null
},
parse : function(response){
response.id = response._id.$oid;
response.created = response.created.$date;
response.timestamp = response.timestamp.$date;
response.severity = response.severity;
return response;
},
clear : function(){
this.destroy();
this.view.remove();
},
// Convert regular JSON into MongoDB extended one.
toExtendedJSON: function() {
var attrs = this.attributes;
attrs = _.omit(attrs, ["created", "timestamp"]);
if (_.isUndefined(attrs.created)) {
// console.log("this", this["this.created"]);
attrs.created = { $date: this.get("created") };
}
if (_.isUndefined(attrs.timestamp)) {
attrs.timestamp = { $date: this.get("timestamp") };
}
console.dir(attrs);
return attrs;
},
// Substute toJSON method when performing synchronization.
sync : function(method, model, options) {
/*
* If we are performing an update we need to call the extendedJSON method
* By calling this, we guarantee that we comply to the MongoDB model.
* After applying that model, we then call Backbone .sync protoryp and then set the model.toJSON method
* back to its original definition.
*/
if(method === "update" && !model.isNew()){
var toJSON = this.toJSON;
this.toJSON = this.toExtendedJSON;
var ret = Backbone.sync.apply(this, arguments);
this.toJSON = toJSON;
return ret;
}
else{
return Backbone.sync.call(this, method, this, options);
}
},
formatDate : function(dateString) {
return new Date(dateString).toUTCString();
}
});
return MessagesModel;
});
Collection
define([
"jquery",
"underscore",
"backbone",
"js/models/messagesModel"
],function($,_, Backbone, MessagesModel){
var MessagesCollection = Backbone.Collection.extend({
model : MessagesModel,
url : "/api/v1/message",
parse : function(response, xhr){
return response.list;
}
});
return MessagesCollection;
});

Try following for renderMessage():
renderMessage : function(item){
var messageView = new MessageView({
model : item
});
this.$el.find('div.message-list').append(messageView.render().el);
},
Also update the code in a similar way for renderMessageDetails().

Related

backbone.js template is not rendering data even though model passing data

Backbone.js template is not rendering data even though model passing data
View
var SectionView = Backbone.View.extend({
initialize : function() {
this.render();
},
model: Section,
className: 'div-body-row',
template: _.template($("#table-body-template").html()),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
Template:-
<script type="text/templete" id="table-body-template">
<div class="inner-div col-lg-2 col-md-2 col-sm-2 col-xs-2"><%= id %></div>
<div class="inner-div col-lg-2 col-md-2 col-sm-2 col-xs-2"><%= roomNumber %></div>
<div class="inner-div col-lg-2 col-md-2 col-sm-2 col-xs-2"><%= dateTime %></div>
<div class="inner-div col-lg-2 col-md-2 col-sm-2 col-xs-2"><%= personId %></div>
<div class="inner-div col-lg-2 col-md-2 col-sm-2 col-xs-2"><%= courseId %></div>
<div class="inner-div col-lg-2 col-md-2 col-sm-2 col-xs-2"><%= termId %></div>
</script>
this is entire code
var Section = Backbone.Model.extend({
defaults : {
id : '',
roomNumber : '',
dateTime : '',
person : '',
course : '',
term : ''
}
});
var SectionView = Backbone.View.extend({
initialize : function() {
this.render();
},
model: Section,
className: 'div-body-row',
template: _.template($('#table-body-template').html()),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
var a = this.model.get("id");
var b = this.model.get("sectionName");
var c = this.model.get("roomNumber");
var d = this.model.get("dateTime");
var e = this.model.get("person");
var f = this.model.get("course");
var g = this.model.get("term");
console.log(a,b,c,d,e,f,g);
return this;
}
});
var SectionCollection = Backbone.Collection.extend({
model: Section,
url: 'http://localhost:8080/student-faculty-attendance/section/sectionDetails'+'?id='+id,
});
var SectionCollectionView = Backbone.View.extend({
initialize : function(){
this.render();
},
tagName: 'div',
className: 'div-body',
singleSectionview: function(section){
var sectionView = new SectionView({model: section});
this.$el.append(sectionView.el);
},
render: function(){
this.collection.forEach(this.singleSectionview, this);
return this;
}
});
var section_collection = new SectionCollection();
var section_collection_view;
section_collection.fetch({
success: function(collection) {
console.log(collection);
if (collection.length) {
section_collection_view = new SectionCollectionView({collection: collection});
$("#table-body").append(section_collection_view.el);
} else {
console.log("Collection is empty!!");
}
}
And even template is generating but without data
<div id="table-body" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="div-body">
<div class="div-body-row">
<div class="inner-div"></div>
<div class="inner-div"></div>
</div>
<div class="div-body-row">
<div class="inner-div"></div>
<div class="inner-div"></div>
</div>
<div class="div-body-row">
<div class="inner-div"></div>
<div class="inner-div"></div>
</div>
</div>
</div>
You have defined model: Section in the view constructor, where Section is probably a model constructor. This is usually done in a collection, and the collection later constructs model instances using the specified constructor. View does not do that.
Calling toJSON() directly on a model constructor will result in error
Uncaught TypeError: .toJSON is not a function
because toJSON is defined on the prototype of constructor to be shared with it's instances, not directly on the constructor.
You should do:
var SectionView = Backbone.View.extend({
model: new Section()
});
but in this case if there are multiple instances of this view, they will share same model, which is generally not desired. Ideally you should create a model instance per view instance, like:
var view = new SectionView({model: new Section() });
or
var SectionView = Backbone.View.extend({
initialize : function() {
this.model = new Section();
this.render();
},

Angular autocomplete not working

From the tutorial. The search box is styled correctly.
But when I type the drop down doesn't appear with the static data in my controller.
Here is my template.
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-3">
<div class="panel panel-default panel-filter">
<div class="panel-heading">
<h3 class="panel-title">Calendar Filter</h3>
</div>
<div class="panel-body">
<div class="section section-filter">
<form ng-submit="$event.preventDefault()">
<div class="form-group" style="margin-bottom:0">
<div class="input-group input-group-sm addon-left">
<span class="input-group-addon">View By</span>
<select class="form-control" name="select_view" id="select_view">
<option value="taskown">Task Owner</option>
<option value="taskacc">Task Account</option>
</select>
</div>
</div>
<div class="form-group-taskown">
<div class="space15"></div>
<div class="form-group">
<div class="input-group input-group-sm addon-left">
<span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span>
<div class="autocompletedemoCustomTemplate">
<md-autocomplete
ng-disabled="taskCalendarCtrl.isDisabled"
md-no-cache="taskCalendarCtrl.noCache"
md-selected-item="taskCalendarCtrl.selectedItem"
md-search-text-change="taskCalendarCtrl.searchTextChange(taskCalendarCtrl.searchText)"
md-search-text="taskCalendarCtrl.searchText"
md-selected-item-change="taskCalendarCtrl.selectedItemChange(item)"
md-items="item in taskCalendarCtrl.querySearch(taskCalendarCtrl.searchText)"
md-item-text="item.name"
md-min-length="0"
placeholder=""
md-menu-class="autocomplete-custom-template">
<md-item-template>
<span class="item-title">
<md-icon md-svg-icon="img/icons/octicon-repo.svg"></md-icon>
<span> {{item.name}} </span>
</span>
<span class="item-metadata">
<span class="item-metastat">
<strong>{{item.watchers}}</strong> watchers
</span>
<span class="item-metastat">
<strong>{{item.forks}}</strong> forks
</span>
</span>
</md-item-template>
</md-autocomplete>
</div>
<!--
<input type="text" class="form-control" id="searchBox" name="typeahead_example_1" ng-model="searchBox" ng-change="change(text)" auto-complete ui-items="users">-->
</div>
</div>
</div>
</form>
</div><!--/section-->
</div>
</div>
</div>
<div class="col-sm-12 col-md-8 col-lg-6">
<div class="section section-calendar">
<div id='calendar'></div>
</div><!--/section-->
</div>
<div class="space20 hidden-lg"></div>
<div class="col-sm-12 col-sm-offset-0 col-md-8 col-md-offset-4 col-lg-3 col-lg-offset-0">
<div class="panel panel-default panel-tasks">
<div class="panel-heading">
<h3 class="panel-title">Tasks</h3>
</div>
<div class="list-group" ng-repeat="task in taskList | limitTo: 5">
<a href="{{task.url}}" class="list-group-item">
<span class="badge">{{task.status}}</span>
<h4 class="list-group-item-heading">{{task.heading}}</h4>
<ul class="list-unstyled">
<li><strong>Assigned To:</strong>{{task.assignedTo}}</li>
<li><strong>Releted To:</strong>{{task.relatedTo}}</li>
</ul>
</a>
</div><!--/list-group-->
</div>
</div>
</div><!--/row-->
</div> <!-- /container -->
and controller aka taskCalendarCtrl
'use strict';
angular
.module('taskCalendar')
.controller('taskCalendarCtrl', ['$scope', 'task', 'user', 'account', function($scope, task , user, account) {
}], taskCalendarCtrl);
function taskCalendarCtrl ($timeout, $q, $log) {
var self = this;
self.simulateQuery = false;
self.isDisabled = false;
self.repos = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;
// ******************************
// Internal methods
// ******************************
/**
* Search for repos... use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
var results = query ? self.repos.filter( createFilterFor(query) ) : self.repos,
deferred;
if (self.simulateQuery) {
deferred = $q.defer();
$timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
return deferred.promise;
} else {
return results;
}
}
function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
}
/**
* Build `components` list of key/value pairs
*/
function loadAll() {
var repos = [
{
'name' : 'Angular 1',
'url' : 'https://github.com/angular/angular.js',
'watchers' : '3,623',
'forks' : '16,175',
},
{
'name' : 'Angular 2',
'url' : 'https://github.com/angular/angular',
'watchers' : '469',
'forks' : '760',
},
{
'name' : 'Angular Material',
'url' : 'https://github.com/angular/material',
'watchers' : '727',
'forks' : '1,241',
},
{
'name' : 'Bower Material',
'url' : 'https://github.com/angular/bower-material',
'watchers' : '42',
'forks' : '84',
},
{
'name' : 'Material Start',
'url' : 'https://github.com/angular/material-start',
'watchers' : '81',
'forks' : '303',
}
];
return repos.map( function (repo) {
repo.value = repo.name.toLowerCase();
return repo;
});
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
return (item.value.indexOf(lowercaseQuery) === 0);
};
}
}
I get these errors when I click and type in the search box
more details on my error
You have your controller declaration wrong in your code.
The syntax of dependency injection of the controller is not correct.
it should be,
.controller('taskCalendarCtrl', ['$scope', 'task', 'user',
'account','$timeout','$q','$log', function($scope, task , user,
account,$timeout,$q,$log) {
}])
Here is the change in the complete file.
'use strict';
angular
.module('taskCalendar')
.controller('taskCalendarCtrl', ['$scope', 'task', 'user', 'account','$timeout','$q','$log', function($scope, task , user, account,$timeout,$q,$log) {
var self = this;
self.simulateQuery = false;
self.isDisabled = false;
self.repos = loadAll();
self.querySearch = querySearch;
self.selectedItemChange = selectedItemChange;
self.searchTextChange = searchTextChange;
// ******************************
// Internal methods
// ******************************
/**
* Search for repos... use $timeout to simulate
* remote dataservice call.
*/
function querySearch (query) {
var results = query ? self.repos.filter( createFilterFor(query) ) : self.repos,
deferred;
if (self.simulateQuery) {
deferred = $q.defer();
$timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
return deferred.promise;
} else {
return results;
}
}
function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
}
/**
* Build `components` list of key/value pairs
*/
function loadAll() {
var repos = [
{
'name' : 'Angular 1',
'url' : 'https://github.com/angular/angular.js',
'watchers' : '3,623',
'forks' : '16,175',
},
{
'name' : 'Angular 2',
'url' : 'https://github.com/angular/angular',
'watchers' : '469',
'forks' : '760',
},
{
'name' : 'Angular Material',
'url' : 'https://github.com/angular/material',
'watchers' : '727',
'forks' : '1,241',
},
{
'name' : 'Bower Material',
'url' : 'https://github.com/angular/bower-material',
'watchers' : '42',
'forks' : '84',
},
{
'name' : 'Material Start',
'url' : 'https://github.com/angular/material-start',
'watchers' : '81',
'forks' : '303',
}
];
return repos.map( function (repo) {
repo.value = repo.name.toLowerCase();
return repo;
});
}
/**
* Create filter function for a query string
*/
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
return (item.value.indexOf(lowercaseQuery) === 0);
};
}
}
])
check if you have set ng-controller directive. If not then set it first.
eg :
<div class="container-fluid" ng-controller="taskCalendarCtrl as taskCalendarCtrl">
Next change
.controller('taskCalendarCtrl', ['$scope', 'task', 'user', 'account', function($scope, task , user, account) {
}], taskCalendarCtrl);
to
.controller('taskCalendarCtrl', taskCalendarCtrl);

ion-slides, each overlap with ng-repeat

I'm real newbie in ionic, html, angular and java script. I have an app that take some JSON data and display it with ng-repeat.
But when I tried to switch to the next slide, it overlap. and I have an $interval that refresh JSON each 5 sec, it reset to the first slide also.
here html:
<ion-view title="home">
<ion-content ng-controller="temperatureCtrl">
<div ng-init="init()"></div>
<ion-slides options="options" slider="data.slider" >
<ion-slide-page ng-repeat="channel in channels">
<div class="list">
<h2><center>canal# {{channel.canal}}</center></h2>
<br/>
<center>
<button class="button button-stable" ng-click="switchChannel(channel, channel.canal)" ng-model="channel.status">
{{channel.status}}
</button>
</center>
<div class="list">
<label class="item item-input">
<input type="text" style="text-align:center;" placeholder="Channel name" ng-model="channel.name" ng-focus="stopRefresh()" ng-blur="restartRefresh()">
</label>
</div>
<h4><center>
<span class="Ainput" ><h3>{{channel.temperature}}ºC</h3></span>
</center></h4>
<h3><center>Setpoint= {{channel.setPoint}}</center></h3><br>
<div class="item range range-positive">
<i class="icon ion-minus-round"></i>
<input type="range" name="setpoint" min="5" max="30" step="0.5" value="33" ng-model="channel.setPoint" ng-focus="stopRefresh()" ng-blur="restartRefresh()">
<i class="icon ion-plus-round"></i>
</div>
<centrer>
<button class="button button-dark button-block padding " ng-click="channelsClk(channel, channel.setPoint)">ok</button>
</centrer>
<h3>
<span class="permRun">{{channel.permission}}</span>
</h3>
<h3>
<span class="AoutputChannel">{{channel.percentOut}}%</span>
</h3>
</ion-slide-page>
</ion-slides>
</ion-content>
and the controler:
main.controller("temperatureCtrl", ["$scope", "$interval", "ArduinoService", function($scope, $interval, service) {
var autoRefresh;
$scope.channels = [];
$scope.options = {
loop: false,
effect: 'fade',
speed: 500,
}
$scope.data = {};
$scope.$watch('data.slider', function(nv, ov) {
$scope.slider = $scope.data.slider;
})
function startRefresh(){
autoRefresh = $interval(function() {
updateAjax();
}, 5000);
}
function updateAjax() {
service.getChannels(function(err, result) {//get json data
if (err) {
return alert(err);
}
// puis les mets dans le scope
$scope.channels = result.channels;
})
};
$scope.init = function() { //on load page first get data
updateAjax();
startRefresh()
}
$scope.switchChannel = function($scope, channel) { // change name function
var switchCh = {canal : $scope.canal, status : $scope.status}
service.switchChannel(switchCh, function() {
});
updateAjax();
};
$scope.channelsClk = function($scope, channel) {
var chanObj = {setPoint : $scope.setPoint, name : $scope.name, canal : $scope.canal
};
service.putChannels(chanObj, function() {
});
}
$scope.stopRefresh = function() { //ng-mousedown
$interval.cancel(autoRefresh);
};
$scope.restartRefresh = function() {
startRefresh();
};
$scope.$on('$destroy', function() {
// Make sure that the interval is destroyed too
$scope.stopRefresh();
});
}]);
remove option fade solve the problem.
$scope.options = {
loop: false,
//effect: 'fade', /* <-- */
speed: 500,
}

how to replace view with another view in backbone.js on runtime

I am trying to build backbone.js application with twitter API.
the application that I am working on performs 3 tasks:1-returns the recent tweets on the user 's timeline, 2-returns the user profile 3- provides the ability to search in twitter. my problem is that I want the results of the search functionality to appear in the location of the tweets when the user clicks the search button. in my code there is view to display the tweets and another view to display the results of searching..how to put view in the place of another view on runtime. here is some of the code to explain the idea:
index.html :
<body>
<header role="banner">
<!—some code here-->
</header>
<div id="search" class="inner-search">
<form>
<label>Search for</label>
<input type="search" id="searchbox" style="width: 70%;"
autofocus="" placeholder="I'm looking for.."/>
<button id="searchbutton" style="width: 10%;">Go</button>
</form>
</div><!--search-view-->
<div class="inner-content">
<nav role="navigation">
<ul class="chapter-list">
………
</ul>
</nav>
<div role="main" class="main-content metrouicss">
<div id='timeline' class='timeline-view'>
<h3>Tweets </h3>
</div>
</div><!--main-->
<div role="right" class="right-content">
<h3>My Profile </h3>
<div id="profile" class="profile-view">
<!-- This would be the template -->
</div></div><!--right-->
</div> <!-- /.content-wrapper -->
<footer role="contentinfo">
<div class="inner-footer">
<p class="copyright">© Eva Hriekes, 2015. All rights
reserved.</p>
</div> <!-- /.inner-footer -->
</footer>
<!-- Template for profile -->
<script type="text/x-handlebars-template" id="profile-template">
<div class='tiles clearfix'>
<div class="tile double bg-color-orangeDark">
<div class="tile-content">
<img src="{{user.profile_image_url}}" class="place-left">
<h3 style="margin-bottom: 5px;">{{user.name}}</h3>
<p style="float:left;">{{user.description}}</p>
<div class="brand">
<div class="badge">{{user.followers_count}} Followers</div>
</div>
</div>
</div>
</div>
</script>
<!-- Template for timeline -->
<script type="text/x-handlebars-template" id="timeline-template">
<ul class='listview fluid'>
{{#each tweet}}
<li >
<div class='icon'>
<img src='{{user.profile_image_url}}'></img>
</div>
<div class='data'>
<h4>{{user.name}}</h4>
<p>{{format text}}</p>
<p class="timestamp" style="text-decoration:underline;">
<i>{{friendlyDate}}</i></p>
<p style="font-weight:bold;">Rating:
<i class="fa fa-star-o"></i><i class="fa fa-star-
o"></i><i class="fa fa-star-o"></i><i class="fa fa-star-
o"></i><i class="fa fa-star-o"></i></p>
</div>
</li>
{{/each}}
</ul>
</script>
<!-- Template for search results -->
<script type="text/x-handlebars-template" id="search-template">
<ul class='listview fluid'>
{{#each tweet}}
<li >
<div class='icon'>
<img src='{{user.profile_image_url}}'></img>
</div>
<div class='data'>
<h4>{{user.name}}</h4>
<p>{{format text}}</p>
<p class="timestamp" style="text-decoration:underline;">
<i>{{friendlyDate}}</i></p>
</div>
</li>
{{/each}}
</ul>
</script>
<script data-main="js/main" src="js/vendor/require.js"></script>
</body>
</html>
timeline view:
define(['jquery', 'handlebars', 'backbone', 'app/collection
/Timeline','app/view/ProfilePopupView'],
function($, Handlebars, Backbone, Timeline,ProfilePopupView) {
var com = com || {};
com.apress = com.apress || {};
com.apress.view = com.apress.view || {};
com.apress.view.TimelineView = Backbone.View.extend({
el: '#timeline',
template: Handlebars.compile($("#timeline-template").html()),
timeline: null,
events: {
'click .profile': 'showDialog'
},
initialize: function(options){
var self = this;
//create a collection for this view to render
self.timeline = new Timeline();//new
com.apress.collection.Timeline();
//initial render
self.render();
//force the fetch to fire a reset event
self.timeline.fetch({reset:true
});
self.listenTo(self.timeline, 'reset', self.render);
},
render: function(){
var self = this;
if(self.timeline.models.length > 0){
var output = self.template({tweet: self.timeline.toJSON()});
self.$el.append(output);
}
return self;
},
showDialog: function(options){
var self =this,
$target = $(options.currentTarget),
username = $target.data('user');
/**
* Reuse the profile view
**/
var profileView = new ProfilePopupView({user: username});
}
});
// export stuff:
return com.apress.view.TimelineView;
});
search view:
define(['jquery', 'backbone'], function($, Backbone) {
var com = com || {};
com.apress = com.apress || {};
com.apress.view = com.apress.view || {};
com.apress.view.SearchView = Backbone.View.extend({
el: '#search',
model: null,
events: {
'click #searchbutton': 'runSearch'
},
initialize: function(options){
var self = this;
self.model = options.model;
},
runSearch: function(e){
var self = this;
query = $('#searchbox').val();
e.preventDefault();
console.log('Run search against ' + query);
//force a reset
self.model.set('query', '', {silent: true});
self.model.set('query', query);
}
});
return com.apress.view.SearchView;
});
results view:
define(['jquery', 'backbone', 'handlebars','dialog'], function($,
Backbone, Handlebars,Dialog) {
var com = com || {};
com.apress = com.apress || {};
com.apress.view = com.apress.view || {};
com.apress.view.ResultsView = Backbone.View.extend({
el: '#results', /* or should be el="#timeline"???*/
model: null,
template: Handlebars.compile($("#search-template").html()),
initialize: function(options){
var self = this;
self.model = options.model;
self.model.fetch({
error: function(e){
self.model.trigger("app:error", {message: 'Error
retrieving timeline information'});
},
success: function(e){
self.model.trigger("app:success", {message: 'success
retrieving timeline information'});
}
});
self.listenTo(self.model,'change', self.render);
self.render();
},
render: function(){
console.log('Display now');
var self = this,
output = self.template({tweet: self.model.get('statuses')});
/* I want to delete this code and display the results
in the place of tweets*/
$.Dialog({
'title' : 'Search Results',
'content' : output,
'draggable' : true,
'overlay' : true,
'closeButton' : true,
'buttonsAlign': 'center',
'keepOpened' : true,
'position' : {
'zone' : 'left'
},
'buttons' : {
'OK' : {
'action': function(){}
}
}
});
}
});
return com.apress.view.ResultsView;
});
can anyone help me in doing what I want?

Backbone.js Event Not firing

I can't get this thing to add when i click the add button. I'm completely new to this.
JS code
function RecipeApp() {
var _Ingredient=Backbone.Model.extend(COOKBOOK.Domain.Ingredient),
_Ingredients = Backbone.Collection.extend({
model: _Ingredient
}),
_IngredientView = Backbone.View.extend({
tagName: "li",
initialize: function () {
this.model.bind("change", this.render, this);
},
render: function () {
var templateid = this.model.get('ViewID');
$(this.el).html(Mustache.to_html($("#"+templateid).html(),this));
}
}),
_AddView = Backbone.View.extend({
id:"divAddIngredient",
events: {
"click .btn": "create"
},
render: function () {
var tmpAddAnIngredient = $("#tmpMasterView").html(),
$submain = $("#submain");
$submain.html(Mustache.to_html(tmpAddAnIngredient, COOKBOOK.Domain));
},
initialize: function (ingredients) {
console.log("init enter");
this.render();
this._Ingredients = ingredients;
this._Ingredients.bind('add', this.add, this);
console.log("init leave");
},
//added functions
create: function () {
console.log("create");
var typename = this.$(".typeName").val(),
ingredient = _.detect(COOKBOOK.Domain.Ingredients, function (i) { i.TypeName === typename });
if (!!ingredient) {
this._Ingredients.create(ingredient);
}
},
add: function (ingredient) {
console.log('add');
var view = new _IngredientView(ingredient);
this.$("#divIngredients").append(view.render().el);
}
});
this.Ingredients = new _Ingredients();
this.AddView = new _AddView(this.Ingredients);
}
$(function () {
window.app = new RecipeApp();
//
});
And here is the mustache template
<script id="tmpTempDirectoryIngredient" type="text/html">
<div class="block-message">
<form>
<fieldset>
<legend>Create a Temporary Directory</legend>
<div class="clearfix">
<input type="text" name="DirectoryName" class="DirectoryName" />
</div>
</fieldset>
</form>
</div>
</script>
<script id="tmpMasterView" type="text/html">
<div class="block-message info" id="divAddIngredient">
<form>
<fieldset>
<legend>Add an Ingredient</legend>
<div class="clearfix">
<select class="typeName">
{{#Ingredients}}
<option value="{{TypeName}}">{{Name}}</option>
{{/Ingredients}}
</select>
</div>
<div class="clearfix">
<input type="button" class="btn primary" value="Add Ingredient" />
</div>
</fieldset>
</form>
</div>
<hr />
<div id="divIngredients">
</div>
</script>
it started working as soon as i explicitly set the el property of the _AddView to a tag that existed when the _AddView was created.
$(function(){
new Apps({el:$("body"),'records':[1,2,3,4,5]});
});
Here need to give el.
because of only after DOM is generating.....
The way you are passing Ingredients to the _AddView initialize, they will be accessible by this.options (see http://documentcloud.github.com/backbone/#View-constructor).
I think a better way is pass your ingredients collection into you _AddView like this:
this.AddView = new _AddView({collection: this.Ingredients});
Then within your definition of your view, always refer to this.collection instead of this._Ingredients. That is I think a more standard way to do it.

Resources