Backbone JS Create dynamic views and collection - backbone.js

I am a bit noob to backbone JS
I have this one code in which I need to list out the categories according to the json and list them out on the page.
Now when user clicks on any of the category list a new JSON attached to that category is fetched from the server and listed on the page.
My problem is I have listed out the categories but don't know how to get new JSON and display it on the screen by creating views and collection for new JSON dynamically depending on thecategory chosen.
Here is my HTML Code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Category list</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Category list</h1>
<hr />
<div class='categoryList'></div>
<div class='selected_category'></div>
</div>
<script type="text/template" id="events-template">
<% _.each( CategoryCollection, function(Category){ %>
<div class='category'>
<h2 class='<%= Category.get("category") %>' >
<%= Category.get("category") %>
</h2>
</div>
<% }); %>
</script>
<script type="text/template" id="selectedCategory-template">
<% _.each( SelectedCategoryCollection, function(selected_category){ %>
<div class='category_list'>
<%= selected_category.get("category") %>
</div>
<% }); %>
</script>
</body>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script>
var categoryJSON;
var Category = Backbone.Model.extend();
var CategoryCollection = Backbone.Collection.extend({
model: Category,
url: 'categories.json',
parse: function (response) {
categoryJSON = response;
console.log(categoryJSON)
return response;
}
});
var CategoryAbout = Backbone.View.extend ({
el: '.categoryList',
render: function () {
var that = this;
// console.log(that)
var eventCategory = new CategoryCollection();
// console.log(eventCategory);
eventCategory.fetch({
success: function (CategoryCollection) {
// console.log(CategoryCollection)
var template = _.template($('#events-template').html(), {CategoryCollection: CategoryCollection.models});
// console.log(template)
that.$el.html(template);
}
})
},
events: {
"click .category h2" : "doSearch"
},
doSearch: function(event){
// Button clicked
console.log('clicked');
console.log(event.toElement.className)
router.navigate('/category/'+event.toElement.className, { trigger: true });
// window.location.href = window.location.href + '/#/category/all';
}
});
var CategoryAbout = new CategoryAbout ();
var Router = Backbone.Router.extend({
routes: {
'': 'home',
"category/:categoryName": "getCategory",
}
});
var router = new Router();
// console.log(router)
router.on('route:home', function () {
// console.log(this)
console.log('home');
CategoryAbout.render();
});
router.on('route:getCategory', function (categoryName) {
console.log( "Category Name " + categoryName );
var urlToFetch;
for (var i = 0; i < categoryJSON.length; i++) {
if(categoryJSON[i].category == categoryName)
{
urlToFetch = categoryJSON[i].data;
}
};
console.log(urlToFetch);
});
Backbone.history.start();
</script>
and the JSON file for Category
[
{
"category": "all",
"data": "all.json"
},
{
"category": "music",
"data": "music.json"
},
{
"category": "business",
"data": "business.json"
},
{
"category": "sports",
"data": "sports.json"
},
{
"category": "workshops",
"data": "workshops.json"
}
]
and say that we have chosen workshop category then JSON of workshop is like this
{
"request": {
"venue": "0",
"ids": "0",
"type": "json",
"city": "NY",
"edate": 0,
"page": 0,
"keywords": "0",
"sdate": 0,
"category": "workshops",
"city_display": "NY",
"rows": 50
},
"count": 10,
"item": [
{
"event_id": "230801950442480",
"eventname": "Holiday special YES! course :) :)",
"thumb_url": "http://graph.facebook.com/230801950442480/picture",
"thumb_url_large": "http://graph.facebook.com/230801950442480/picture?type=large",
"start_time": 1395943200,
"start_time_display": "Thu Mar 27 2014 at 06:00 pm",
"end_time": 1396213200,
"end_time_display": "Sun Mar 30 2014 at 09:00 pm",
"location": "NY,ABC street",
"venue": {
"street": "",
"city": "NY",
"state": "XYZ",
"country": "PQR"
},
"label": "Tomorrow",
"featured": 0
},
{
"event_id": "230801950442480",
"eventname": "Holiday special YES! course :) :)",
"thumb_url": "http://graph.facebook.com/230801950442480/picture",
"thumb_url_large": "http://graph.facebook.com/230801950442480/picture?type=large",
"start_time": 1395943200,
"start_time_display": "Thu Mar 27 2014 at 06:00 pm",
"end_time": 1396213200,
"end_time_display": "Sun Mar 30 2014 at 09:00 pm",
"location": "NY,ABC street",
"venue": {
"street": "",
"city": "NY",
"state": "XYZ",
"country": "PQR"
},
"label": "Tomorrow",
"featured": 0
}
]
}
thanks in advance.
let me know if I am missing out any data

Related

AngularJS Changing DropDowns according to DropDown Values for ng-repeat filters

I have a list of about 1400 locations around the world and displaying them using ng-repeat. I want to have dropdowns to narrow the list down using the filter feature so I can only see locations in Region: Americas, Country:Canda for example. I have gotten the dropdown filters to work properly but my issue is changing the values of the dropdowns. If I select the Region option in the first dropdown, the country dropdown should only have countries in that Region.
Here is my Template:
Region:<select ng-model='RegionLocation.Region' ng-options="location.Region for location in RegionOptions.Regions"></select>
Country:<select ng-model='CountryLocation.Country' ng-options="location.Country for location in CountryOptions.Countries"></select>
<div>
<md-card data-ng-repeat="location in LocationCtrl.Locationlist | filter:RegionFilter | filter:CountryFilter ">
<md-card-content>
<h2>{{::location.LID}}</h2>
</md-card-content>
</md-card>
</div>
Here is my Controller.js
function LocationController(LocationList, $scope) {
var LocationCtrl = this;
LocationCtrl.Locationlist = LocationList;
LocationCtrl.Regions = filterRegions(LocationList);
LocationCtrl.Regions.unshift({
Region: 'Show All'
})
$scope.RegionOptions = {
Regions:LocationCtrl.Regions,
}
$scope.RegionLocation = {
Region: $scope.RegionOptions.Regions[0],
}
$scope.CountryOptions = {
Countries:getCountries()
};
$scope.CountryLocation = {
Country: $scope.CountryOptions.Countries[0]
};
$scope.RegionFilter = function (data) {
if($scope.RegionLocation.Region.Region == 'Show All'){
return true;
} else if(data.Region == $scope.RegionLocation.Region.Region){
return true;
} else{
return false;
}
};
$scope.CountryFilter = function (data) {
if($scope.CountryLocation.Country.Country == 'Show All'){
return true;
} else if(data.Country == $scope.CountryLocation.Country.Country){
return true;
} else{
return false;
}
};
function getCountries(){
LocationCtrl.Countries = filterCountries(LocationList);
LocationCtrl.Countries.unshift({
Country: 'Show All'
});
return LocationCtrl.Countries;
};
function filterRegions(arr) {
var f = []
return arr.filter(function(n) {
return f.indexOf(n.Region) == -1 && f.push(n.Region)
})
};
function filterCountries(arr){
var f = [];
return arr.filter(function(n) {
return f.indexOf(n.Country) == -1 && f.push(n.Country)
})
};
}
I also understand my code is not super clean nor simple so suggestions to simplify it are more than welcome.
Thank you!!
You were on the right track with using a filter on the ng-repeat, here is how I managed to get it working based of some mock data. Its really simple to get this done using a filter. I hope this helps.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $filter) {
$scope.name = 'Sup World';
$scope.list = [{
"LID": "AB02",
"City": "Calgary",
"State": "Alberta",
"Country": "Canada",
"Region": "Americas",
"Latitude": "XXXXXX",
"Longitude": "XXXXX"
}, {
"LID": "AB08",
"City": "Canmore",
"State": "Alberta",
"Country": "Canada",
"Region": "Americas",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB09",
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB12",
"City": "Eish",
"State": "Somewhere",
"Country": "Zimbabwe",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXX"
}, {
"LID": "AB18",
"City": "Lusaka",
"State": "Zambia?",
"Country": "Zambia",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB19",
"City": "Durban",
"State": "Kwazulu Natal",
"Country": "South Africa",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB13",
"City": "Pretoria",
"State": "JoJo",
"Country": "South Africa",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}];
$scope.region = [];
//get unique regions
$scope.regions = $filter('unique')($scope.list, "Region");
$scope.country = [];
//get unique countries
$scope.countries = $filter('unique')($scope.list, "Country");
});
app.filter('unique', function() {
return function(arr, field) {
var o = {},
i, l = arr.length,
r = [];
for (i = 0; i < l; i += 1) {
o[arr[i][field]] = arr[i];
}
for (i in o) {
r.push(o[i]);
}
return r;
};
})
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
Region:
<select ng-model='region' ng-options="location.Region for location in regions"></select>
Country:
<select ng-model='country' ng-options="location.Country for location in countries | filter:{'Region': region.Region }"></select>
<div>
<md-card data-ng-repeat="location in list | filter:{'Region':region.Region,'Country':country.Country} ">
<md-card-content>
<h2>{{::location.LID}}</h2>
</md-card-content>
</md-card>
</div>
</body>
</html>
See this Plunker, i had to change the values of country and region to differentiate since the values are same in both the objects.

How to create "this" object in AngularJs?

I have a list of name's and id's. I have displayed it with ng-repeat property. I want to show the corresponding id's along with the name in 1 second on its click.
$scope.showFn = function() {
$scope.showPopup = true;
$timeout(function(){
console.log("timeout");
$scope.showPopup = false;
}, 1000);
};
I have created a plunker https://plnkr.co/edit/kvkgwp60Bxq2MrHrr5Rr?p=preview
Now showing all the id's in a single click. Please help. Thanks.
Try with below in HTML:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="main">
<ul>
<li ng-repeat="item in items">
{{item.name}}
<span ng-show="showPopup && item.id == shownId">{{item.id}}</span>
</li>
</ul>
</body>
</html>
Controller will be like below:
var app = angular.module('app', [])
.controller('main', function($scope, $timeout) {
$scope.items = [{
"name": "one",
"id": "1"
}, {
"name": "two",
"id": "2"
}, {
"name": "three",
"id": "3"
}, {
"name": "four",
"id": "4"
}, {
"name": "five",
"id": "5"
}, {
"name": "six",
"id": "6"
}, {
"name": "seven",
"id": "7"
}]
$scope.showFn = function(Item) {
$scope.shownId = Item;
$scope.showPopup = true;
$timeout(function() {
console.log("timeout");
$scope.showPopup = false;
}, 1000);
};
});

AngularJS Filed nested array of objects with array of objects

I'm trying to filter a nested array of objects with my own objects, by idSubject. But I'm not getting the right result.
I have articles (which have subjects)
And a array of objects (which are the subjects I want to filter the articles with)
Data looks like this:
So I'm trying to filter the array of articles by its subjects.
I tried the following:
<div class="panel panel-default"
ng-repeat="searchArticle in searchArticles | filter: {subjects: filterSubjects} as articleSearchResult">
So filterSubjects is the second screenshot and SearchArticles is the first screenshot.
Without much luck.
Hope you can help, please tell me if things are still unclear.
This custom filter will help you.
Example : http://plnkr.co/edit/jMizCLxPH6DtDA5wL15Q?p=preview
HTML:
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<h2>Select Subjects</h2>
<div ng-repeat="subject in subjects">
<label>
<input type="checkbox" ng-model="filterSubjects[subject.id]" ng-true-value="'{{subject.id}}'" ng-false-value="''">{{subject.name}}</label>
</div>
<h2>Filtered Articles</h2>
<div ng-repeat="searchArticle in searchArticles | subjectFilter:filterSubjects">{{searchArticle.name}}</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
filtered = articles.filter(function(e){return filterSubjects.indexOf(e.sid) >= 0},filterSubjects);
return filtered;
}
});
if you want to filter based on object :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject1",
"id": "2"
}];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
var sFiltered = [];
for (var i = 0; i < filterSubjects.length; i++) {
sFiltered.push(filterSubjects[i].id);
}
var filtered = articles.filter(function(e) {
return sFiltered.indexOf(e.sid) >= 0;
}, sFiltered);
return filtered;
}
});

How to display my JSON datas expressjs/angularjs

I am a beginner in JSON.
I would like to display all my JSON datas in my html <div>, but I am not sure how to do it with an object using EXPRESSJS.
Find bellow my JSON Datas
app.post("/form",function(req,res)
{
var departure=req.body.departure;
var destination=req.body.destination;
response = {
"flights": [{
"departure": departure,
"destination": destination,
"time": {
departure: 10,
destination: 12
},
"price": 2000
}, {
"departure": departure,
"destination": destination,
"time": {
departure: 12,
destination: 14
},
"price": 4000
}, {
"departure": departure,
"destination": destination,
"time": {
departure: 14,
destination: 16
},
"price": 8000
}]
};
res.json({departure: departure, destination: destination});
});
My html
<div ng-repeat="item in response">
<dir>{{item.departure}}</dir>
<dir>{{item.destination}}</dir>
<dir>{{item.time.departure}}</dir>
<dir>{{item.time.destination}}</dir>
<dir>{{item.price}}</dir>
</div>
AngularJS code
app.controller('formController', function($scope, $http) {
$scope.pageClass = 'form';
$scope.departure = '';
$scope.destination = '';
$scope.submit = function() {
$http.post('/form', {
departure: $scope.departure,
destination: $scope.destination
}).then(function(res) {
$scope.response = res.data;
});
}
});
At the moment it is displaying only my departure and destination as I asked. Is there a way to display all my datas by writing my res.json() without doing it variable by variable ? I guess I have to do something with ng-repeat as well ?
Thank you by advance
Yes, you need use ng-repeat
var app = angular.module('app',[]);
app.controller('myController',function($scope){
$scope.response = {
"flights": [{
"departure": "departure1",
"destination": "destination1",
"time": {
departure: 10,
destination: 12
},
"price": 2000
}, {
"departure": "departure2",
"destination": "destination2",
"time": {
departure: 12,
destination: 14
},
"price": 4000
}, {
"departure": "departure3",
"destination": "destination3",
"time": {
departure: 14,
destination: 16
},
"price": 8000
}]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div ng-repeat="item in response.flights">
<dir>{{item.departure}}</dir>
<dir>{{item.destination}}</dir>
<dir>{{iteme.time.departure}}</dir>
<dir>{{item.time.destination}}</dir>
<dir>{{item.price}}</dir>
</div>
</div>
</div>
check the docu: https://docs.angularjs.org/api/ng/directive/ngRepeat
you do need to use a ng-repeat
<div ng-repeat="flight in response.flights">
<dir>{{flight.departure}}</dir>
<dir>{{flight.destination}}</dir>
<dir>{{flight.time.departure}}</dir>
<dir>{{flight.time.destination}}</dir>
<dir>{{flight.price}}</dir>
</div>
Reference for ngRepeat
A good reference for anything Angular can be found on the documentation site for AngularJS

Filter by text search in some fields of array of objects

There must a small detail missing in this code but as I am new to angular I cannot figure it out myself. Here is the output:
Looping with objects:
{{ x.address + ', ' + x.beds }}
And here is the code:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="objectsCtrl">
<p>Looping with objects:</p>
<ul>
<li ng-repeat="x in objects">
{{ x.address + ', ' + x.beds }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('objectsCtrl', function($scope) {
$scope.objects = [
{
"address": "123, Demo Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "3",
"baths": "1"
},
{
"address": "123, second Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "1",
"baths": "1"
},
{
"address": "123, third Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "2",
"baths": "1"
},
{
"address": "123, fourth Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "4",
"baths": "1"
},
];
});
angular.module('myApp').filter('textSearchFilter',[ function (objects) {
return function(objects, searchText) {
searchText = searchText.toLowerCase();
var filtered = [];
angular.forEach(objects, function(item, searchText) {
if( item.address.toLowerCase().indexOf(searchText) >= 0 ||
item.beds.toLowerCase().indexOf(searchText) >= 0 ||
item.baths.toLowerCase().indexOf(searchText) >= 0
) {
filtered.push(item);
}
});
return filtered;
}
}]);
</script>
</body>
</html>
It seems that the list of objects is not passed correctly to the filter. I am guessing I did not put the filter function in thew right place.
Filter should be place on the ng-repeat directive objects array, using | pipe sign, thereafter you need to mention filter name.
<li ng-repeat="x in objects | textSearchFilter: searchInput">
Addionally you need to correct filter code
angular.module('myApp').filter('textSearchFilter',[ function (objects) { //<--remove object dependency
return function(objects, searchText) {
to
angular.module('myApp').filter('textSearchFilter',[ function () {
return function(objects, searchText) {
and add input field inside your HTML, like
<input type="text" ng-model="searchText"/>
Here is the final code working now:
<div ng-app="myApp" ng-controller="objectsCtrl">
<p>Looping with objects:</p>
<ul>
<li ng-repeat="x in objects | textSearchFilter:'demo'">
{{ x.address + ', ' + x.beds }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('objectsCtrl', function($scope) {
$scope.objects = [
{
"address": "123, Demo Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "3",
"baths": "1"
},
{
"address": "123, second Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "1",
"baths": "1"
},
{
"address": "123, third Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "2",
"baths": "1"
},
{
"address": "123, fourth Address",
"lat": "45.123123",
"lng": "85.003342",
"beds": "4",
"baths": "1"
},
];
});
angular.module('myApp').filter('textSearchFilter',[ function () {
return function(objects, searchText) {
searchText = searchText.toLowerCase();
var filtered = [];
angular.forEach(objects, function(item) {
console.log(searchText);
if( item.address.toLowerCase().indexOf(searchText) >= 0 ||
item.beds.toLowerCase().indexOf(searchText) >= 0 ||
item.baths.toLowerCase().indexOf(searchText) >= 0
) {
filtered.push(item);
}
});
return filtered;
}
}]);

Resources