Showing result from array once then looping through second array - javascript

I have two arrays that I am using to simulate two different REST call's JSON response for the time with some static data. One to get the available active categories and another to get all links and then search to find what links go with what category.
The goal here is to build out a navigation that will take each category and display the corresponding links underneath each.
Currently I am unable to get the category to display only once and above the links related to each category then draw the output to the dom once complete.
I tried to use $.one but that did not work. Does anyone have any pointers or suggestions to nudge me in the right direction?
var links = [
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com"
},
"Id": 01,
"Title": "Link 01 - test category 01",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 01"
]
},
"Image": null,
"ID": 01
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 02,
"Title": "Link 02 - test category 01",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 01"
]
},
"Image": null,
"ID": 02
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 03,
"Title": "Link 01 - test category 02",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 02"
]
},
"Image": null,
"ID": 209
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 210,
"Title": "Link 02 - test category 02",
"Link": "https://www.somerandomdomain.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 02"
]
},
"Image": null,
"ID": 210
}
]
//category arr
var categoryArr = [
"Test Category 01",
"Test Category 02",
"Test Category 03"
]
var categoryTitle;
var menu = $("#output2");
$.each(categoryArr, function (catIndex, category) {
$.each(links, function(linkIndex, links) {
if(links.Category.results == category) {
// DOM ELEMENTS
var item = $('<div>').addClass('navContainer'),
title = $('<h4>'),
info = $('<p>'),
link = $('<a>');
// CATEGORY TITLE
info.text(categoryArr[catIndex]); // not showing once per iteration.
// ADD LINKS
link.attr('href',links.Link)
.text(links.Title)
.appendTo(title);
// ADD EVERYTHING
item.append(info,title);
// DISPLAY TO CONTAINER
item.appendTo(menu);
}
})// end glinks
}) // end categoryArr
.navContainer {
border: 1px solid grey;
margin: 10px;
padding:5px;
}
.links ul li {
list-style-type:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output2"></div>
<hr>
<!-- result should be like this -->
<h5>
Result should look like this below
</h5>
<div class="navContainer">
<div class="title">Category title</div>
<div class="links">
<ul>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
</ul>
</div>
</div>
</div>
<div class="navContainer">
<div class="title">Category title</div>
<div class="links">
<ul>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
</ul>
</div>
</div>
</div>
etc.. etc..

You are creating everything inside your inner loop, so for each link you are creating a new item, title, etc.
Also the links.Category.results is an array, whilst you check it as so: links.Category.results == category. To check whether the Category.results contains the category string, you should use indexOf() (or includes(), but it has worse browser support).
Here's a fixed snippet:
var links = [{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com"
},
"Id": 01,
"Title": "Link 01 - test category 01",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 01"
]
},
"Image": null,
"ID": 01
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 02,
"Title": "Link 02 - test category 01",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 01"
]
},
"Image": null,
"ID": 02
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 03,
"Title": "Link 01 - test category 02",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 02"
]
},
"Image": null,
"ID": 209
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 210,
"Title": "Link 02 - test category 02",
"Link": "https://www.somerandomdomain.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 02"
]
},
"Image": null,
"ID": 210
}
]
//category arr
var categoryArr = [
"Test Category 01",
"Test Category 02",
"Test Category 03"
]
var categoryTitle;
var menu = $("#output2");
$.each(categoryArr, function(catIndex, category) {
// DOM ELEMENTS
var $item = $('<div>').addClass('navContainer');
var $title = $('<div>').addClass('title').appendTo($item);
var $links = $('<ul>').appendTo(
$('<div>').addClass('links').appendTo($item)
);
// CATEGORY TITLE
$title.text(category);
$.each(links, function(linkIndex, link) {
var $link = $('<a>');
if (link.Category.results.indexOf(category) != -1) {
// ADD LINKS
$link.attr('href', link.Link)
.text(link.Title)
.appendTo($('<li>').appendTo($links));
}
}) // end glinks
// DISPLAY TO CONTAINER
$item.appendTo(menu);
}) // end categoryArr
.navContainer {
border: 1px solid grey;
margin: 10px;
padding: 5px;
}
.links ul li {
list-style-type: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output2"></div>
<hr>
<!-- result should be like this -->
<h5>
Result should look like this below
</h5>
<div class="navContainer">
<div class="title">Category title</div>
<div class="links">
<ul>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
</ul>
</div>
</div>
<div class="navContainer">
<div class="title">Category title</div>
<div class="links">
<ul>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
</ul>
</div>
</div>

Assign the links first and then do the UI stuff.
var links = [
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com"
},
"Id": 01,
"Title": "Link 01 - test category 01",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 01"
]
},
"Image": null,
"ID": 01
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 02,
"Title": "Link 02 - test category 01",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 01"
]
},
"Image": null,
"ID": 02
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 03,
"Title": "Link 01 - test category 02",
"Link": "https://www.google.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 02"
]
},
"Image": null,
"ID": 209
},
{
"__metadata": {
"id": "",
"uri": "http://www.whatever.com",
"etag": "",
"type": ""
},
"Id": 210,
"Title": "Link 02 - test category 02",
"Link": "https://www.somerandomdomain.com",
"Category": {
"__metadata": {
"type": ""
},
"results": [
"Test Category 02"
]
},
"Image": null,
"ID": 210
}
]
//category arr
var categoryArr = [
"Test Category 01",
"Test Category 02",
"Test Category 03"
]
var categories = categoryArr.map(function(label){
var category = {}
category.label = label
category.links = []
for(var i in links){
if(links[i].Category.results.indexOf(label)!=-1)
category.links.push(links[i])
}
return category
})
var menu = $("#output2");
$.each(categories, function (catIndex, category) {
var item = $('<div>').addClass('navContainer'),
title = $('<h4>'),
linklist = $('<ul>')
title.text(category.label)
$.each(category.links, function(linkIndex, link) {
var li = $('<li>')
// ADD LINK
$('<a>').attr('href',link.Link)
.text(link.Title)
.appendTo(li);
li.appendTo(linklist)
})
// ADD EVERYTHING
item.append(title,linklist);
// DISPLAY TO CONTAINER
item.appendTo(menu);
})
.navContainer {
border: 1px solid grey;
margin: 10px;
padding:5px;
}
.links ul li {
list-style-type:none;
}
a{
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output2"></div>
<hr>
<!-- result should be like this -->
<h5>
Result should look like this below
</h5>
<div class="navContainer">
<div class="title">Category title</div>
<div class="links">
<ul>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
</ul>
</div>
</div>
</div>
<div class="navContainer">
<div class="title">Category title</div>
<div class="links">
<ul>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
<li>http://www.google.com</li>
</ul>
</div>
</div>
</div>

Related

How to dynamically filter JSON data based on category

[
{
"category": "Beauty",
"subcategories": [
{
"name": "Baby Care",
"items": [
{
"name": "soap",
"price": 10.00
},
{
"name": "cream",
"price": 20.00
},
{
"name": "dipers",
"price": 8.00
},
{
"name": "Dress",
"price": 13.00
}
]
},
{
"name": "Drug Store",
"items": [
{
"name": "Bandage",
"price": 5.00
},
{
"name": "stringe",
"price": 6.50
},
{
"name": " Pain Relief",
"price": 8.00
},
{
"name": "First Aid Kit",
"price": 14.99
},
{
"name": "Cold Relief",
"price": 6.50
}]
},
{
"name": "Health and Personal Care",
"items": []
},
{
"name": "Household Supplies",
"items": [{
"name": "Air Freshener",
"price": 1.25
},
{
"name": "All Purpose Cleaner",
"price": 2.99
},
{
"name": "Disinfecting Wipes",
"price": 8.99
}
]
}
]
},
{
"category": "Pantry Items",
"subcategories": [
{
"name": "Beverages",
"items": [
{
"name": "Apple Juice",
"price": 5.99
},
{
"name": "Banana-Orange Juice",
"price": 1.99
},
{
"name": "Cranberry Juice",
"price": 4.99
},
{
"name": "Strawberry Lemonade",
"price": 2.50
}
]
},
{
"name": "Canned Food",
"items": [
{
"name": "Pickels",
"description": "Assorted pickles",
"price": 1.99
},
{
"name": "Tomatoe Sauce",
"price": 1.59
}
]
}
]
},
{
"category": "Perishables",
"subcategories": [
{
"name": "Bread and Bakery",
"items": [
{
"name": "Baguette",
"price": 3.00
},
{
"name": "Pie",
"price": 5.00
},
{
"name": "Brownies",
"price": 2.50
}
]
},
{
"name": "Cheese",
"items": [
{
"name": "Feta Cheese",
"price": 7.54
},
{
"name": "Emental Cheese",
"price": 8.74
},
{
"name": "Swiss Cheese",
"price": 5.89
}
]
}
]
}
]
Am working on this project that require fetching items from a JSON file according to categories, when a particular subcategory is clicked, it should display only items from that subcategory but my code is working for only one subcategory but I don't know how to make it dynamic to work for every subcategory
$('#subcategory1').click(function() {
$.getJSON("list.json",
function(data) {
console.log(data);
let output = '';
$.each(data[0].subcategories[0].items, function(index, product) {
output += `
<div class="col-md-3">
<div class="items">
<div class='photo'>
<img src="${product.imagelink}">
</div>
<div class="info">
<h4>${product.name}</h4>
<h5>$${product.price}</h5>
</div>
<div class="info">
<p>
Add to cart
</p>
</div>
</div>
</div>
`;
});
$('#images').html(output);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="category1">
<li>Baby Care</li>
<li>Drug Store</li>
<li>Health and Personal Care</li>
<li>Household Supplies</li>
</ul>
There might be better ways to do what you are looking for. But you can give a try to check below things.
Changed your html to below
<ul id="category1">
<li>Baby Care</li>
<li>Drug Store</li>
<li>Health and Personal Care</li>
<li>Household Supplies</li>
</ul>
<div id="subItems"></div>
Changed your js code a bit to below
var selectedSubCategoryObj = null
$('#subcategory1').click(function() {
$.getJSON("list.json",
function(data) {
console.log(data);
let output = '';
selectedSubCategoryObj= $(this)
$.each(data[0].subcategories, function(index, product) {
if($(selectedSubCategoryObj)[0].innerHTML == product.name){
$.each(product.items, function(index, eachItem) {
output += `
<div class="col-md-3">
<div class="items">
<div class='photo'>
<img src="${eachItem.imagelink}">
</div>
<div class="info">
<h4>${eachItem.name}</h4>
<h5>$${eachItem.price}</h5>
</div>
<div class="info">
<p>
Add to cart
</p>
</div>
</div>
</div>
`;
})
$('#subItems').html(output);
}
});
});
});
Once cross check if its similar to what you are looking for.

Angularjs search filter based on dropdown range

I have an angular dropdown problem. I want to show projects with ng-repeat with dropdown selected value and split them into range. can anybody help
me please?
jsfiddle : http://jsfiddle.net/faridulhassan/cWVrV/1010/
Here are my codes:
JS
var app = angular.module('myapp', []);
app.controller('searchCtrl', ['$scope', '$http', function($scope, $http) {
$scope.results = [{
"id": 1,
"name": "Allergy Relief",
"address": "87 Waxwing Court",
"link": "https://purevolume.com/viverra/eget/congue/eget/semper/rutrum/nulla.jpg",
"image": "https://dummyimage.com/143x130.bmp/ff4444/ffffff",
"size": 500,
"type": "all"
}, {
"id": 2,
"name": "Mirtazapine",
"address": "368 Rowland Terrace",
"link": "https://wordpress.com/vestibulum/proin/eu/mi/nulla/ac.png",
"image": "https://dummyimage.com/214x184.jpg/ff4444/ffffff",
"size": 900,
"type": "all"
}, {
"id": 3,
"name": "Doxepin Hydrochloride",
"address": "86065 Washington Trail",
"link": "https://reference.com/orci/vehicula/condimentum/curabitur/in/libero/ut.aspx",
"image": "https://dummyimage.com/146x224.png/cc0000/ffffff",
"size": 1000,
"type": "all"
}, {
"id": 4,
"name": "Lactulose",
"address": "478 Lillian Point",
"link": "https://china.com.cn/montes/nascetur/ridiculus/mus/etiam.jsp",
"image": "https://dummyimage.com/218x170.bmp/cc0000/ffffff",
"size": 1800,
"type": "commercial"
}, {
"id": 5,
"name": "Clindamycin Phosphate",
"address": "995 Rowland Junction",
"link": "https://facebook.com/auctor/gravida.json",
"image": "https://dummyimage.com/113x123.png/5fa2dd/ffffff",
"size": 2000,
"type": "residential"
}, {
"id": 6,
"name": "Neutrogena Men Triple Protect Face",
"address": "4128 Columbus Circle",
"link": "https://ibm.com/proin/eu/mi.html",
"image": "https://dummyimage.com/235x184.png/cc0000/ffffff",
"size": 2446,
"type": "all"
}, {
"id": 7,
"name": "Ibuprofen",
"address": "3357 Garrison Circle",
"link": "https://scientificamerican.com/quam.js",
"image": "https://dummyimage.com/149x232.jpg/5fa2dd/ffffff",
"size": 2800,
"type": "residential"
}, {
"id": 8,
"name": "VANACOF",
"address": "01888 Messerschmidt Center",
"link": "https://taobao.com/in/magna.jpg",
"image": "https://dummyimage.com/147x245.jpg/cc0000/ffffff",
"size": 4572,
"type": "commercial"
}, {
"id": 9,
"name": "Oxazepam",
"address": "2 Harper Crossing",
"link": "https://sakura.ne.jp/lectus.json",
"image": "https://dummyimage.com/183x248.jpg/cc0000/ffffff",
"size": 2900,
"type": "residential"
}, {
"id": 10,
"name": "Blistex",
"address": "94401 Melody Lane",
"link": "https://istockphoto.com/non/sodales.html",
"image": "https://dummyimage.com/204x196.jpg/5fa2dd/ffffff",
"size": 2350,
"type": "residential"
}, {
"id": 11,
"name": "Axe",
"address": "3851 Melody Center",
"link": "https://storify.com/nulla.jsp",
"image": "https://dummyimage.com/159x126.bmp/ff4444/ffffff",
"size": 9258,
"type": "commercial"
}, {
"id": 12,
"name": "ESIKA Perfect Match",
"address": "3 American Avenue",
"link": "https://google.de/quam.png",
"image": "https://dummyimage.com/155x229.png/ff4444/ffffff",
"size": 7219,
"type": "all"
}, {
"id": 13,
"name": "PCA SKIN Body Hydrator",
"address": "34 East Road",
"link": "https://marketwatch.com/vulputate.aspx",
"image": "https://dummyimage.com/174x146.jpg/cc0000/ffffff",
"size": 1623,
"type": "commercial"
}, {
"id": 14,
"name": "CLARINS Daily Energizer SPF 15",
"address": "07369 Northview Lane",
"link": "https://pagesperso-orange.fr/augue/luctus/tincidunt/nulla/mollis/molestie.jpg",
"image": "https://dummyimage.com/181x207.png/dddddd/000000",
"size": 2350,
"type": "all"
}, {
"id": 15,
"name": "OXYGEN",
"address": "60 Drewry Pass",
"link": "https://sourceforge.net/vestibulum.png",
"image": "https://dummyimage.com/243x176.jpg/cc0000/ffffff",
"size": 7678,
"type": "all"
}, {
"id": 16,
"name": "Dove",
"address": "68 Anthes Center",
"link": "https://unc.edu/at.html",
"image": "https://dummyimage.com/218x231.bmp/cc0000/ffffff",
"size": 9999,
"type": "residential"
}, {
"id": 17,
"name": "Joints and Muscles Pain Relieving",
"address": "25 Coleman Lane",
"link": "https://360.cn/aenean/auctor/gravida.json",
"image": "https://dummyimage.com/127x118.bmp/dddddd/000000",
"size": 9501,
"type": "all"
}, {
"id": 18,
"name": "Healthy Accents Famotidine",
"address": "4 Melrose Junction",
"link": "https://nytimes.com/ultrices/posuere/cubilia/curae/mauris.png",
"image": "https://dummyimage.com/250x183.bmp/cc0000/ffffff",
"size": 8776,
"type": "residential"
}, {
"id": 19,
"name": "sunmark nite time",
"address": "03 Mallard Way",
"link": "https://thetimes.co.uk/vel/pede/morbi/porttitor/lorem/id.xml",
"image": "https://dummyimage.com/185x241.bmp/dddddd/000000",
"size": 1274,
"type": "all"
}, {
"id": 20,
"name": "Bupivacaine Hydrochloride",
"address": "964 Elka Place",
"link": "https://cmu.edu/auctor/gravida/sem/praesent/id.aspx",
"image": "https://dummyimage.com/203x208.bmp/dddddd/000000",
"size": 5609,
"type": "residential"
}];
}]);
HTML
<div class="container-fluid" ng-app="myapp" ng-controller="searchCtrl">
<div class="row">
<div class="col-xs-6">
<div class="well">
<form class="form-primary text-white">
<div class="form-group">
<div>
<label for="search.size">By Size (Sft)</label>
<select name="search.size" id="search.size" ng-model="search.size">
<option value="">All Size</option>
<option value="600-1000">BELOW 1000</option>
<option value="1001-1500">1000 - 1500</option>
<option value="1501-2000">1500 - 2000</option>
<option value="2001-2500">2000 - 2500</option>
<option value="2601-3000">2500 - 3000</option>
<option value="3001-15000">ABOVE 3000</option>
</select>
</div>
</div>
</form>
</div>
</div>
<div class="col-xs-6">
<div class="well">
<ul class="search-result-list">
<li ng-repeat="result in filteredResuls = (results | filter:search ) | orderBy:name">
<a ng-href="{{result.link}}" target="_blank" class="">
<div class="search-thumb" style="background-image: url({{result.image}});">
</div>
<div class="search-meta">
<h3 class="search-item-title">{{result.name}}</h3>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
CSS
ul {
list-style: none;
padding: 0;
margin: 0;
}
a {
text-decoration: none;
display: flex;
align-items: flex-start;
width: 100%;
margin-bottom: 5px;
}
h3 {
font-size: 12px;
margin-top: 0;
}
.search-thumb {
width: 50px;
height: 50px;
background-repeat: no-repeat;
-webkit-background-size: cover;
background-size: cover;
}
.search-meta {
padding-left: 5px;
}
You can write a custom filter function which can filter out items based on range. Something like this:
$scope.searchSize = function(obj) {
if($scope.size && obj.size) {
var range = $scope.size.split("-");
if(obj.size >= Number(range[0]) && obj.size <= Number(range[1])) {
return true;
}
return false;
}
return true;
}
Here's the working fiddle
create a custom filter like this
$scope.searchPro = function(name){
return function(item){
debugger
if(name && name != ""){
var arr = name.split("-");
if(parseInt(arr[0]) <= item.size && parseInt(arr[1]) >= item.size){
return item;
}
}else{
return item
}
}
}
call the custom filter from the ng repeat like this
ng-repeat="result in filteredResuls = (results | filter:searchPro(search.size) ) | orderBy:name"
Demo

Javascript multiple drop down box

Is there a way to get a multiple drop down field from a list of arrays without having to hardcode the information into the HTML? So that by selecting each category the relevant subcategory will drop down.
The list looks something like this:
var listData = [
{
"title": "Meeting Room",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Book a Car",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Stationery",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Hospitality",
"category": "Forms",
"url": "https://www.google.co.uk/"
},
{
"title": "Communications",
"category": "News",
"url": "https://blogs.office.com/"
},
{
"title": "Industries",
"category": "News",
"url": "https://blogs.office.com/"
},
{
"title": "Policy",
"category": "News",
"url": "https://blogs.office.com/"
},
{
"title": "Get started",
"category": "Information",
"url": "https://support.office.com/"
},
{
"title": "What do you need",
"category": "Useful Information",
"url": "https://support.office.com/"
},
{
"title": "Accessibility features",
"category": "Useful Information",
"url": "https://support.office.com/"
},
{
"title": "Videos",
"category": "Useful Information",
"url": "https://support.office.com/"
}
]
The following code does the work. It's vanilla JS.
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Form</title>
</head>
<body>
<select id="categories" onchange="changeCategory(event)"> </select>
<select id="title"> </select>
<select id="url"> </select>
<script>
var listData = [{
"title": "Meeting Room"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Book a Car"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Stationery"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Hospitality"
, "category": "Forms"
, "url": "https://www.google.co.uk/"
}, {
"title": "Communications"
, "category": "News"
, "url": "https://blogs.office.com/"
}, {
"title": "Industries"
, "category": "News"
, "url": "https://blogs.office.com/"
}, {
"title": "Policy"
, "category": "News"
, "url": "https://blogs.office.com/"
}, {
"title": "Get started"
, "category": "Information"
, "url": "https://support.office.com/"
}, {
"title": "What do you need"
, "category": "Useful Information"
, "url": "https://support.office.com/"
}, {
"title": "Accessibility features"
, "category": "Useful Information"
, "url": "https://support.office.com/"
}, {
"title": "Videos"
, "category": "Useful Information"
, "url": "https://support.office.com/"
}];
function removeOptions(selectbox) {
var i;
for (i = selectbox.options.length - 1; i >= 0; i--) {
selectbox.remove(i);
}
}
function changeCategory(event) {
removeOptions(document.getElementById('title'))
removeOptions(document.getElementById('url'))
mySelect1 = document.getElementById('title')
mySelect2 = document.getElementById('url');
listData.forEach(function (item, index) {
if (item.category == event.target.value) {
mySelect1.options[mySelect1.options.length] = new Option(item.title, item.title);
mySelect2.options[mySelect2.options.length] = new Option(item.url, item.url);
}
});
}
Array.prototype.contains = function (obj) {
var i = this.length;
while (i--) {
if (this[i] == obj) {
return true;
}
}
return false;
}
var mySelect = document.getElementById('categories');
var categories = new Array;
listData.forEach(function (item, index) {
if (!categories.contains(item.category)) {
mySelect.options[mySelect.options.length] = new Option(item.category, item.category);
categories.push(item.category);
}
});
</script>
</body>
</html>

Applying filter on parent if it has been applied on children AngularJS

I have a list with items and have applied filter on those items by value from text box. I want to get new filtered list with parent and its children if parent has at least one filtered item.If doesn't, that parent should not be displayed.
For an example: If I enter "3D" in the text box I don't want to get "Day parts" and "Week parts" listed below as they don't have children anymore after filtering.
<div ng-controller="Ctrl">
<input type="text" data-ng-model="inputValue.name"/>
<ul data-ng-repeat="condition in conditions">
<div data-ng-click="setHeadingStatus(condition)">
<div>
{{condition.name}}
</div>
<li ng-repeat="item in condition.items | filter:inputValue">
<div class="custom-typeahead-list-title">{{item.name}}</div>
<div class="custom-typeahead-list-desc">{{item.description}}</div>
</li>
</div>
</ul>
function Ctrl($scope , $filter){
$scope.countryCode = 1;
$scope.conditions = [
{
"id": 1,
"name": "Experiences",
"expanded": false,
"items": [
{
"id": 1,
"name": "3D"
},
{
"id": 2,
"name": "Imax"
},
{
"id": 3,
"name": "D-Box"
},
{
"id": 4,
"name": "THX"
}
]
},
{
"id": 2,
"name": "Day parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Early Bird"
},
{
"id": 2,
"name": "Matinee"
},
{
"id": 3,
"name": "Last Night"
}
]
},
{
"id": 3,
"name": "Week parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Monday"
},
{
"id": 2,
"name": "Wednesday"
},
{
"id": 3,
"name": "Weekend"
}
]
}
]
}
Here is the example of it
http://jsfiddle.net/KJ3Nx/48/
You can put an ng-show on the div that displays each block, and set the expression to the filtered length;
<div data-ng-show="(condition.items | filter:inputValue).length > 0" data-ng-click="setHeadingStatus(condition)">
Updated fiddle

Converting Multidimensional JSON key-value pairs into an Angular Menu (no Angular knowledge required)

I asked this question here:
Working With Dynamic Multidimensional key-value pairs in JSON
But it's become a bit more involved and I can't get where I'm going from that answer. If I have a data object that looks like this:
{
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
How can I convert that into an Angular menu? The menu would need to list all of the services, and then if the service has an associated item in "fields" that item should be listed underneath it. So for instance "svc1" and its description should be listed on a line (got that working) but then "Product1" and "Product2" with their descriptions should appear on the next two lines because you can see that "svc1" is listed in the "services" field for "Products." Similarly, "svc4" should appear on a line, and then "Wines" and its description on the next line because "svc4" appears in the "services" field of "Wines."
I think the best way is to unpack and re-pack this JSON object in sequential order in the Angular controller and then push this data out to the Angular view but there might be a solution using only the logic available from the view. I've tried a bunch of nested fors and ifs along these lines (very much not working):
var i, j;
var listArray = [];
for (i = 0; i < $scope.svcs.length; i++) {
var littleArray = [$scope.svcs[i].status, $scope.svcs[i].name, $scope.svcs.desc];
listArray.push[littleArray1];
for (j=0; j < $scope.jFA.length; j++) {
if ($scope.jFA[j] == $scope.svcs[i].name) {
if ($scope.jFA[j] == $scope.svcs[i].fields)
littleArray = [$scope.jFA[j].fields] //...etc
}
}
...but that logic just keeps getting more and more dense and isn't working no matter now I try to use it. I liked the simplicity in the answer to the other question but have not had success in replicating it.
So if someone can help me figure out how to get the data into the right sequence using JS I can handle the Angular part. Or if you're an Angular whiz and have an answer along those lines, even better.
So it was a little hard understanding your question, but I gave it my best shot. Does this fiddle show what you are trying to achieve? http://jsfiddle.net/arknr6qz/1/
JS:
var app = angular.module('TestApp',[]);
app.controller('TestController', function($scope)
{
$scope.checkService = function(service, fieldServices)
{
if (fieldServices.indexOf(service) != -1) return true;
return false;
};
$scope.data = {
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
});
HTML:
<div ng-app="TestApp">
<div ng-controller="TestController">
<div ng-repeat="service in data.custom.services">
{{ service.name }}
<div class="indent" ng-repeat="fields in data.custom.fields">
<span ng-if="checkService(service.name, fields.services)">
{{fields.services.values}}
<span ng-repeat="value in fields.values">
{{value.name}} - {{value.desc}}<br>
</span>
</span>
</div>
</div>
</div>
</div>
and finally css:
.indent {
margin-left:10px;
}

Categories

Resources