How can I call value on another object array - javascript

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>
))

Related

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>

jquery each selector and ajax not producing the right results

I am trying to simplify my code but running into issues where it is not working when it place in an each loop.
Here is what I am trying to do:
- html has n parent DIV that generates a report via an AJAX call to pull data
- each div respective to report utilizes a data attribute to define which report to pull
- based no the results of the report, it should populate the html with the respective results.
HTML Code (to simplify, using n = 2):
<div class="widget-box widget-hits card no-border bg-white no-margin" data-widget-report="widget-hits">
<div class="container-xs-height full-height">
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="card-header top-left top-right">
<div class="card-title text-black hint-text">
<span class="font-montserrat fs-11 all-caps">Weekly Hits
<i class="far fa-chevron-right p-l-5"></i>
</span>
</div>
<div class="card-controls">
<ul>
<li>
<a data-toggle="refresh" class="card-refresh text-black" href="#">
<i class="far fa-circle fa-xs"></i>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="row-xs-height ">
<div class="col-xs-height col-top relative">
<div class="row">
<div class="col-sm-6">
<div class="p-l-20 widget-total">
<h3 class="no-margin p-b-5"></h3>
<p class="small hint-text m-t-5">
<span class="label m-r-5">%</span>
</p>
</div>
</div>
<div class="col-sm-6">
</div>
</div>
<div class="widget-chart"></div>
</div>
</div>
</div>
</div>
<div class="widget-box widget-sales card no-border bg-white no-margin" data-widget-report="widget-sales">
<div class="container-xs-height full-height">
<div class="row-xs-height">
<div class="col-xs-height col-top">
<div class="card-header top-left top-right">
<div class="card-title text-black hint-text">
<span class="font-montserrat fs-11 all-caps">Weekly Sales
<i class="far fa-chevron-right p-l-5"></i>
</span>
</div>
<div class="card-controls">
<ul>
<li>
<a data-toggle="refresh" class="card-refresh text-black" href="#">
<i class="far fa-circle fa-xs"></i>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="row-xs-height ">
<div class="col-xs-height col-top relative">
<div class="row">
<div class="col-sm-6">
<div class="p-l-20 widget-total">
<h3 class="no-margin p-b-5"></h3>
<p class="small hint-text m-t-5">
<span class="label m-r-5">%</span>
</p>
</div>
</div>
<div class="col-sm-6">
</div>
</div>
<div class="widget-chart"></div>
</div>
</div>
</div>
</div>
JS:
$('.widget-box').each(function() {
$widget_report = $(this).data('widget-report');
if ($widget_report !== undefined) {
$.ajax({
type: 'get',
url: '/admin/reports/' + $widget_report,
dataType: 'json',
success:
function(data) {
if (data.success) {
var labelsData = [];
var seriesData = [];
var trend = data.trend * 100;
widget_class = '.' + $widget_report + ' .widget-chart';
console.log(widget_class);
$(this).find('.widget-total h3').text(data.total);
$(this).find('.widget-total p span').text(trend + '%');
trend_span = $(this).find('.widget-total p').children('span');
if(data.trend > 0) {
$(this).find('.widget-total p span.label').addClass('label-success');
$(this).find('.widget-total p').text('Higher');
}
else {
$(this).find('.widget-total p span.label').addClass('label-important');
$(this).find('.widget-total p').text('Lower');
}
$(this).find('.widget-total p').prepend(trend_span);
$.each(data.values, function(key, value){
date = new Date(value.label + 'T00:00:00');
labelsData.push(date.getMonth() + 1 + '/' + date.getDate());
seriesData.push(value.value);
});
chartData = {
labels: labelsData,
series: [seriesData]
}
alert(widget_class);
new Chartist.Bar(widget_class, chartData, {
axisX: {
showGrid: false
},
axisY: {
showGrid: false,
showLabel: false
}
});
}
}
});
}
});
Here are the problems I've encountered:
$(this).find('.widget-total h3').text is not updating the respective DIV group
widget_class for some reason is always returning the last DIV group... even if the last DIV group was returning data.success = false. Ex: above would return widget-sales twice and not widget-hits and then widget-sales.
I am scratching my head on this one... I am able to get this to work without the .each loop and distinctively create one for each... but was hoping to make this universal and allow the control rely on the data-widget-report attribute on the html.
Is this the proper approach?
Any help / direction is appreciated...
Add var in front of widget_class and $widget_report so they are scoped to the function instead of global. I think that will fix your problem. Right now $widget_report gets replaced by the last widget even before the ajax calls are completed.
As for the $(this) not working, you have to assign it to a variable before you make the ajax call.
$('.widget-box').each(function() {
var widgetBoxElement = $(this);
var $widget_report = $(this).data('widget-report');
if ($widget_report !== undefined) {
$.ajax({
type: 'get',
url: '/admin/reports/' + $widget_report,
dataType: 'json',
success:
function(data) {
if (data.success) {
// use widgetBoxElement here instead of $(this)
}
}
});
}
});

convert HTML List to JSON

I have a little problem with my HTML template for convert to JSON. I wish convert a list of HTML messages to JSON. Thank you in advance for your response.
HTML Template
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Name</h4>
<span class="date">MM/DD/YYYY</span>
<span class="time">HH:MM</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Message here
</div>
</div>
</div>
<!-- Others .message -->
JSON Render
{
"list": [
{
"pseudo": "Name",
"date": "MM/DD/YYYY",
"time": "HH:MM",
"message": "Message here"
},
/* ... */
]
}
even if it doesn't look that cool I think this will be much faster:
var pseudo = document.getElementsByClassName("pseudo");
var date = document.getElementsByClassName("date");
var time = document.getElementsByClassName("time");
var message = document.getElementsByClassName("message-text");
var list = [];
for(var i=0, l=pseudo.length;i<l;i++) {
list.push({
pseudo: pseudo[i].textContent,
data: date[i].textContent,
time: time[i].textContent,
message: message[i].textContent
})
}
console.log(list);
.. depending on your file structure this may not be the best solution
You can use jQuery to simply extract your date from html:
var result = [];
$(".message").each(function() {
var obj = {
pseudo: $(this).find(".pseudo").text(),
date: $(this).find(".date").text(),
time: $(this).find(".time").text(),
message: $(this).find(".message-text").text(),
};
result.push(obj);
})
console.log(result)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Name</h4>
<span class="date">MM/DD/YYYY</span>
<span class="time">HH:MM</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Message here
</div>
</div>
</div>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">John</h4>
<span class="date">09/11/2011</span>
<span class="time">HH:MM</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
World Disaster
</div>
</div>
</div>
Simply get all your .message elements, and cycle through them to add their properties to the resulting Array (I used trim() to remove extra spaces at the beginning and the end of the message texts):
console.log( messagesToJSON() );
function messagesToJSON(){
var messages = [],
elements = $('.message');
for(var i=0; i<elements.length; i++){
messages.push({
"pseudo": elements.eq(i).find('.pseudo').text(),
"date": elements.eq(i).find('.date').text(),
"time": elements.eq(i).find('.time').text(),
"message": elements.eq(i).find('.message-text').text().trim()
});
}
return {list: messages};
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Kevin</h4>
<span class="date">08/01/2016</span>
<span class="time">14:52</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Hi there!
</div>
</div>
</div>
<div class="message">
<div class="message-data">
<div class="infos">
<h4 class="pseudo">Robert</h4>
<span class="date">08/01/2016</span>
<span class="time">15:03</span>
</div>
</div>
<div class="message-content">
<div class="message-text">
Hello
</div>
</div>
</div>

iterating a multidimensional Json with AngularJS(Ng-Repeat)

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>

Categories

Resources