I'm used to using jQuery's each to go through an array and now I need to do the same in PHP, but I'm not quite sure how. PHP's each doesn't work quite the same way.
Given the following array, I know in jquery I could do something like the following to get the id value from each of the entry fields:
$.each(obj.entry, function(i, data) {
console.log(data.id);
});
The question I have is how to do this same thing in PHP. I tried:
//code to generate `$json` up here
echo $json; //returns array shown below
$newarray =json_decode($json, true);
$broke = each($newarray);
What do I need to do differently to get all the id from all the entries? Assume there will be around 100 or so.
Example JSON object below:
{
"id": "https://itunes.apple.com/us/rss/toppodcasts/limit=2/explicit=true/xml",
"title": "iTunes Store: Top Podcasts",
"updated": "2016-02-11T07:26:05-07:00",
"link": [{
"#attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewTop?cc=us&id=38&popId=3"
}
}, {
"#attributes": {
"rel": "self",
"href": "https://itunes.apple.com/us/rss/toppodcasts/limit=2/explicit=true/xml"
}
}],
"icon": "http://itunes.apple.com/favicon.ico",
"author": {
"name": "iTunes Store",
"uri": "http://www.apple.com/itunes/"
},
"rights": "Copyright 2008 Apple Inc.",
"entry": [{
"updated": "2016-02-11T07:26:05-07:00",
"id": "https://itunes.apple.com/us/podcast/serial/id917918570?mt=2&uo=2",
"title": "Serial - This American Life",
"summary": "Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. Serial unfolds one story - a true story - over the course of a whole season. The show follows the plot and characters wherever they lead, through many surprising twists and turns. Sarah won't know what happens at the end of the story until she gets there, not long before you get there with her. Each week she'll bring you the latest chapter, so it's important to listen in, starting with Episode 1. New episodes are released on Thursday mornings.",
"link": {
"#attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://itunes.apple.com/us/podcast/serial/id917918570?mt=2&uo=2"
}
},
"category": {
"#attributes": {
"term": "News & Politics",
"scheme": "https://itunes.apple.com/us/genre/podcasts-news-politics/id1311?mt=2&uo=2",
"label": "News & Politics"
}
},
"rights": "© Copyright 2016 Serial Podcast",
"content": "<table border=\"0\" width=\"100%\">\n <tr>\n <td>\n <table border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n <tr valign=\"top\" align=\"left\">\n \n <td align=\"center\" width=\"166\" valign=\"top\">\n <img border=\"0\" alt=\"This American Life - Serial artwork\" src=\"http://is2.mzstatic.com/image/thumb/Podcasts69/v4/90/ef/70/90ef704d-a2d6-ca6f-6972-1b62f8eadb01/mza_7676577196916555630.png/170x170bb-85.jpg\" />\n </td>\n <td width=\"10\"><img alt=\"\" width=\"10\" height=\"1\" src=\"https://s.mzstatic.com/images/spacer.gif\" /></td>\n \t<td width=\"95%\">\n \n \n <b>Serial</b><br/>\n \n \n \n \n\n This American Life\n\n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t \t<br/>\n <b>Genre:</b> News & Politics\n \n\t\t\t\t\t\t \t<br/>\n <b>Release Date:</b> February 6, 2016\n \n </font>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td>\n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"><br/>Serial is a podcast from the creators of This American Life, hosted by Sarah Koenig. Serial unfolds one story - a true story - over the course of a whole season. The show follows the plot and characters wherever they lead, through many surprising twists and turns. Sarah won't know what happens at the end of the story until she gets there, not long before you get there with her. Each week she'll bring you the latest chapter, so it's important to listen in, starting with Episode 1. New episodes are released on Thursday mornings.</font><br/>\n \n \n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"> © © Copyright 2016 Serial Podcast</font>\n\t \n </td>\n </tr>\n</table>\n"
}, {
"updated": "2016-02-11T07:26:05-07:00",
"id": "https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2",
"title": "Real Crime Profile - Real Crime Profile",
"summary": "Podcast talking about criminal cases and personality profiling.",
"link": {
"#attributes": {
"rel": "alternate",
"type": "text/html",
"href": "https://itunes.apple.com/us/podcast/real-crime-profile/id1081244497?mt=2&uo=2"
}
},
"category": {
"#attributes": {
"term": "History",
"scheme": "https://itunes.apple.com/us/genre/podcasts-history/id1462?mt=2&uo=2",
"label": "History"
}
},
"rights": "© All rights reserved",
"content": "<table border=\"0\" width=\"100%\">\n <tr>\n <td>\n <table border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n <tr valign=\"top\" align=\"left\">\n \n <td align=\"center\" width=\"166\" valign=\"top\">\n <img border=\"0\" alt=\"Real Crime Profile - Real Crime Profile artwork\" src=\"http://is5.mzstatic.com/image/thumb/Podcasts69/v4/ff/fa/95/fffa95d2-5156-2f85-8e2e-1b2bc3a82236/mza_1683998348979602855.jpg/170x170bb-85.jpg\" />\n </td>\n <td width=\"10\"><img alt=\"\" width=\"10\" height=\"1\" src=\"https://s.mzstatic.com/images/spacer.gif\" /></td>\n \t<td width=\"95%\">\n \n \n <b>Real Crime Profile</b><br/>\n \n \n \n \n\n Real Crime Profile\n\n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t \t<br/>\n <b>Genre:</b> History\n \n\t\t\t\t\t\t \t<br/>\n <b>Release Date:</b> February 2, 2016\n \n </font>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td>\n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"><br/>Podcast talking about criminal cases and personality profiling.</font><br/>\n \n \n \n <font size=\"2\" face=\"Helvetica,Arial,Geneva,Swiss,SunSans-Regular\"> © © All rights reserved</font>\n\t \n </td>\n </tr>\n</table>\n"
}]
}
foreach($newarray as $key => $value) {
echo $key; // 0, 1, 2, etc
echo $value['id'] ; // echos ID
}
As your JSON String represents an object I would leave it as an object i.e. loose the ,true in the json_decode()
$jObj = json_decode($json);
foreach( $jObj->entry as $entry ) {
echo $entry->id . PHP_EOL;
echo $entry->title . PHP_EOL;
echo $entry->updated . PHP_EOL;
}
To make a new object out of what you take from the original data you coudl do something like this
$jObj = json_decode($json);
$new = new stdClass(); // create a new object
foreach( $jObj->entry as $entry ) {
$t = new stdClass();
$t->id = $entry->id;
$t->title = $entry->title;
$t->updated = $entry->updated;
$new->entries[] = $t; // create an array of objects
}
$newJsonString = json_encode($new);
PHP has foreach for this kind of operation
foreach($data as $key=> $value){
echo $value['id'];// or whatever you need
}
You can use php foreach loop:
foreach($newarray as $key => $value) {
// do smthg here
}
You can use for and foreach statements.
$row = json_decode($jsonString);
foreach($row as $key => $value) {
echo $key, '=>', $value;
// for you in $value will be key id $value['id']
}
Related
I've searched and attempted to get this working for a few weeks and I'm still failing. I've tried several ways including reg expressions. I have a dynamic table that I scrape with puppeteer and I'm trying to output that data as JSON. The problem is that the header "2nd flr (Rm 226)" & 'Location - Room 115' May or may not show. The events in these rooms may have 1 or multiple events. How do I convert dynamic data like this and ensure that I get everything listed?
I'm trying to get something like this JSON.
data: [
{
"location": "2nd flr (Rm 226)"
"time": "10:00 AM",
"description": "Social Security Administration Commissioner",
"document": "18",
"type": "Social Security Hearing",
"blank": " ",
"order": "Hearing"
},
{
"location": "2nd flr (Rm 226)"
"time": "01:00 PM",
"description:"
"Social Security Administration Commissioner",
"document": "18",
"type": "Order Setting Social Security Hearing",
"blank": " ",
order: "Hearing"
},
{
"location": "3rd flr (100)"
"time": "01:00 PM",
"description:"
"Social Security Administration Commissioner",
"document": "18",
"type": "Order Setting Social Security Hearing",
"blank": " ",
order: "Hearing"
}
]
const data = Array.from(
document.querySelectorAll('#content > table > tbody > tr'),
row => Array.from(row.querySelectorAll('td'), cell => cell.innerText)
)
Here is the output that I get.
{
"data": [
[
"2nd flr (Rm 226)"
],
[
"10:00 AM",
"Social Security Administration Commissioner",
"18",
"Social Security Hearing",
" ",
"Hearing"
],
[
"01:00 PM",
"Social Security Administration Commissioner",
"18",
"Order Setting Social Security Hearing",
" ",
"Hearing"
],
[
"3rd flr (100)"
],
[
"09:30 AM",
"TERMINATED on 03/23/2015",
"34",
"Resetting Hearings",
" ",
"Hearing"
],
[
" ",
"Reserved for case",
"23",
"Motion Hearing",
" ",
"Hearing"
],
[
"01:00 PM",
"Case Information",
"19",
"Order Setting",
" ",
"Hearing"
],
[
"01:30 PM",
"Case information",
"31",
"Order Setting",
" ",
"Hearing"
],
[
" ",
"TERMINATED on 06/14/2019",
"16",
"Order Setting/Resetting Hearings",
" ",
"Hearing"
],
[
"3rd flr (Rm 310)"
],
[
"01:30 PM",
"Insurance Company",
"122",
"Order Setting/Resetting Hearings",
" ",
"Hearing"
]
]
}
<center><Table border=1 width=98%>
<TR><TD id='report' class='report' align=center><B><FONT SIZE=+2>Daily Calendar Report of 09/23/2019</font></B><BR><CENTER></table></center>
<Table border=1 width=98% >
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 226)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>10:00 AM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top> </TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 406)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>1:30 PM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top> </TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
</table>
const tds = Array.from(document.querySelectorAll('#Content > table > tbody > tr > td'));
const trs = Array.from(document.querySelectorAll('#Content > table > tbody > tr'))
const data = Array.from(
document.querySelectorAll('#Content > table > tbody > tr'),
row => Array.from(row.querySelectorAll('td'), cell => cell.innerText),
data =>{ return ( [data] ) }
)
You need to look for further clues in your HTML to achieve the structure you desire. In this case I looked for the class of the first td in each tr.
[[ I know you are only reading the HTML, but it is faulty, as there are multiple identical ids assigned (room) in it ...]]
// define shortcut function qsa: querySelectorAll, returning a proper array
// An HTML context `el` can be given as an optional second parameter
function qsa(s,el){
return Array.prototype.map.call((el?Element:Document).prototype
.querySelectorAll.call((el||document),s),function(e){return e})
}
data=[];
qsa('tr').forEach(function(tr,i,arr){
var tds=qsa('td',tr);
if (tds[0].className=='room')
arr.room=tds[0].innerText // "remember" the current room data ...
else if (tds[0].className=='case-0')
data.push([arr.room].concat(tds.map(function(e){return e.innerText}))) // output room and row data
});
console.log(data)
// and, of course, the JSON is created by
var JSONdata=JSON.stringify(data);
<center><Table border=1 width=98%>
<TR><TD id='report' class='report' align=center><B><FONT SIZE=+2>Daily Calendar Report of 09/23/2019</font></B><BR><CENTER></table></center>
<Table border=1 width=98% >
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 226)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>10:00 AM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top> </TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
<TR><TD class='room' id='room' ALIGN=CENTER COLSPAN=6><STRONG>2nd flr (Rm 406)</STRONG></TD></TR>
<TR id='casedata' class='casedata'>
<TD class=case-0 id=case-0 VALIGN=top NOWRAP>1:30 PM</TD>
<TD class=case-1 id=case-1 VALIGN=top><A HREF=/Reportpt.pl?55244>Social Security Administration</A><B></B></TD>
<TD class=case-2 id=case-2 VALIGN=top>18</TD>
<TD class=case-3 id=case-3 VALIGN=top>Security Hearing</TD>
<TD class=case-4 id=case-4 VALIGN=top> </TD>
<TD class=case-5 id=case-5 VALIGN=top NOWRAP><I>Hearing</I></TD>
</TR>
</table>
This solution might seem a bit old-fashioned (no Array.from, no arrow functions). I wrote it so it will still work in IE.
I don't think that you have the right title. Getting json is easy, just use JSON.stringify Your problem is getting the objects you want to convert to be consistent, or at least the way you want them - it looks like the code is generating lots of arrays, rather than an array of objects
So I think you have to do more work parsing the html. I would console log the objects coming from the html to check it before converting to json.
So you could read each <td> explicitly, rather than in the loop, assigning either the value to the object or a default value
I have no idea how i do this, i have some pieces of code, that i need to "handle" and use in javascript for some search engine
This is what i have in my database
[
["Reparation", "Pris"],
["Fejlfinding", "Gratis"],
["Udskiftning af Skærm (Refurbished)", "3699,-"]
]
This is what i need it to look like after i get it from the database and it has been handled.
var searchChoices = {
"Name": {
"Model Name": {
"icons": {
"dark": "Imagelink",
"light": "imagelink"
},
"items": [
{
"headline": "Gratis",
"text": "Fejlfinding"
},
{
"headline": "3699",
"text": "Udskiftning af Skærm (Refurbished)"
}
]
}
}
};
I have really no idea how to do this? I don't even know what it's called.
Can someone please help me, or point me in the right way?
Thanks
I think you should use php json_encode function to send data to javascript. You can make something like this:
<script>
var data = <?=json_encode($data);?>
...
Next step is simple loop to add items:
for(var row in data)
searchChoices["Name"]["Model name"].items.push({
"headline": data[row][1],
"text": data[row][0]
});
You can also generate whole javascript object using PHP:
<script>
var searchChoices = {
"Name": {
"Model Name": {
"icons": {
"dark": "Imagelink",
"light": "imagelink"
},
"items": [
<?php
foreach($data as $row)
echo '{"headline": "' . $row[1] . '", "text": "' . $row[0] . '"},';
?>
]
}
}
};
OK, this is another solution, regular expression:
(\[\"(.+)\"\,\ ?\"(.+)\"\]\,?)
The next step is to get data from preg_match_all result.
This is simple script i wrote to test:
<?php
$data = <<<JS
[
["Reparation", "Pris"],
["Fejlfinding", "Gratis"],
["Udskiftning af Skærm (Refurbished)", "3699,-"]
]
JS;
$pattern = '/(\[\"(.+)\"\,\ ?\"(.+)\"\]\,?)/';
$matches = [];
$result = preg_match_all($pattern, $data, $matches);
for($i=0, $j=count($matches[2]); $i<$j; $i++) {
echo '{"headline": "' . $matches[3][$i] . '", "text": "' . $matches[2][$i] . '"},' . "\n";
}
I am working with Laravel and implementing Google Tag manager. I am pushing an object into Google's data layer with an event.
<a href="javascript:void(0)" class="btn btn-default" id="step1"
onclick="dataLayer.push({
#foreach(Cart::content() as $content)
#if($loop->first)
'id': '{{$content->rowId}}',
'affiliation':'Gazebo',
'revenue':'{{Cart::total()}}',
#endif
#endforeach
'transactionProductts':[
#foreach(Cart::content() as $cart)
{
'sku': '{{$cart->id}}',
'price': '{{$cart->subtotal}}',
'name':'{{$cart->name}}'
}
#if($loop->iteration != $loop->last)
,
#endif
#endforeach
})">Continue.</a>
And after it has rendered it looks like this in page source
<a href="javascript:void(0)" class="btn btn-default" id="step1" onclick="dataLayer.push({
"affiliation": "foo-bar",
"id": "id1",
"revenue": "146.96",
"transactionProductts": [
{
"name": "Video1",
"price": "2.99",
"sku": "23409"
},
{
"name": "Video2",
"price": "3.99",
"sku": "21598"
},
{
"name": "Video 3",
"price": "129.99",
"sku": "23430"
},
{
"name": "Mozart's Magic Flute Diaries ",
"price": "2.99",
"sku": "22370"
}
]
})">Continue.</a>
I am thinking that it is my last conditional statement and adding the comma, because it works fine when I dont have the comma there, but I need to wrap in conditional statement so it doesn't add a comma at the end of the array and it gives me the "unexpected identifier" error
Any help greatly appreciated
Build the json string first and trim the trailing comma:
#php
$json = ''
foreach(Cart::content() as $idx => $content) {
if ($idx === 0) {
$json .= "id: ${content->rowId},";
$json .= "affiliation:'Gazebo',";
$json .= "revenue: " . Cart::total() . ",";
}
}
$json .= 'transactionProductts:[';
foreach(Cart::content() as $cart) {
$json .= "{sku: ${cart->id},";
$json .= "price: ${cart->subtotal,";
$json .= "name: ${cart->name}},";
}
$final = trim($json, ',') . ']';
#endphp
onclick="dataLayer.push({ {{ $final }} })"
Im struggling with a piece of code i have below and cant seam to find something like it anywhere on stacks.
I have tried using the JavaScript .indexof(is returning all that doesn't contain variables) as well as the .match(shows all even if contain part of the word. i need it to be exact for obvious reasons) and even jquery.
I was wondering if anyone can help me.
I have a script that pulls data from the server into the following array.
from there i need to be able to compare this array with data that is on the page. if it exists in the server i want to highlight the checkbox i have created. when i did .match it found all variables that contained say the characters foo but i need exact matches not just if it contains.
see below for what i currently have. (note that the variables aren't set in stone and some may be different that will be contained in others which is why they need to be exact)
var industriesget = [ "Servers & Software", "Environmental Issues", "Hotels & Tourism"];
var industries = [ "Servers & Software", "Environmental Issues", "Hotels & Tourism", "Liquor, Wine & Beer", "Defense Industries", "Publishing & Printing", "Real Estate", "Not For Profit", "Food Services", "Corporate & Banking", "Agriculture & Fishing", "Communications", "Manufacturing", "Mining", "Entertainment & Gambling", "Retail Sales", "Signage & Fitouts", "Construction", "Transportation", "Public Utilities", "Education" ];
for ( var i = 0; i < industries.length; i++ ) {
//another for loop to run through the matches?
if..........
document.write( "<label for='" + industries[ i ] + "' class='col-md-2 col-xs-5' style=' float:left; height:55px;' valign='middle'>" + industries[ i ] + "<input valign='middle' type='checkbox' style='vertical-align: middle;text-align: center;' name='products' id='" + industries[ i ] + "' checked></label>" );
else{
document.write( "<label for='" + industries[ i ] + "' class='col-md-2 col-xs-5' style=' float:left; height:55px;' valign='middle'>" + industries[ i ] + "<input valign='middle' type='checkbox' style='vertical-align: middle;text-
}
}
Is this what you are looking for? This is simplest way.
var industriesget = [ "Servers & Software", "Environmental Issues", "Hotels & Tourism"];
var industries = [ "Servers & Software", "Environmental Issues", "Hotels & Tourism", "Liquor, Wine & Beer", "Defense Industries", "Publishing & Printing", "Real Estate", "Not For Profit", "Food Services", "Corporate & Banking", "Agriculture & Fishing", "Communications", "Manufacturing", "Mining", "Entertainment & Gambling", "Retail Sales", "Signage & Fitouts", "Construction", "Transportation", "Public Utilities", "Education" ];
for ( var i = 0; i < industries.length; i++ ) {
//another for loop to run through the matches?
if(industriesget.indexOf(industries[i])!== -1)
document.write( "<label for='" + industries[ i ] + "' class='col-md-2 col-xs-5' style=' float:left; height:55px;' valign='middle'>" + industries[ i ] + "<input valign='middle' type='checkbox' style='vertical-align: middle;text-align: center;' name='products' id='" + industries[ i ] + "' checked></label>" );
else{
document.write( "<label for='" + industries[ i ] + "' class='col-md-2 col-xs-5' style=' float:left; height:55px;' valign='middle'>" + industries[ i ] + "<input valign='middle' type='checkbox' style='vertical-align: middle;text-")
}
}
If you want to find whether industriesget is subset of industries, then try using
var intersectionIndustries = industries.filter(function(n) {
return industriesget.indexOf(n) !== -1;
});
and check
(intersectionIndustries.length == industriesget.length)
,if true then its subset, else there are non existent entries in industries get.
Use this:
pass two arrays to this function and check if the flag is true or not:
var industriesget = [ "Servers & Software", "Environmental
Issues", "Hotels & Tourism"];
var industries = [ "Servers & Software", "Environmental Issues", "Hotels
& Tourism", "Liquor, Wine & Beer", "Defense Industries", "Publishing &
Printing", "Real Estate", "Not For Profit", "Food Services", "Corporate &
Banking", "Agriculture & Fishing", "Communications", "Manufacturing",
"Mining", "Entertainment & Gambling", "Retail Sales", "Signage &
Fitouts",
"Construction", "Transportation", "Public Utilities", "Education" ];
if(arr(industriesget,industries)) {
alert("contains");
}
Where our function is:
function arr(industriesget,industries)
{
var flag=false;
for(var i=0;i<industriesget.length;i++)
{
if(industries.includes(industriesget[i])) {
flag = true;
}
}
return flag;
}
I a have a webpage with a complex table structure. The entire code is right here --> (index.php)
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<?php
// this turns the json object into an array
$json_string = file_get_contents("info.json");
$json = json_decode($json_string, true);
?>
<div id="scroll_box">
<table border="1" cellpadding="10" id="container">
<tr>
<td>
<table class="organizer">
<?php foreach($json as $key => $value): ?>
<!-- this is what needs to be repeated -->
<tr><td class="index"> <?php echo $key ?> </td></tr>
<thead class="sticky" align="center"><tr><th> <?php echo $value["name"] ?></th></tr></thead>
<tbody>
<tr>
<td>
<table class="spell_container">
<?php
foreach ($value["items"] as $key => $value) {
echo '<tr><td><table class="table-bordered spell_shorthand">'.
'<tr><td>Name</td><td class="name">'.$value["name"].'</td></tr>'.
'<tr><td>Type</td><td class="type">'.$value["type"].'</td></tr>'.
'</table>'.
'</td>'.
'<td class="description">'.$value["description"].'</td>'.
'<td><div class="btn-group"><button class="learn">Learn</button></div></td>'.
'</tr>';
}
?>
</table>
</td>
</tr>
</tbody>
<?php endforeach; ?>
</table>
</td>
</tr>
</table>
</div>
<script type="text/javascript">
$(".learn").on('click', function(){
var the_name = $(this).closest("tr").find("table.spell_shorthand").find("td.name").text();
var the_type = $(this).closest("tr").find("table.spell_shorthand").find("td.type").text();
var the_description = $(this).closest("tr").find("td.description").text();
var the_index = $(this).closest("table.organizer").find("td.index").text();
console.log(the_name);
console.log(the_type);
console.log(the_description);
console.log(the_index);
});
</script>
</body>
</html>
and the JSON data that is being used looks like this --> (info.json)
[
{
"name": "level0",
"items": [
{
"name": "item1",
"type": "type1",
"description": "this is item 1"
},
{
"name": "item2",
"type": "type2",
"description": "this is item 2"
},
{
"name": "item2",
"type": "type2",
"description": "this is item 3"
}
]
},
{
"name": "Level1",
"items": [
{
"name": "item4",
"type": "type4",
"description": "this is item 4"
},
{
"name": "item5",
"type": "type5",
"description": "this is item 5"
}
]
},
{
"name": "Level2",
"items": [
{
"name": "item6",
"type": "type6",
"description": "this is item 6"
}
]
}
]
Now. All of my console.log statements in the js script work perfectly except for the one that deals with "the_index" ... for whatever reason, it is returning all of the instances of index (0, 1, 2) when really it should just be returning the index of the header that is the parent of the button that is clicked.
I encourage you to take these two files and see for yourself what I'm talking about.
Any insight as to why clicking a button under the first index (0) would return (0 1 2) would be appreciated, thank you.
Try running an index on your tables in the loop like so:
<?php
$num_row = 0;
foreach ($value["items"] as $key => $value) {
echo '<tr id="row_'.$num_row.'"><td><table class="table-bordered spell_shorthand">'.
'<tr><td>Name</td><td class="name">'.$value["name"].'</td></tr>'.
'<tr><td>Type</td><td class="type">'.$value["type"].'</td></tr>'.
'</table>'.
'</td>'.
'<td class="description">'.$value["description"].'</td>'.
'<td><div class="btn-group"><button class="learn" data-row-id="#row_'.$num_row.'">Learn</button></div></td>'.
'</tr>';
$num_row = $num_row + 1;
}
?>
You can revise your click event to be something like below using jQuery. This will simplify things quite a bit.
$(".learn").on('click', function(){
var row_selector = $(this).data('row-id');
var the_name = $(row_selector + ' .name').text();
var the_type = $(row_selector + ' .type').text();
var the_description = $(row_selector + ' .description').text();
var the_index = $(row_selector + ' .index').text();
});