function doesnt work, add to favorites E-commerce project - javascript

what I need to do is when I click on the heartBtn it turns red and add the item to an array of objects in the localstorage productsInFavArr and when I click again it should turns grey and remove the object from productsInFavArr.
the adding function is working perfectly in added the item to the arr part but the drawProductUI function supposed to check if the product exist in the productsInFacArr the btn will be red and if not its gonna be grey, so i put the drawProductUIfunction in the adding and removing function after adding and removing the item but it doesnt work till I reload the page
and the removing function remove the object from the arr after two click and still doesnt change colot of the btn
so my main problem is changing the color of the btn after adding or removing the item and the removing function remove the item after two clicks
here is the code:
// Draw Product UI
function drawProductUI(array){
var productsUI = array.map((item) => {
if (productsInFavArr) {
for (const favProd of productsInFavArr){
if (favProd.id === item.id) {
// console.log(favProd);
return `
<div class="product-item">
<div class="product-img-container">
<img src=${item.imgURL} alt="products" class="product-img" width="100%" height="150px">
</div>
<div class="product-text">
<h2 class="product-title">${item.title}</h2>
<span class="product-desc">${item.desc}</span>
<p class="product-price">USD ${item.price}</p>
</div>
<div class="product-btns">
<button class="add-to-cart">Add To Cart</button>
<button class="heart-btn heart-icon-red" onclick="removeItemFromFav( ${item.id} )"><i class="far fa-heart"></i></button>
</div>
</div>
`;
}
}}
return`
<div class="product-item">
<div class="product-img-container">
<img src=${item.imgURL} alt="products" class="product-img" width="100%" height="150px">
</div>
<div class="product-text">
<h2 class="product-title">${item.title}</h2>
<span class="product-desc">${item.desc}</span>
<p class="product-price">USD ${item.price}</p>
</div>
<div class="product-btns">
<button class="add-to-cart">Add To Cart</button>
<button class="heart-btn heart-icon" ><i class="far fa-heart"></i></button>
</div>
</div>
`
});
productsContainer.innerHTML = productsUI.join("");
}
drawProductUI(allProducts)
// add to favorites
for(let f=0; f < heartBtn.length; f++){
heartBtn[f].addEventListener("click" ,()=>{
addToFavorites(allProducts[f]);
function addToFavorites(product){
if (localStorage.getItem("userValidate") && localStorage.getItem("passValidate")) {
let productsInFavObj = localStorage.getItem("productsInFavObj");
productsInFavObj = JSON.parse(productsInFavObj);
if(productsInFavObj != null){
if(productsInFavObj[product.id] == undefined){
productsInFavObj = {
...productsInFavObj,
[product.id] : product
}
}
}else{
productsInFavObj = {
[product.id] : product
}
}
let productsInFavArr = Object.values(productsInFavObj)
localStorage.setItem("productsInFavArr" , JSON.stringify(productsInFavArr) )
localStorage.setItem("productsInFavObj" , JSON.stringify(productsInFavObj) )
}else{
window.location.href = "login.html";
}
}
drawProductUI(allProducts)
})
}
// Remove From Favorite
function removeItemFromFav(id){
for(let f=0; f < heartBtn.length; f++){
let productsInFavArr = localStorage.getItem("productsInFavArr")
if(productsInFavArr){
let items = JSON.parse(productsInFavArr);
console.log("removed item:",allProducts[f]);
let filteredItems = items.filter((item) => item.id !== id);
localStorage.setItem("productsInFavArr" , JSON.stringify(filteredItems));
localStorage.setItem("productsInFavObj" , JSON.stringify(filteredItems) )
drawProductUI(allProducts)
console.log(filteredItems);
if(filteredItems.length==0){
localStorage.removeItem("productsInFavArr")
localStorage.removeItem("productsInFavObj")
}
}
}
}
and here is an example of the products
let products = [
{
title: "Sunglasses",
imgURL: "images/Products/sunglasses.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:80,
id: 1
},
{
title: "Laptop",
imgURL: "images/Products/laptop.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:100,
id: 2
},
{
title: "Microphone",
imgURL: "images/Products/mic.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:75,
id: 3
},
{
title: "Cat",
imgURL: "images/Products/cat.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:200,
id: 4
},
]
thanks

In the drawProductUI function you are not reading local storage value, but it depends on productsInFavArr which is probably only reading the local storage value ONCE. I think you need to grab the fresh value whenever you call drawProductUI in order to reflect changes made to local storage without reloading the page.
function drawProductUI(array){
let productsInFavArr = JSON.parse(localStorage.getItem("productsInFavArr")) || []; // read the value here so it's fresh before redraw happens
var productsUI = array.map((item) => {
// rest of the function code
In the drawProductUI function you define handler for selected items:
<button class="heart-btn heart-icon-red" onclick="removeItemFromFav(${item.id})">
<i class="far fa-heart"></i>
</button>
You should do the same for the unselected button version:
<button class="heart-btn heart-icon" onclick="addToFavorites(${item.id})">
<i class="far fa-heart"></i>
</button>
this way the click handler will be attached every time you redraw the UI not only once when the js file is being read, which is the case when you define the handler as you currently do.
Having this in place you need to define the addToFavorites function at the top level, so outside of the loop, just as you define removeItemFromFav.
Since the handler takes id of the product now, you need to find the appropriate product before processing it.
You also want to redraw the UI when this is clicked so add the appropriate method to the bottom of the function.
I've attached comments indicating those changes:
function addToFavorites(id){ // this is now defined at the top level as removeItemFromFav
if (localStorage.getItem("userValidate") && localStorage.getItem("passValidate")) {
const product = allProducts.find(p => p.id == id); // this and next lines handle product lookup
if (!product) { return; }
let productsInFavObj = localStorage.getItem("productsInFavObj");
productsInFavObj = JSON.parse(productsInFavObj);
if(productsInFavObj != null){
if(productsInFavObj[id] == undefined){
productsInFavObj = {
...productsInFavObj,
[id] : product
}
}
}else{
productsInFavObj = {
[id] : product
}
}
let productsInFavArr = Object.values(productsInFavObj)
localStorage.setItem("productsInFavArr" , JSON.stringify(productsInFavArr) )
localStorage.setItem("productsInFavObj" , JSON.stringify(productsInFavObj) )
drawProductUI(allProducts); // this redraws the UI
}else{
window.location.href = "login.html";
}
}
Last thing you want to correct is the removeItemFromFav function.
Loop is unnecessary
function removeItemFromFav(id){
// loop is gone now, also console.logs are gone
let productsInFavArr = localStorage.getItem("productsInFavArr")
if(productsInFavArr){
let items = JSON.parse(productsInFavArr);
let filteredItems = items.filter((item) => item.id !== id);
localStorage.setItem("productsInFavArr" , JSON.stringify(filteredItems));
localStorage.setItem("productsInFavObj" , JSON.stringify(filteredItems) )
drawProductUI(allProducts)
if(filteredItems.length==0){
localStorage.removeItem("productsInFavArr")
localStorage.removeItem("productsInFavObj")
}
}
}

Related

How can I make html file dynamic with angularjs

I have an html file and a JS file. The JS file contains some data that I want to present in the html file depending on a clicked link from another html file
html file:
<div class="jumbotron mb-5">
{{product.name}}
</div>
<div class="jumbotron mb-5">
{{product.price}}
</div>
<div class="jumbotron mb-5">
{{product.description}}
</div>
js file
var app = angular.module('app', [']);
app.controller('prodCtrl', function ($scope) {
$scope.courses = [
{
id: 1,
name: 'prod 1',
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid ea fugit
tempore error, tenetur adipisci hic voluptas sapiente distinctio,.',
price: 100,
image: 'public/photos/prod1.png'
},
{
id: 2,
name: 'prod 2',
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit.',
price: 30,
image: 'public/photos/prod2.png'
},
];
});
in another html page I have the products listed as links and I want to present them in the html page up there depending on the link I clicked
You would pass the param in the route with ui-router
It sounds like you're asking for dynamic routing. There are a few questions about this on SO, but to point you in the right direction for what you're doing:
You have to declare your routes in the app config like so:
angular.module('myApp', [
'ui.router'
])
.config(function($stateProvider) {
$stateProvider
.state({
name: 'product',
url: '/product/{id}', //{id} or :id will tell it to expect the param
templateUrl: '/products/index.html',
controller: 'ProdCtrl'
});
});
Inside your index.html file, make sure you add:
<div ng-app="myApp">
<ui-view></ui-view>
</div>
(or where you want the content to appear)
And finally, your controller:
.controller('ProdCtrl', function($scope, $stateParams) {
//get id from the url and convert it to an int to match data type in courses id
//may want to consider doing some validation
$scope.productId = parseInt($stateParams.id);
var courses = [
{
id: 1,
name: 'prod 1',
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit.',
price: 100,
image: 'public/photos/prod1.png'
},
{
id: 2,
name: 'prod 2',
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit.',
price: 30,
image: 'public/photos/prod2.png'
}
];
//find the matching item by id and set it to scope
$scope.product = courses.map(function(item) {
if (item.id === $scope.productId) {
return item;
}
});
});
You should now be able to go to /product/1 and see prod 1
Please note this is untested code, but should get you on the right track. I also renamed a couple things for clarity and be more aligned with common practices (e.g. myApp and ProdCtrl).
If you go through the ui-router documentation, you can also achieve this without using the id in the url and have it pass params in the background. This would mean you can only access that page via links in your app and not deep link them.

how to display table using handlebars with array of Object

I creating a web app using express-generator using handlebar as templating engine. If I display array of object from response, it displays. But, when I each loop in view display nothing.
/********************************
model file ../controllers/books.js
*********************************/
var request = require('request');
exports.list = function(req, res, next){
request.get({ url: "https://jsonplaceholder.typicode.com/posts" }, function(error, response, body) {
if (!error && response.statusCode == 200) {
res.render('index', { title: 'speed Tracker', list: body });
}
});
};
/***********************
route file
************************/
var express = require('express');
var router = express.Router();
var books = require('../controllers/books');
/* GET home page. */
router.get('/', books.list);
<!-- language: lang-html -->
<table id="datatable" class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Album Id</th>
<th>title</th>
<th>url</th>
<th>image</th>
</tr>
</thead>
{{list}}
<tbody>
{{#each list}}
<tr>
<td>{{id}}</td>
<td>{{userId}}</td>
<td>{{title}}</td>
<td>{{body}}</td>
<td></td>
</tr>
{{/each}}
</tbody>
</table>
json of list
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
},
{.....
I have added code above data is not display in each loop.
I have to convert list from String to Object in book.js file. I have add the code below.
var request = require('request');
exports.list = function(req, res, next){
request.get({ url: "https://jsonplaceholder.typicode.com/posts" }, function(error, response, body) {
if (!error && response.statusCode == 200) {
res.render('index', { title: 'speed Tracker', list: JSON.parse(body) }); // add JSON.parse to convert string to object :)
}
});
};

Underscore template can't access data model

I am having difficulty accessing model data with underscore, nothing is appearing on screen and I'm not getting any errors. Any help would be greatly appreciated.
Here is my templating area
<script type='text/template' id='ListContainerView'>
<p> <%= ListItemModel.id %> </p>
<p> <%= ListItemModel.network %> </p>
<p> <%= ListItemModel.created_by_id %> </p>
</script>
Collection
var ListItemCollection = Backbone.Collection.extend({
baseUrl: '/api/get_accounts',
url: '/api/get_accounts',
model: ListItemModel,
total: 0,
// Sample data
TESTDATA: {"status":"ok","posts":[{"id":"1","schedule":"2020-0417 17:00:00","utc_offset":"420","project_id":"1","network":"facebook","network_name":"TestFacebookPage","network_thumb":"https://scontent.xx.fbcdn.net/v/t1.0-9/17634406_1854330461448271_6787736791983791423_n.jpg?oh=e4c3a3573c0fc59359422cfd66a3865a&oe=598721E7","message":"Test Post 1 (just text, approved)","data":[],"customer_approved":"1","manager_approved":"1","rejection_message":"","created_at":"2020-0413 17:41:03","created_by":"admin","created_by_id":"1","created_by_name":"John Admin"},{"id":"2","schedule":"2020-0419 19:00:00","project_id":"1","network":"facebook","network_name":"TestFacebookPage","network_thumb":"https://scontent.xx.fbcdn.net/v/t1.0-9/17634406_1854330461448271_6787736791983791423_n.jpg?oh=e4c3a3573c0fc59359422cfd66a3865a&oe=598721E7","message":"Test Post 2 (text with image, approved) Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.","data":{"pictures":["https://pbs.twimg.com/media/C9T6n0UUwAAOBaU.jpg"],"image_added":"true","picture":"https://pbs.twimg.com/media/C9T6n0UUwAAOBaU.jpg","type":"photo"},"customer_approved":"1","manager_approved":"1","rejection_message":"","rejection_message_manager":"","created_at":"2020-0413 17:42:34","created_by":"admin","created_by_id":"1","created_by_name":"John Admin"},{"id":"3","schedule":"2020-0421 22:00:00","network":"facebook","network_name":"TestFacebookPage","network_thumb":"https://scontent.xx.fbcdn.net/v/t1.0-9/17634406_1854330461448271_6787736791983791423_n.jpg?oh=e4c3a3573c0fc59359422cfd66a3865a&oe=598721E7","message":"Test Post 3 (link, approved) http://www.adultswim.com/videos/rick-and-morty/","data":{"image_added":"true","pictures":["http://i.cdn.turner.com/adultswim/big/img/2015/07/17/Rick%26MortyS02_fbsearchTn.jpg"],"picture":"http://i.cdn.turner.com/adultswim/big/img/2015/07/17/Rick%26MortyS02_fbsearchTn.jpg","link":"http://www.adultswim.com/videos/rick-and-morty/","name":"Watch Rick and Morty on Adult Swim","caption":"www.adultswim.com","description":"Every episode of Rick and Morty is now on AdultSwim.com for free. Rick is a mad scientist who drags his grandson, Morty, on crazy sci-fi adventures. Their escapades often have potentially harmful consequences for their family and the rest of the world. Join Rick and Morty on AdultSwim.com as they trek through alternate dimensions, explore alien planets, and terrorize Jerry, Beth, and Summer.","domain":"www.adultswim.com","type":"link"},"customer_approved":"1","manager_approved":"1","rejection_message":"","created_at":"2020-0413 17:43:29","created_by":"admin","created_by_id":"1","created_by_name":"John Admin"},{"id":"4","schedule":"2020-0424 17:00:00","network":"facebook","network_name":"TestFacebookPage","network_thumb":"https://scontent.xx.fbcdn.net/v/t1.0-9/17634406_1854330461448271_6787736791983791423_n.jpg?oh=e4c3a3573c0fc59359422cfd66a3865a&oe=598721E7","message":"Test Post 4 (text, pending)","data":[],"customer_approved":"0","manager_approved":"1","rejection_message":"","created_at":"2020-0413 17:43:48","created_by":"admin","created_by_id":"1","created_by_name":"John Admin"},{"id":"5","schedule":"2020-0426 19:00:00","network":"facebook","network_name":"TestFacebookPage","network_thumb":"https://scontent.xx.fbcdn.net/v/t1.0-9/17634406_1854330461448271_6787736791983791423_n.jpg?oh=e4c3a3573c0fc59359422cfd66a3865a&oe=598721E7","message":"Test Post 5 (picture, pending)","data":[],"customer_approved":"0","manager_approved":"1","rejection_message":"","created_at":"2020-0413 17:44:03","created_by":"admin","created_by_id":"1","created_by_name":"John Admin"},{"id":"6","schedule":"2020-0428 21:00:00","network":"facebook","network_name":"TestFacebookPage","network_thumb":"https://scontent.xx.fbcdn.net/v/t1.0-9/17634406_1854330461448271_6787736791983791423_n.jpg?oh=e4c3a3573c0fc59359422cfd66a3865a&oe=598721E7","message":"Test Post 6 (link, pending) https://www.reddit.com/","data":{"image_added":"true","pictures":["https://b.thumbs.redditmedia.com/2Hwaff37fC4f37j-3orrbjVAOVBChqbdm_dXeIhjlNw.jpg"],"picture":"https://b.thumbs.redditmedia.com/2Hwaff37fC4f37j-3orrbjVAOVBChqbdm_dXeIhjlNw.jpg","link":"https://www.reddit.com/","name":"reddit: the front page of the internet","caption":"www.reddit.com","description":"reddit: the front page of the internet","domain":"www.reddit.com","type":"link"},"customer_approved":"0","manager_approved":"1","rejection_message":"","created_at":"2020-0413 17:44:19","created_by":"admin","created_by_id":"1","created_by_name":"John Admin"}],"total":"6"},
initialize: function(models, options) {
this.total = this.TESTDATA.total;
this.reset(this.TESTDATA.posts);
}
})
Views...
var ListContainerView = SOCIView.extend({
template: _.template($('#ListContainerView').text()),
className: 'ListContainerView'
})
var SOCIView = Backbone.View.extend({
render: function() {
if (typeof this.beforeRender === 'function') {
this.beforeRender();
}
var modelData = { };
if (this.model && this.model instanceof Backbone.Model) {
modelData = this.model.toJSON();
}
if (typeof this.template === 'function') {
this.$el.html(this.template(modelData));
}
if (typeof this.afterRender === 'function') {
this.afterRender();
}
return this;
}
})
and script inside HTML...
<script type="text/javascript">
$(document).ready(function() {
// Instantiate and render Backbone view
$('.home_body').append( new ListContainerView({
collection: new ListItemCollection(),
}).render().el)
});
</script>
The toJSON method on a Backbone model gives you a simple copy of the model attributes. In your case, this:
modelData = this.model.toJSON();
should give you an object that looks like this:
{
id: 1,
schedule: "2020-0417 17:00:00",
utc_offset: "420",
...
}
Notice that there is no ListItemModel anywhere in that object. That object would be suitable for a template that looks like this:
<p> <%= id %> </p>
<p> <%= network %> </p>
<p> <%= created_by_id %> </p>
If you really wanted the ListItemModel prefixes in the template then you'd want to say:
this.template({ ListItemModel: modelData })
when calling the template function.
Alternatively you could compile the template using the {variable: 'ListItemModel'} option to _.template and leave the template and this.template call alone. So your view would have:
template: _.template($('#ListContainerView').html(), { variable: 'ListItemModel'),
and the rest wouldn't change.
Where you define your template for the ListContainerView, I think using .text() (instead of .html()) might be causing your problem. Instead try
template: _.template($('#ListContainerView').html())
and see if it works.
Jquery's .text() ignores html markup like <span> or <strong> tags (etc), so it may be removing your templating tags <% ... %> as well, giving you just a few spaces.

Angularjs - UI Boostrap: Accordion Open and close all

i have written some code to open and close all tabs of an accordion respectively use a separate 'open' and 'close' button. How ever it requires me to dynamically add a key value pair(a Boolean value) to my json data.
What is the best practice in this situation? should i add the Boolean value as a static json element or is it OK to dynamically add values when their sole purpose is for visual structure and not relevant to actual object data.
HTML/Angular directives
<div id="app" ng-app="demoApp">
<div id="controller" ng-controller="demoAppCtrl">
<uib-accordion close-others="false">
<div class="btn-group form-group">
<button type="button" class="btn btn-warning" ng-click="toggle(true)">Open</button>
<button type="button" class="btn btn-warning" ng-click="toggle(false)">Close</button>
</div>
<uib-accordion-group is-open="hero.state" ng-click="setOpened(false)" ng-repeat="hero in heroes">
<uib-accordion-heading>
{{hero.name}}
</uib-accordion-heading>
{{hero.bio}}
</uib-accordion-group>
</uib-accordion>
</div>
</div>
Javascript/Angular
var app = angular.module('demoApp', ['ngAnimate','ui.bootstrap']);
app.controller('demoAppCtrl', function($scope) {
// This json object contain only one entry as an example
$scope.heroes = [
{'name': 'Captain America', 'team': 'Avengers', 'bio': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae metus placerat, condimentum nisl et, accumsan sapien. Quisque molestie magna nulla, id malesuada sem interdum a.'}
];
$scope.addDefaultState = function(val) {
for (var i=0;i<$scope.heroes.length;i++) {
$scope.heroes[i].state = val;
}
}
$scope.addDefaultState(false);
$scope.toggle = function(status) {
$scope.heroes.forEach(function(e) {
e.state = status;
});
}
});
codepen.io - Working example (with corrections)
In my opinion the static json should not contain Boolean state value. It is okay to dynamically add values for visual presentation.
In your code the function addDefaultState is not needed. The is-open="hero.state" will take care of default state cause initially it will not find state and will consider it as false. So you change your code like below it should work too:
var app = angular.module('demoApp', ['ngAnimate','ui.bootstrap']);
app.controller('demoAppCtrl', function($scope) {
// This json object contain only one entry as an example
$scope.heroes = [
{'name': 'Captain America', 'team': 'Avengers', 'bio': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae metus placerat, condimentum nisl et, accumsan sapien.'}
];
$scope.toggle = function(status) {
$scope.heroes.forEach(function(e) {
e.state = status;
});
}
});

How to create a custom <select> filter in Angular.js using 2 JSON options

I have a Q&A JSON feed with the following:
"questions": [
{
"answer": "Ea et non sunt dolore nulla commodo esse laborum ipsum minim non.",
"id": 0,
"poster": "Chelsea Vang",
"question": "Ex ex elit cupidatat ullamco labore quis cupidatat. Reprehenderit occaecat mollit ex proident aliqua. Anim minim in labore pariatur adipisicing velit dolore elit nostrud proident reprehenderit in voluptate.",
"userAsked": false
},
{
"answer": null,
"id": 1,
"poster": "Serena Randolph",
"question": "Esse occaecat anim cupidatat eu sit ad eiusmod. Et tempor deserunt ea ipsum velit irure elit qui. Ipsum qui labore laboris Lorem occaecat enim Lorem exercitation ut non duis. Sit cillum incididunt culpa ipsum.",
"userAsked": true
}
]
I want to create a custom filter that allows you to filter (by select dropdown) the results by: All Questions, "userAsked: true" a.k.a My Questions, and Answered Questions (so questions that are not 'null' in this case it would be something like !null?). I know how to create a custom filter for a single object, but can't figure out how to do it in this instance since I am trying to filter by more then one option-I can't do an ng-repeat for the select options because of this.. unless I am under the wrong impression.
My view looks something like this:
<select>
<option value="all">All Questions</option>
<option value="answered">Answered Questions</option>
<option value="mine">My Questions</option>
</select>
<ul class="list-unstyled">
<li ng-repeat="questions in qa.questions">
<strong>Question:</strong><br>
{{questions.question}}<br>
<strong>Answer:</strong><br>
{{questions.answer}}
<hr>
</li>
</ul>
Controller:
sessionControllers.controller('SessionDetailCtrl', ['$scope', '$routeParams', 'SessionFactory', 'CommentsFactory', 'QAFactory', function($scope, $routeParams, SessionFactory, CommentsFactory, QAFactory){
$scope.session = SessionFactory.get({id: $routeParams.id});
$scope.comments = CommentsFactory.get({eventId: $routeParams.id});
$scope.qa = QAFactory.get({eventId: $routeParams.id});
}]);
Please help! Thank you :)
I was able to figure it out by implementing some of what #tymeJV suggested.
View
<select ng-model="filterItem.question" ng-options="item.questionType for item in filterOptions.questions">
<option value="All Questions">All Questions</option>
<option value="Answered Questions">Answered Questions</option>
<option value="My Questions">My Questions</option>
</select>
<ul>
<li ng-repeat="questions in qa.questions | filter: myCustomFilter">
<strong>Question:</strong>
<br>{{questions.question}}<br>
<strong>Answer:</strong><br>
{{questions.answer}}
</li>
</ul>
Controller
$scope.filterOptions = {
questions: [
{questionType: 'All Questions'},
{questionType: 'Answered Questions'},
{questionType: 'My Questions'}
]
};
//Mapped to the model to filter
$scope.filterItem = {
question: $scope.filterOptions.questions[0]
};
//Custom filter - filter based on the QuestionType selected
$scope.myCustomFilter = function (data) {
if ($scope.filterItem.question.questionType === "All Questions") {
return true;
} else if ($scope.filterItem.question.questionType === 'Answered Questions') {
return data.answer != null;
} else if ($scope.filterItem.question.questionType === 'My Questions') {
return data.userAsked;
}
};
Hmm, attach a model to your select filter and try something like this:
<select ng-model="questionFilter">
<option value="all">All Questions</option>
<option value="answered">Answered Questions</option>
<option value="mine">My Questions</option>
</select>
<li ng-repeat="questions in qa.questions | filter: myCustomFilter">
And the controller:
$scope.myCustomFilter = function(item) {
if (questionFilter == "all") {
return true;
} else if (questionFilter == "answered") {
return item.answer != null;
} else if (questionFilter == "mine")
return item.userAsked;
}

Categories

Resources