I have an object in Angular that is being used in the library I'm using. When I wrote a new function I cannot pass this same object. I'm not sure why.
The object is called person. The function I'm trying to write is called clickLike. I literally just want the same thing to happen whether someone clicks or swipes right. You can see the dev site here:
http://430designs.com/xperience/black-label-app/deck.php
Here's the entire controller.js file:
angular.module('black-label', ['ngTouch', 'ngSwippy'])
.controller('MainController', function($scope, $timeout, $window) {
$scope.cardsCollection = [
{
thumbnail: 'images/deck/thor_01.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_02.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_03.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_04.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_05.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_06.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/rhap_01.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_02.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_03.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_04.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_05.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_06.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/cha_01.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_02.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_03.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_04.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_05.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_06.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/mod_01.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_02.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_03.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_04.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_05.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_06.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/ind_01.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_02.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_03.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_04.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_05.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_06.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/cnt_01.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_02.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_03.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_04.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_05.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_06.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/vin_01.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_02.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_03.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_04.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_05.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_06.jpg',
collection: 'vineyard',
},
];
// Do the shuffle
var shuffleArray = function(array) {
var m = array.length,
t, i;
// While there remain elements to shuffle
while (m) {
// Pick a remaining element
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
};
$scope.deck = shuffleArray($scope.cardsCollection);
$scope.myCustomFunction = function() {
$timeout(function() {
$scope.clickedTimes = $scope.clickedTimes + 1;
$scope.actions.unshift({ name: 'Click on item' });
});
};
$scope.count = 0;
$scope.showinfo = false;
$scope.clickedTimes = 0;
$scope.actions = [];
$scope.picks = [];
var counterRight = 0;
var counterLeft = 0;
$scope.swipeend = function() {
$scope.actions.unshift({ name: 'Collection Empty' });
$window.location.href = 'theme-default.html';
}; //endswipeend
$scope.swipeLeft = function(person) {
//Essentially do nothing
$scope.actions.unshift({ name: 'Left swipe' });
$('.circle.x').addClass('dislike');
$('.circle.x').removeClass('dislike');
$(this).each(function() {
return counterLeft++;
});
}; //end swipeLeft
$scope.swipeRight = function(person) {
$scope.actions.unshift({ name: 'Right swipe' });
// Count the number of right swipes
$(this).each(function() {
return counterRight++;
});
// Checking the circles
$('.circle').each(function() {
if (!$(this).hasClass('checked')) {
$(this).addClass('checked');
return false;
}
});
$('.icon-like').addClass('liked');
$('.icon-like').removeClass('liked');
$scope.picks.push(person.collection);
// console.log('Picks: ' + $scope.picks);
// console.log("Counter: " + counterRight);
if (counterRight === 4) {
// Calculate and store the frequency of each swipe
var frequency = $scope.picks.reduce(function(frequency, swipe) {
var sofar = frequency[swipe];
if (!sofar) {
frequency[swipe] = 1;
} else {
frequency[swipe] = frequency[swipe] + 1;
}
return frequency;
}, {});
var max = Math.max.apply(null, Object.values(frequency)); // most frequent
// find key for the most frequent value
var winner = Object.keys(frequency).find(element => frequency[element] == max);
$window.location.href = 'theme-' + winner + '.html';
} //end 4 swipes
}; //end swipeRight
$scope.clickLike = function() {
$scope.swipeRight();
}; //clickLike
});
If I'm leaving anything out please let me know.
Thanks in advance everyone!
UPDATE:
HTML file for the deck
<div class="ng-swippy noselect">
<div person="person" swipe-directive="swipe-directive" ng-repeat="person in peopleToShow" class="content-wrapper swipable-card">
<div class="card">
<div style="background: url({{person.thumbnail}}) no-repeat 50% 15%" class="photo-item"></div>
<div class="know-label">{{labelOk ? labelOk : "YES"}}</div>
<div class="dontknow-label">{{labelNegative ? labelNegative : "NO"}}</div>
</div>
<div class="progress-stats" ng-if="data">
<div class="card-shown">
<div class="card-shown-text">{{person.collection}}</div>
<div class="card-shown-number">{{person.subtitle}}</div>
</div>
<div class="card-number">{{collection.length - (collection.indexOf(person))}}/{{collection.length}}
</div>
</div>
<div class="container like-dislike" >
<div class="circle x" ng-click="$parent.$parent.clickDisike()"></div>
<div class="icon-like" ng-click="$parent.$parent.clickLike()"></div>
<div class="clearfix"></div>
</div>
</div><!-- end person-->
<div class="clearfix"></div>
Related
I have this nested object:
const menus = {
path: '/actions/step',
icon: 'fa fa-wine-bottle',
title: 'Fasi',
children: [
{
path: '/actions/step/analysis',
title: 'Analisi'
},
{
path: '/actions/step/import',
title: 'Importazione'
},
{
path: '/actions/step/squeeze',
title: 'Spremitura'
},
{
path: '/actions/step/move',
title: 'Spostamento'
},
{
path: '/actions/step/splitauto',
title: 'Travaso Guidato'
},
{
path: '/actions/step/stir',
title: 'Rimestaggio'
},
{
path: '/actions/step/clarify',
title: 'Chiarifica'
},
{
path: '/actions/step/stabilization',
title: 'Stabilizzazione'
},
{
path: '/actions/step/bottling',
title: 'Imbottigliamento'
},
{
path: '/actions/step/clean',
title: 'Pulizia'
},
{
path: '/actions/step/clean_close',
title: 'Pulizia e Chiusura'
},
{
path: '/actions/step/add_product',
title: 'Aggiunta Prodotto'
},
]
},
{
path: '/actions',
icon: 'fa fa-tasks',
title: 'Azioni',
children: [
{
path: '/actions/type',
title: 'Tipi di Azione'
},
{
path: '/actions/list',
title: 'Lista delle Azioni'
},
{
path: '/actions/traceability',
title: 'Tracciabilità'
}
]
},
{
path: '/warehouse',
icon: 'fa fa-warehouse',
title: 'Magazzino',
children: [
{
path: '/warehouse/list-warehouse-item',
title: 'Lista Oggetti',
children: [
{
path: '/warehouse/new-warehouse-item',
title: 'Nuovo Oggetto'
}
]
},
]
},
{
path: '/suppliers',
icon: 'fa fa-truck',
title: 'Fornitori',
children: [
{
path: '/suppliers/list-suppliers',
title: 'Lista Fornitori',
children: [
{
path: '/suppliers/new-supplier',
title: 'Nuovo Fornitore'
}
]
}
]
}
What I'm trying to achieve is to filter the nested object based on the path value.
So if I have /actions/step/import I would like to have this:
[{
path: '/actions/step',
icon: 'fa fa-wine-bottle',
title: 'Fasi'
},
{
path: '/actions/step/import',
title: 'Importazione'
}]
Or in case /warehouse/new-warehouse-item I would have:
[{
path: '/warehouse',
icon: 'fa fa-warehouse',
title: 'Magazzino'
},
{
path: '/warehouse/list-warehouse-item',
title: 'Lista Oggetti'
},
{
path: '/warehouse/new-warehouse-item',
title: 'Nuovo Oggetto'
}]
What I've tried to do is filtering like this way but it's incomplete (this.$router.history.current.path contains the string path):
menus.filter(menu => {
if(menu.children){
return menu.children.some(child => {
if(child.children){
return child.children.some(nephew => {
return nephew.path === this.$router.history.current.path;
})
} else {
return child.path === this.$router.history.current.path;
}
})
} else {
return menu.path === this.$router.history.current.path;
}
});
The following recursive code gives the requested filtering.
Please note that I included the given data "menus" in an Array for test purposes.
The cnt variable (int) is used for debugging purposes and indicates the level of recursion. It can be omitted.
The items variable (array of objects) is the initial array that contains the objects.
The target variable (string) is the desired path.
The sol variable (array of objects) is an initially empty array that will be populated with the paths that lead to the target.It must be cleared before any new call to itemFilter
let cnt = 0 //For debugging only
const itemFilter= function(items, target, cnt, sol ) {
cnt += 1
for( let i = 0; i<items.length; i++) {
let item = items[i]
if ( item.path == target) {
sol.push(item)
//console.log("DEBUG 1 : ", cnt, i, item.path, "Hit")
//console.log(sol)
return sol
}
//Otherwise...
//console.log(cnt, i, item.path, "No hit")
if (item.children) {
itemFilter(item.children, target, cnt, sol)
//console.log("DEBUG 2 : ", cnt, i)
//console.log(sol)
if (sol.length > 0) {
sol.push(item)
return sol
}
}
}
}
console.log("Suggested solution")
console.log("--------------------------------------------------------")
let t = "/actions/step/import"
console.log("CASE 1 : ", t)
let filteredItems = []
itemFilter(menus, t, 0, filteredItems)
console.log(filteredItems)
console.log("--------------------------------------------------------")
t = "/warehouse/new-warehouse-item"
console.log("CASE 2 : ", t)
filteredItems = []
itemFilter(menus, t, 0, filteredItems)
console.log(filteredItems)
console.log("--------------------------------------------------------")
t = "/UNDEFINEDPATH/anything"
console.log("CASE 3 : ", t)
filteredItems = []
itemFilter(menus, t, 0, filteredItems)
console.log(filteredItems)
/*This is the console output (without debugging) :
Suggested solution
--------------------------------------------------------
CASE 1 : /actions/step/import
[ { path: '/actions/step/import', title: 'Importazione' },
{ path: '/actions/step',
icon: 'fa fa-wine-bottle',
title: 'Fasi',
children:
[ [Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object] ] } ]
--------------------------------------------------------
CASE 2 : /warehouse/new-warehouse-item
[ { path: '/warehouse/new-warehouse-item',
title: 'Nuovo Oggetto' },
{ path: '/warehouse/list-warehouse-item',
title: 'Lista Oggetti',
children: [ [Object] ] },
{ path: '/warehouse',
icon: 'fa fa-warehouse',
title: 'Magazzino',
children: [ [Object] ] } ]
--------------------------------------------------------
CASE 3 : /UNDEFINEDPATH/anything
[]
*/
Based on the excellent contribute of #Myrer, to omit the children object I edited his script like this:
const itemFilter = function(items, target, sol) {
for(let i = 0; i < items.length; i++) {
let item = items[i];
if (item.path === target) {
const itemToPush = {
path: item.path,
title: item.title
};
if(item.icon){
itemToPush['icon'] = item.icon;
}
sol.push(itemToPush);
return sol;
}
if (item.children) {
itemFilter(item.children, target, sol);
if (sol.length > 0) {
const itemToPush = {
path: item.path,
title: item.title
};
if(item.icon){
itemToPush['icon'] = item.icon;
}
sol.push(itemToPush);
return sol;
}
}
}
}
let t = '/warehouse/new-warehouse-item';
let filteredItems = [];
itemFilter(this.menus, t, filteredItems);
console.log(filteredItems.reverse()); // Reversed the order of the array
// Output:
// [
// {
// "path": "/warehouse",
// "title": "Magazzino",
// "icon": "fa fa-warehouse"
// },
// {
// "path": "/warehouse/list-warehouse-item",
// "title": "Lista Oggetti"
// },
// {
// "path": "/warehouse/new-warehouse-item",
// "title": "Nuovo Oggetto"
// }
// ]
I am trying to add tasks for each todo list that has a specific title.
Can I get a specific todo list by its id and add some tasks to it?
I am new to javascript, so I searched google about adding lists for a specific list with no results :(
class Model {
constructor() {}
this.todos = [
{
id: 1,
title: 'Outside',
text: 'Running',
complete: false,
tasks: [
{ id: 1, text: 'Run a marathon', complete: false},
{ id: 2, text: 'Run with freinds', complete: false}
]
},
{
id: 2,
title: 'Garden',
text: 'Plant',
complete: false,
tasks: [
{ id: 1, text: 'Plant a garden', complete: false},
{ id: 2, text: 'Water the garden', complete: false}
]
}];
addTodo(todoText) {
const todo = {
id: this.todos.length > 0 ? this.todos[this.todos.length - 1].id + 1 : 1,
text: todoText,
complete: false,
tasks: []
}
this.todos.push(todo)
}
}
Is it true to do like addTodo function for adding a tasks for a specific todo list like this?
addTodoTask(todoTaskText) {
const todoTask = {
id: this.todos.tasks.length > 0 ? this.todos[this.todos.tasks.length - 1].id + 1 : 1,
text: todoText,
complete: false,
}
this.todos.tasks.push(todoTask)
}
and how to add a list of a list in javascript like:
<ul>
<li>Running
<ul>
<li>Run a marathon</li>
<li>Run with freind</li>
</ul>
</li>
</ul>
You could make each class handle rendering its own content and just map the list items consecutively while rendering from the top-down.
Edit: The render() methods make use of ES6 template literals. These are special strings that allow you embed variabes and expressions without the use of string concatenation.
const main = () => {
let todoList = new TodoList({ todos : getData() })
document.body.innerHTML = todoList.render()
}
class TodoTask {
constructor(options) {
this.id = options.id
this.text = options.text
this.complete = options.complete
}
render() {
return `<li>[${this.id}] ${this.text} (${this.complete})</li>`
}
}
class TodoEntry {
constructor(options) {
this.id = options.id
this.title = options.title
this.text = options.text
this.complete = options.complete
this.tasks = []
if (options.tasks) {
options.tasks.forEach(task => this.addTask(task))
}
}
addTask(task) {
this.tasks.push(new TodoTask(Object.assign({
id : (this.tasks.length || 0) + 1
}, task)))
}
render() {
return `<li>
[${this.id}] ${this.title} (${this.complete})
<ul>${this.tasks.map(task => task.render()).join('')}</ul>
</li>`
}
}
class TodoList {
constructor(options) {
this.todos = []
if (options.todos) {
options.todos.forEach(todo => this.addTodo(todo))
}
}
addTodo(todo) {
this.todos.push(new TodoEntry(Object.assign({
id : (this.todos.length || 0) + 1
}, todo)))
}
render() {
return `<ul>${this.todos.map(todo => todo.render()).join('')}</ul>`
}
}
function getData() {
return [{
id: 1,
title: 'Outside',
text: 'Running',
complete: false,
tasks: [{
id: 1,
text: 'Run a marathon',
complete: false
}, {
id: 2,
text: 'Run with freinds',
complete: false
}]
}, {
id: 2,
title: 'Garden',
text: 'Plant',
complete: false,
tasks: [{
id: 1,
text: 'Plant a garden',
complete: false
}, {
id: 2,
text: 'Water the garden',
complete: false
}]
}]
}
main() // entry
To add a task your todo, you should have a way of knowing which todo list you're updating. Like using the todo's id.
For example your addTaskToTodo will looks like so.
addTask(todoId, taskObject) {
// find that todos index
const todoIndex = this.todos.findIndex(todo => todo.id ===todoId);
// using that index update the tasks
this.todos[todoIndex].tasks.push(taskObject)
}
This assumes your taskObject already has all the properties. If you need to manually update its id, you can also do that before pushing by checking the length of the tasks and incrementing by 1.
I made an example of how to use dictionaries instead of arrays, and also a random ID. I think you will find it much cleaner and simpler:
class Model {
constructor() { }
todos = {
1: {
id: 1,
title: 'Outside',
text: 'Running',
complete: false,
tasks: {
1: { id: 1, text: 'Run a marathon', complete: false },
2: { id: 2, text: 'Run with freinds', complete: false }
}
},
2: {
id: 2,
title: 'Garden',
text: 'Plant',
complete: false,
tasks: {
1: { id: 1, text: 'Plant a garden', complete: false },
2: { id: 2, text: 'Water the garden', complete: false }
}
}
}
getRandomId = () => {
return '_' + Math.random().toString(36).substr(2, 9);
}
addTodo(todoText) {
const id = this.getRandomId();
const todo = {
id,
text: todoText,
complete: false,
tasks:{}
}
this.todos[id] = todo;
}
addTodoTask(todoTaskText,todoId) {//Pass also the id of the todo, to know where this task belongs to.
const id = this.getRandomId();
const todoTask = {
id,
text: todoTaskText,
complete: false,
}
this.todos[todoId].tasks[id] = todoTask
}
}
This way you could easily edit/remove both todos and tasks, just by their id, without using any messy Array.filter and such
I have an object in Angular that is being used in the library I'm using. When I wrote a new function I cannot pass this same object. I'm not sure why.
The object is called person. It's bound directly in the HTML. The object returns just 2 items from the cardsCollection array below.
The function I'm trying to write is called clickLike. I literally just want the same thing to happen whether someone clicks or swipes right. You can see the dev site here:
http://430designs.com/xperience/black-label-app/deck.php
Here's the entire controller.js file:
angular.module('black-label', ['ngTouch', 'ngSwippy'])
.controller('MainController', function($scope, $timeout, $window) {
$scope.cardsCollection = [
{
thumbnail: 'images/deck/thor_01.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_02.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_03.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_04.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_05.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/thor_06.jpg',
collection: 'thoroughbred',
}, {
thumbnail: 'images/deck/rhap_01.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_02.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_03.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_04.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_05.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/rhap_06.jpg',
collection: 'rhapsody',
}, {
thumbnail: 'images/deck/cha_01.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_02.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_03.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_04.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_05.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/cha_06.jpg',
collection: 'chalet',
}, {
thumbnail: 'images/deck/mod_01.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_02.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_03.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_04.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_05.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/mod_06.jpg',
collection: 'modern',
}, {
thumbnail: 'images/deck/ind_01.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_02.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_03.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_04.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_05.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/ind_06.jpg',
collection: 'indulgence',
}, {
thumbnail: 'images/deck/cnt_01.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_02.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_03.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_04.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_05.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/cnt_06.jpg',
collection: 'center-stage',
}, {
thumbnail: 'images/deck/vin_01.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_02.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_03.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_04.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_05.jpg',
collection: 'vineyard',
}, {
thumbnail: 'images/deck/vin_06.jpg',
collection: 'vineyard',
},
];
// Do the shuffle
var shuffleArray = function(array) {
var m = array.length,
t, i;
// While there remain elements to shuffle
while (m) {
// Pick a remaining element
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
};
$scope.deck = shuffleArray($scope.cardsCollection);
$scope.myCustomFunction = function() {
$timeout(function() {
$scope.clickedTimes = $scope.clickedTimes + 1;
$scope.actions.unshift({ name: 'Click on item' });
});
};
$scope.count = 0;
$scope.showinfo = false;
$scope.clickedTimes = 0;
$scope.actions = [];
$scope.picks = [];
var counterRight = 0;
var counterLeft = 0;
$scope.swipeend = function() {
$scope.actions.unshift({ name: 'Collection Empty' });
$window.location.href = 'theme-default.html';
}; //endswipeend
$scope.swipeLeft = function(person) {
//Essentially do nothing
$scope.actions.unshift({ name: 'Left swipe' });
$('.circle.x').addClass('dislike');
$('.circle.x').removeClass('dislike');
$(this).each(function() {
return counterLeft++;
});
}; //end swipeLeft
$scope.swipeRight = function(person) {
$scope.actions.unshift({ name: 'Right swipe' });
// Count the number of right swipes
$(this).each(function() {
return counterRight++;
});
// Checking the circles
$('.circle').each(function() {
if (!$(this).hasClass('checked')) {
$(this).addClass('checked');
return false;
}
});
$('.icon-like').addClass('liked');
$('.icon-like').removeClass('liked');
$scope.picks.push(person.collection);
// console.log('Picks: ' + $scope.picks);
// console.log("Counter: " + counterRight);
if (counterRight === 4) {
// Calculate and store the frequency of each swipe
var frequency = $scope.picks.reduce(function(frequency, swipe) {
var sofar = frequency[swipe];
if (!sofar) {
frequency[swipe] = 1;
} else {
frequency[swipe] = frequency[swipe] + 1;
}
return frequency;
}, {});
var max = Math.max.apply(null, Object.values(frequency)); // most frequent
// find key for the most frequent value
var winner = Object.keys(frequency).find(element => frequency[element] == max);
$window.location.href = 'theme-' + winner + '.html';
} //end 4 swipes
}; //end swipeRight
$scope.clickLike = function() {
$scope.swipeRight();
}; //clickLike
});
HTML file for the deck
<div class="ng-swippy noselect">
<div person="person" swipe-directive="swipe-directive" ng-repeat="person in peopleToShow" class="content-wrapper swipable-card">
<div class="card">
<div style="background: url({{person.thumbnail}}) no-repeat 50% 15%" class="photo-item"></div>
<div class="know-label">{{labelOk ? labelOk : "YES"}}</div>
<div class="dontknow-label">{{labelNegative ? labelNegative : "NO"}}</div>
</div>
<div class="progress-stats" ng-if="data">
<div class="card-shown">
<div class="card-shown-text">{{person.collection}}</div>
<div class="card-shown-number">{{person.subtitle}}</div>
</div>
<div class="card-number">{{collection.length - (collection.indexOf(person))}}/{{collection.length}}
</div>
</div>
<div class="container like-dislike" >
<div class="circle x" ng-click="$parent.$parent.clickDisike()"></div>
<div class="icon-like" ng-click="$parent.$parent.clickLike()"></div>
<div class="clearfix"></div>
</div>
</div><!-- end person-->
<div class="clearfix"></div>
If I'm leaving anything out please let me know.
Thanks in advance everyone!
I don't see how you get peopleToShow:
ng-repeat="person in peopleToShow"
Possibly you want to replace it with:
ng-repeat="person in cardsCollection"
because $scope.cardsCollection seems is where you store your thumbnails.
I'm getting this error after the Displaying Model Data step while trying to follow the TodoMVC demo app on the Ember site (http://guides.emberjs.com/v1.10.0/getting-started/). My javascript code up to this point is:
window.Todos = Ember.Application.create();
Todos.ApplicationAdapter = DS.FixtureAdapter.extend();
Todos.Router.map(function () {
this.resource('todos', { path: '/' });
});
Todos.TodosRoute = Ember.Route.extend({
model: function () {
return this.store.find('todo');
}
});
Todos.Todo = DS.Model.extend({
title: DS.attr('string'),
isCompleted: DS.attr('boolean')
});
Todos.Todo.FIXTURES = [
{
id: 1,
title: 'Learn Ember.js',
isCompleted: true
},
{
id: 2,
title: '...',
isCompleted: false
},
{
id: 3,
title: 'Profit!',
isCompleted: false
}
];
I think your router.map is wrong. Try using it in this way -
Todos.Router.map(
function () {
this.resource('todos', { path: '/' }, function () {
this.route('active');
this.route('completed');
});
});
I have been battling the level 7.4 review question with no luck:
Rating isn’t a object like Review was, so our createRating function will be a little different. We can addObject the currently selected rating to the array of ratings on our product. You’ll need to save the product to update it in the store.
I can not seem to get the value from the select list. Can anyone point me in the right direction or collaborate on this?
My handlebars code:
<script type='text/x-handlebars' data-template-name='product'>
<div class='row'>
<div class='col-sm-7'>
<h2>{{title}}</h2>
<h3 class='text-success'>${{price}}</h3>
<p class='text-muted'>{{description}}</p>
<p class='text-muted'>This Product has a {{rating}} star rating!</p>
<p>Finely crafted by {{#link-to 'contact' crafter}}{{crafter.name}}{{/link-to}}.</p>
{{render 'reviews' reviews}}
<div class='new-rating'>
<h3>Rate {{title}}</h3>
</div>
<div class='new-review'>
<h3>Review {{title}}</h3>
{{#if text}}
<p class='text-muted'>{{text}}</p>
{{/if}}
{{textarea valueBinding='text'}}
<button {{action 'createReview'}} class='btn-primary'>Review</button>
</div>
</div>
<div class='col-sm-5'>
<img {{bind-attr src='image'}} class='img-thumbnail img-rounded'/>
</div>
</div>
{{contact-details contact=crafter className='row'}}
{{view Ember.Select content=ratings value=selectedRating}}
<button {{action 'createRating'}} class='btn-primary'>Rating</button>
</script>
My js code:
var App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function() {
this.route('credits', { path: '/thanks' });
this.resource('products', function() {
this.resource('product', { path: '/:product_id' });
this.route('onsale');
this.route('deals');
});
this.resource('contacts', function() {
this.resource('contact', { path: '/:contact_id' });
});
});
App.IndexController = Ember.ArrayController.extend({
productsCount: Ember.computed.alias('length'),
logo: 'images/logo-small.png',
time: function() {
return (new Date()).toDateString();
}.property(),
onSale: function() {
return this.filterBy('isOnSale').slice(0,3);
}.property('#each.isOnSale')
});
App.ContactsIndexController = Ember.Controller.extend({
contactName: 'Anostagia',
avatar: 'images/avatar.png',
open: function() {
return ((new Date()).getDay() === 0) ? "Closed" : "Open";
}.property()
});
App.ProductsController = Ember.ArrayController.extend({
sortProperties: ['title']
});
App.ContactsController = Ember.ArrayController.extend({
sortProperties: ['name'],
contactsCount: Ember.computed.alias('length')
});
App.ReviewsController = Ember.ArrayController.extend({
sortProperties: ['reviewedAt'],
sortAscending: false
});
App.ContactProductsController = Ember.ArrayController.extend({
sortProperties: ['title']
});
App.ProductController = Ember.ObjectController.extend({
text: '',
ratings: [1,2,3,4,5],
selectedRating: 5,
actions: {
createReview: function(){
var review = this.store.createRecord('review', {
text: this.get('text'),
product: this.get('model'),
reviewedAt: new Date()
});
var controller = this;
review.save().then(function() {
controller.set('text', '');
controller.get('model.reviews').addObject(review);
});
},
createRating: function(){
var rating = this.store.createRecord('rating', {
rating: this.get('selectedRating.value'),
product: this.get('model'),
reviewedAt: new Date()
});
var controller = this;
rating.save().then(function() {
controller.get('model.rating').addObject(rating);
});
}
}
});
App.ProductsRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('product');
}
});
App.ContactsRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('contact');
}
});
App.IndexRoute = Ember.Route.extend({
model: function(){
return this.store.findAll('product');
}
});
App.ProductsIndexRoute = Ember.Route.extend({
model: function(){
return this.store.findAll('product');
}
});
App.ProductsOnsaleRoute = Ember.Route.extend({
model: function(){
return this.modelFor('products').filterBy('isOnSale');
}
});
App.ProductsDealsRoute = Ember.Route.extend({
model: function(){
return this.modelFor('products').filter(function(product){
return product.get('price') < 500;
});
}
});
App.ProductDetailsComponent = Ember.Component.extend({
reviewsCount: Ember.computed.alias('product.reviews.length'),
hasReviews: function(){
return this.get('reviewsCount') > 0;
}.property('reviewsCount')
});
App.ContactDetailsComponent = Ember.Component.extend({
productsCount: Ember.computed.alias('contact.products.length'),
isProductive: function() {
return this.get('productsCount') > 3;
}.property('productsCount')
});
App.ProductView = Ember.View.extend({
isOnSale: Ember.computed.alias('controller.isOnSale'),
classNameBindings: ['isOnSale']
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Product = DS.Model.extend({
title: DS.attr('string'),
price: DS.attr('number'),
description: DS.attr('string'),
isOnSale: DS.attr('boolean'),
image: DS.attr('string'),
reviews: DS.hasMany('review', { async: true }),
crafter: DS.belongsTo('contact', { async: true }),
ratings: DS.attr(),
rating: function(){
return this.get('ratings').reduce(function(previousValue, rating) {
return previousValue + rating;
}, 0) / this.get('ratings').length;
}.property('ratings.#each')
});
App.Product.FIXTURES = [
{ id: 1,
title: 'Flint',
price: 99,
description: 'Flint is a hard, sedimentary cryptocrystalline form of the mineral quartz, categorized as a variety of chert.',
isOnSale: true,
image: 'images/products/flint.png',
reviews: [100,101],
crafter: 200,
ratings: [2,1,3,3]
},
{
id: 2,
title: 'Kindling',
price: 249,
description: 'Easily combustible small sticks or twigs used for starting a fire.',
isOnSale: false,
image: 'images/products/kindling.png',
reviews: [],
crafter: 201,
ratings: [2,1,3,3]
},
{
id: 3,
title: 'Matches',
price: 499,
description: 'One end is coated with a material that can be ignited by frictional heat generated by striking the match against a suitable surface.',
isOnSale: true,
reviews: [],
image: 'images/products/matches.png',
crafter: 201,
ratings: [2,1,3,3]
},
{
id: 4,
title: 'Bow Drill',
price: 999,
description: 'The bow drill is an ancient tool. While it was usually used to make fire, it was also used for primitive woodworking and dentistry.',
isOnSale: false,
reviews: [],
image: 'images/products/bow-drill.png',
crafter: 200,
ratings: [1,3,3]
},
{
id: 5,
title: 'Tinder',
price: 499,
description: 'Tinder is easily combustible material used to ignite fires by rudimentary methods.',
isOnSale: true,
reviews: [],
image: 'images/products/tinder.png',
crafter: 201,
ratings: [2,1,3]
},
{
id: 6,
title: 'Birch Bark Shaving',
price: 999,
description: 'Fresh and easily combustable',
isOnSale: true,
reviews: [],
image: 'images/products/birch.png',
crafter: 201,
ratings: [2,3,5]
}
];
App.Contact = DS.Model.extend({
name: DS.attr('string'),
about: DS.attr('string'),
avatar: DS.attr('string'),
products: DS.hasMany('product', { async: true })
});
App.Contact.FIXTURES = [
{
id: 200,
name: 'Giamia',
about: 'Although Giamia came from a humble spark of lightning, he quickly grew to be a great craftsman, providing all the warming instruments needed by those close to him.',
avatar: 'images/contacts/giamia.png',
products: [1,4]
},
{
id: 201,
name: 'Anostagia',
about: 'Knowing there was a need for it, Anostagia drew on her experience and spearheaded the Flint & Flame storefront. In addition to coding the site, she also creates a few products available in the store.',
avatar: 'images/contacts/anostagia.png',
products: [2,3,5,6]
}
];
App.Review = DS.Model.extend({
text: DS.attr('string'),
reviewedAt: DS.attr('date'),
product: DS.belongsTo('product')
});
App.Review.FIXTURES = [
{
id: 100,
text: "Started a fire in no time!"
},
{
id: 101,
text: "Not the brightest flame, but warm!"
}
];
After detailed research, the answer turned out being:
createRating: function() {
var prod = this.get('model');
var ratings = this.get('model.ratings');
ratings.addObject(this.selectedRating);
prod.save();
}
In the code shown, you should be getting the rating using this.get('selectedRating') not this.get('selectedRating.value')
http://emberjs.jsbin.com/xohidixe/1/edit