iterating a multidimensional Json with AngularJS(Ng-Repeat) - javascript

I have problem to show all elements of subcategory with Ng-Repeat. Actually i can show all events from selected category with this code, but i don't know how to show all activities from specific event.
i have this code....
HTML
<div class = "categorias_eventos">
<ul>
<li value = "0" class = "active">
<img src="images1" ng-click="categorySelected = {categoryName: '1'}">
</li>
<li value = "1" class = "active">
<img src="images2" ng-click="categorySelected = {categoryName: '2'}">
</li>
<li value = "2">
<img src="images3" ng-click="categorySelected = {categoryName: '3'}">
</li>
<li value = "3" >
<img src="images4" ng-click="categorySelected = {categoryName: '4'}">
</li>
<li value = "4">
<img src="images5" ng-click="categorySelected = {categoryName: '5'}">
</li>
</ul>
</div>
<div ng-controller="Test">
<div ng-repeat="evento in eventos | filter:categorySelected" ng-click = "eventSelected = {id: '{{evento.id}}'}">
<div class="infoEvento">
<div class="name_event">
{{evento.eventName}}
</div>
</div>
</div>
</div>
<!-- Activitys -->
<div ng-controller="Test">
<div ng-repeat="activity in evento.activitys | filter:eventSelected">
<div class="infoEvento">
<div class="name_event">
{{activitys.description}}
</div>
</div>
</div>
</div>
JAVASCRIPT
function Test($scope) {
$scope.eventos = [
{
"id":"1",
"dateStart":"01-12-2014",
"dateEnd":"12-12-2014",
"eventName":"partyDeluxe",
"categoryName":"Category 1",
"activitys":
[
{
"pic_id":"1500",
"description":"Picture of a computer",
"localion":"img.cloudimages.us/2012/06/02/computer.jpg",
"type":"jpg"
},
{
"pic_id":"100",
"description":"Picture of a computer",
"localion":"img.cloudimages.us/2012/06/02/computer.jpg",
"type":"jpg"
},
{
"pic_id":"15",
"description":"Picture of a computer",
"localion":"img.cloudimages.us/2012/06/02/computer.jpg",
"type":"jpg"
}
]
},
];;
}

The problem you have is that your inner ng-repeat is sitting outside your outer, which means the activity context is unknown. To fix this, you simply need to rethink your div layout to include one ng-repeat inside the other. For example:
<div ng-controller="Test">
<div ng-repeat="evento in eventos | filter:categorySelected">
<div ng-click = "eventSelected = {id: '{{evento.id}}'}">
<div class="infoEvento">
<div class="name_event">
{{evento.eventName}}
</div>
</div>
</div>
<!-- Activitys -->
<div ng-controller="Test">
<div ng-repeat="activity in evento.activitys | filter:eventSelected">
<div class="infoEvento">
<div class="name_event">
{{activitys.description}}
</div>
</div>
</div>
</div>
</div>
</div>

Related

How can I call value on another object array

json
[
{
"PROFILEUSERS_ID": "PTOKE000007",
"ALAMATUMKM": "Komp.Srijaya Abadi",
"dataTrouble": [
{
"NO": 1,
"IDMASALAH": "PTOmsl000001",
"IDNARASUMBER": "Marfua000100",
"IDUMKM": "PTOKE000007",
"NAMANARASUMBER": "Marfuah, S.SI, M.Kom",
"NAMAUMKMPMT": "PT OKE",
"GAMBARNARASUMBER": "4dwuwHmmHeCGuEv2LQqOmhXxvnoRTZTi08hqYz2C.jpeg",
"KETERANGANPMT": "kami ingin seminar/workshop pembahasan untuk AI di bidang pengelolaan ekonomi untuk mengetahui lebih lanjut peran AI,\r\nDan Belajar UI/UX\r\n\r\nTerima Kasih",
"TLPUMKM": "077845877",
"STATUSPMT": "WAIT",
"created_at": "2019-12-07 14:55:04",
"updated_at": "2019-12-07 14:59:22",
"listSkills": [
{
"NO": 1,
"IDMASALAHJP": "PTOmsl000001",
"JKMASALAH": "Artificial Intelligence",
"created_at": "2019-12-07 14:55:04",
"updated_at": null
},
{
"NO": 2,
"IDMASALAHJP": "PTOmsl000001",
"JKMASALAH": "UI/UX",
"created_at": "2019-12-07 14:55:04",
"updated_at": null
}
]
}
]
}
]
I already tried like this:
let content = ``;
data.forEach(item => {
item.dataTrouble.forEach(child => {
console.log(child);
let customDate = child.created_at;
let subsString = customDate.substring(0, 10);
let newDate = subsString.split("-").reverse().join("-");
content += `
<div class="panel panel-default panel-post">
<div class="panel-heading">
<div class="media">
<div class="media-left">
<a href="#">
<img src="http://localhost/Project_Web/laravel/project/Development/ppu-web/public/assetLogin/img/profile/${child.GAMBARNARASUMBER}" alt="Siostium Activity Image" />
</a>
</div>
<div class="media-body">
<h4 class="media-heading">
${child.NAMANARASUMBER}
</h4>
Tanggal Registrasi Acara: ${newDate}
</div>
</div>
</div>
<div class="panel-body">
<div class="post">
<div class="post-heading">
<p style="text-align: justify;">${child.KETERANGANPMT}</p>
</div>
<div class="post-content">
</div>
</div>
</div>
<div class="panel-footer">
<ul>
<li>
<a href="#">
<p>Permasalahan:</p>
<small><span class="label bg-red">${child.listSkills.JKMASALAH}</span></small>
</a>
</li>
<li></li>
<li></li>
</ul>
<div class="form-group">
<div class="form-line">
</div>
</div>
</div>
</div>
`
});
document.getElementById('activity').innerHTML = content;
});
But on the <small><span class="label bg-red">${child.listSkills.JKMASALAH}</span></small>,
the data is undefined.
I already tried to add looping after the child but the result of data are 3 not 2 data.
listSkills is an array you can access it through its index.
like: child.listSkills[index].JKMASALA.
you can map and show values like:
child.listSkills.map(obj => (
<small>
<span class="label bg-red">
{obj.JKMASALAH}
</span>
</small>
))

Clone LI div so it is placed after the original LI instead of end

I want to be able to click on an item and clone it immediately after that item, At moment it always Clones to the END, id adds it after the last LI in list.
I created a jsFiddle here jsfiddle test
JS
const curId = 20;
function cloneIt(){
var newId = Math.floor((Math.random() * 1000) + 1);
const newCloned = $('#d'+curId).clone(true).prop('id', "d"+newId );
newCloned.html(newCloned.html().replace(
new RegExp(curId, 'g'),
newId
));
$("#ulContainer").append(newCloned);
}
$('#ulContainer').on('click', '.tog', function(e) {
cloneIt();
alert('item cloned');
e.preventDefault();
});
HTML
<ul id='ulContainer'>
<li id="d20" class="cards__item">
<div class="card">
<div class="card__content cellb">
<a id="dup20" class="tog" href="http://test/pgdup/20">
<div class="dup20">clone me</div>
</a>
</div>
<div class="card__content nick">
<p class="card__text nick">Test Tres (20)</p>
</div>
</div>
</li>
<li id="d21" class="cards__item">
<div class="card">
<div class="card__content anchor">
<a id="dup21" class="tog" href="http://test/pgdup/21">
<div class="dup21">clone me</div>
</a>
</div>
<div class="card__content nick">
<p class="card__text nick">Test Tres (21)</p>
</div>
</div>
</li>
</ul>
You can try using .after() by passing the event to the function:
Insert content, specified by the parameter, after each element in the set of matched elements.
Change
$("#ulContainer").append(newCloned);
To
$(e.target.closest('li')).after(newCloned);
const curId = 20;
function cloneIt(e){
var newId = Math.floor((Math.random() * 1000) + 1);
const newCloned = $('#d'+curId).clone(true).prop('id', "d"+newId );
newCloned.html(newCloned.html().replace(
new RegExp(curId, 'g'),newId));
$(e.target.closest('li')).after(newCloned);
}
$('#ulContainer').on('click', '.tog', function(e) {
cloneIt(e);
alert('item cloned');
e.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id='ulContainer'>
<li id="d20" class="cards__item">
<div class="card">
<div class="card__content cellb">
<a id="dup20" class="tog" href="http://test/pgdup/20">
<div class="dup20">clone me</div>
</a>
</div>
<div class="card__content nick">
<p class="card__text nick">Test Tres (20)</p>
</div>
</div>
</li>
<li id="d21" class="cards__item">
<div class="card">
<div class="card__content anchor">
<a id="dup21" class="tog" href="http://test/pgdup/21">
<div class="dup21">clone me</div>
</a>
</div>
<div class="card__content nick">
<p class="card__text nick">Test Tres (21)</p>
</div>
</div>
</li>
</ul>

How do i change multiple elements which should have the same value with javascript?

I am trying to replace the {title} within the following div
<a href="{pagelink}" title="{title}" class="link">
<img data-imgurl="{imgsrc}" class="img-responsive div-details-logo-image" alt="{title}" src="{imgsrc}">
<div class="div-details-image">
<h2 class="div-details-title">{title}</h2>
<div class="label-container">
<span class="label-type" data-type="{type}">{type}</span>
</div>
<span class="div-details-address">{Address}</span>
<span class="openhours"> {opentimes}</span>
</div>
</a>
For this i have come up with the follow js function, which works if i only target one class instance
function updateDivDetails(attributes) {
var x = document.getElementById("itemDetails");
x.querySelector(".div-details-address").innerHTML = attributes.address;
x.querySelector(".div-details-title").innerHTML = attributes.title;
etc
}
The use of class selector to change the {title} seems not the way to do it.
Any tips how to change {title} from the js function??
You can use .replace instead
Get the parent element and change all occurrences
const o = {
title: "Title",
text: "Lorem ipsum"
}
let container = document.getElementById('container');
let t = container.innerHTML;
container.innerHTML = t
.replace(/{title}/g, o.title)
.replace(/{text}/g, o.text);
<div id="container">
<h3>{title}</h3>
<p>{title}: {text}</p>
</div>
Update
You can save the original html into an variable, like that you can change the content multiple times with different object data.
const foo = {
title: "Title",
text: "Lorem ipsum"
}
const bar = {
title: "Title 2",
text: "Ipsum lorem"
}
let container = document.getElementById('container');
let template = container.innerHTML;
function changeText(obj) {
container.innerHTML = template
.replace(/{title}/g, obj.title)
.replace(/{text}/g, obj.text);
}
<div id="container">
<h3>{title}</h3>
<p>{title}: {text}</p>
</div>
<button onclick="changeText(foo)">First</button>
<button onclick="changeText(bar)">Second</button>
Your code works, so what is the issue?
You do know that you can only have one element per page with any given id value?
function updateDivDetails(attributes) {
var x = document.getElementById("itemDetails");
x.querySelector(".div-details-address").innerHTML = attributes.address;
x.querySelector(".div-details-title").innerHTML = attributes.title;
}
const y = {
address: 'address inserted',
title: 'title inserted'
};
updateDivDetails(y);
<div id="itemDetails">
<a href="{pagelink}" title="{title}" class="link">
<img data-imgurl="{imgsrc}" class="img-responsive div-details-logo-image" alt="{title}" src="{imgsrc}">
<div class="div-details-image">
<h2 class="div-details-title">{title}</h2>
<div class="label-container">
<span class="label-type" data-type="{type}">{type}</span>
</div>
<span class="div-details-address">{Address}</span>
<span class="openhours"> {opentimes}</span>
</div>
</a>
</div>
Instead of manually updating individual element, you can use a generic logic and update it.
You can create a list of possible elements selectors and update it based on common format.
function updateDivDetails(attributes) {
var x = document.getElementById("itemDetails");
const selector = ".div-details-address, .div-details-title";
Array.from(x.querySelectorAll(selector)).forEach((el) => {
const key = el.innerText.replace(/[{}]/g, '').trim().toLowerCase();
el.innerText = attributes[key]
})
}
const dummyData = {
title: 'Dummy Title',
address: 'Dummy Address'
}
updateDivDetails(dummyData)
<a href="{pagelink}" title="{title}" class="link" id="itemDetails">
<img data-imgurl="{imgsrc}" class="img-responsive div-details-logo-image" alt="{title}" src="{imgsrc}">
<div class="div-details-image">
<h2 class="div-details-title">{title}</h2>
<div class="label-container">
<span class="label-type" data-type="{type}">{type}</span>
</div>
<span class="div-details-address">{Address}</span>
<span class="openhours"> {opentimes}</span>
</div>
</a>
Above solution might work but its not scalable. If you have option to update markup, you should use data- attribute and based on than fetch new value and set it.
For demonstration purpose, I have added data-attr="KeyName" and fetched based on that
function updateDivDetails(attributes) {
Array.from(document.querySelectorAll("#itemDetails [data-attr]")).forEach((el) => {
el.innerText = attributes[ el.getAttribute('data-attr') ];
})
}
const dummyData = {
title: 'Dummy Title',
address: 'Dummy Address'
}
updateDivDetails(dummyData)
<a href="{pagelink}" title="{title}" class="link" id="itemDetails">
<img data-imgurl="{imgsrc}" class="img-responsive div-details-logo-image" alt="{title}" src="{imgsrc}">
<div class="div-details-image">
<h2 class="div-details-title" data-attr="title">{title}</h2>
<div class="label-container">
<span class="label-type" data-type="{type}">{type}</span>
</div>
<span class="div-details-address" data-attr="address">{Address}</span>
<span class="openhours"> {opentimes}</span>
</div>
</a>
Also, note that replacing innerHtml can have side effect. Better to set innerText instead
I think the problem that you have is that you do not select the element the right way.
Here are few lines to do it:
let h2Element = document.querySelector('.div-details-title');
h2Element.textContent = "New Title";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="{pagelink}" title="{title}" class="link">
<img data-imgurl="{imgsrc}" class="img-responsive div-details-logo-image" alt="{title}" src="{imgsrc}">
<div class="div-details-image">
<h2 class="div-details-title">{title}</h2>
<div class="label-container">
<span class="label-type" data-type="{type}">{type}</span>
</div>
<span class="div-details-address">{Address}</span>
<span class="openhours"> {opentimes}</span>
</div>
</a>
</body>
</html>

Filter ng-repeat in Angular

I searched a lot in google and I found nothing for my problem. My problem is how can I filter my menu option value? I have placed my entire code in below location.
http://plnkr.co/edit/q5WLaIvTN434o4nZNBdR
I have a CSS menu, which have href link but it is located at different div. So how can I filter my result according to menu selection? Please help me for this.
Also My search box is hiding below the menu. I tried to give z-index to it. But it isn't working. How can resolve this?
My Menu div is as follows:
<div id="menu-button">Menu</div>
<ul style="display:block;">
<li>Home</li>
<li id="deptMenu">
<a href='#'>Department</a>
<ul style="display: block;">
<li ng-repeat="dept in empDetails | unique:'department'">
{{dept.department}}
</li>
</ul>
</li>
</ul>
</div>
But container is on different location as below:
<div class="container">
<div id="userlist" class="row">
<p data-ng-show="(empDetails | filter:searchTxt).length==0"><font color="red">There are no results for this search</font></p>
<div id="userDiv{{$index}}" class="shadow col-sm-1" ng-repeat="info in empDetails | filter:menuFilter | orderBy:'Name' | filter:searchTxt" tweenmax-animating-directive ng-click="openDetail()">
<div class="employeeDetail">
<div style="line-height:25px">
<b>{{info.Name}}</b><br/>
<b>number :</b>{{info.number}}<br/>
<b>Post :</b>{{info.post}}<br/>
</div>
</div>
</div>
</div>
</div>
I placed "menuFilter" but that is not working.
Just save the value of the selected department and use that in the filter. So, your links would change to:
{{dept.department}}
The $scope gets a new field, filter, and method:
$scope.selectedDepartment = null;
$scope.departmentFilter = function (info) {
return !$scope.selectedDepartment || info.department === $scope.selectedDepartment;
};
$scope.selectDepartment = function (dept) {
$scope.selectedDepartment = dept;
};
And the ng-repeat changes to:
ng-repeat="info in empDetails | filter: departmentFilter | orderBy:'Name' | filter:searchTxt"
A working version is here: http://plnkr.co/edit/4vbvlsejZivio2A4seWa?p=info.
You can also checkout this version: http://plnkr.co/edit/CKdAnwB6Muh1j3ohkgFq
In your menu:
{{dept.department}}
In your controller:
$scope.showDept = false;
$scope.dept = {};
$scope.setDept = function(d) {
$scope.dept = d;
$scope.showDept = true;
};
ANd in your main container:
<div class="container">
<div id="userlist" class="row">
<p data-ng-show="(empDetails | filter:searchTxt).length==0"><font color="red">There are no results for this search</font></p>
<div id="userDiv{{$index}}" ng-show="showDept" class="shadow col-sm-1" tweenmax-animating-directive ng-click="openDetail()">
<div class="employeeDetail">
<div style="line-height:25px">
<b>{{dept.Name}}</b><br/>
<b>number :</b>{{dept.number}}<br/>
<b>Post :</b>{{dept.post}}<br/>
</div>
</div>
</div>
</div>
</div>

Sorting of divs in Jquery

My code have divs of movies which are used to display movie with poster, now i want jquery to sort divs for me on basis of title,
<!-- Movie -->
<div class="movie" title="Reservoir Dogs">
<div class="movie-image">
<span class="play"><span class="name">Reservoir Dogs |
Reservoir Dogs</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMTQxMTAwMDQ3Nl5BMl5BanBnXkFtZTcwODMwNTgzMQ##._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Saw">
<div class="movie-image">
<span class="play"><span class="name">Saw |
Saw</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMjAyNTcxNzYwMV5BMl5BanBnXkFtZTgwMzQzNzM5MjE#._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Scarface">
<div class="movie-image">
<span class="play"><span class="name">Scarface |
Scarface</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMjAzOTM4MzEwNl5BMl5BanBnXkFtZTgwMzU1OTc1MDE#._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Signs">
<div class="movie-image">
<span class="play"><span class="name">Signs |
Signs</span></span><img src="http://ia.media-imdb.com/images/M/MV5BNDUwMDUyMDAyNF5BMl5BanBnXkFtZTYwMDQ3NzM3._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in3">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Stir of Echoes">
<div class="movie-image">
<span class="play"><span class="name">Stir of Echoes |
Stir of Echoes</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMTU0OTAyMDQzNV5BMl5BanBnXkFtZTcwNTg1NjYyMQ##._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
Now here is my current code
$(document).ready(function () {
var desc = false;
document.getElementById("sort").onclick = function () {
sortUnorderedList("movie", desc);
desc = !desc;
return false;
}
});
function sortUnorderedList(ul, sortDescending) {
if (typeof ul == "string")
var lis = document.getElementsByClassName("movie");
var vals = [];
for (var i = 0, l = lis.length; i < l; i++)
vals.push(lis[i]);
debugger;
vals.sort(function (a, b) { return a.title - b.title });
//vals[].title.sort();
if (sortDescending)
vals.reverse();
for (var i = 0, l = lis.length; i < l; i++)
lis[i].innerHTML = vals[i].innerHTML;
}
above code is not giving desired result
can u suggest better way to do it
You can significantly simplify your code if you use more jQuery, anyway you are using it. Entire code in this case will be:
$(document).ready(function () {
var desc = false;
$("#sort").click(function () {
sortUnorderedList("movie", desc);
desc = !desc;
});
});
function sortUnorderedList(ul, sortDescending) {
$('.' + ul).sort(function(a, b) {
return sortDescending ? a.title.localeCompare(b.title) : b.title.localeCompare(a.title);
}).appendTo('body');
}
Just note that instead of appendTo('body'), you should append to appropriate container that holds .movie elements. I'm appending to body because this is a container for movie divs in my demo.
Demo: http://jsfiddle.net/212oc0kw/

Categories

Resources