Avatar of Dawn
Dawn
 asked on

Javascript/JQuery- Match string in dropdown to string in JSON and display the JSON sibling's array

I'm attempting to display part of an array from JSON when the user clicks on an ID in the dropdown. The data is loading data twice and then subsequent clicks just layer array upon array even though I have set my array to clear when update() is fired. I'm also getting a "update is not defined at HTMLAnchorElement.onclick" although that function itself is firing when the page loads.

How can I resolve the error and only display the one set of matching data? Here is a fiddle: https://jsfiddle.net/dtepdc/4e6mfoct/

Here is the code:

let dataset = [
    {
        "scene": "IR0006426320",
        "scene_start_time": "2018-02-05T15:03:30",
        "chips": [
        {
            "chip": "2018.02.05.150",
            "start_date": "2018-02-05T00:05:07",
            "end_date": "2018-02-05T01:26:23",
            "co_num":["None"],
            "cause": false
        },
        {
            "chip": "2018.02.05.192",
            "start_date": "2018-02-05T15:48:08",
            "end_date": "2018-02-05T17:22:34",
            "co_num": [
                "C03619354",
                "C03618763",
                "C03619064",
                "C03619325"
            ],
            "cause": false
        },
        {
            "chip": "2018.02.05.26",
            "start_date": "2018-02-05T16:38:56",
            "end_date": "2018-02-05T21:08:00",
            "co_num": [
                "C03610724"
            ],
            "cause": false
        },
        {
            "chip": "2018.02.05.303",
            "start_date": "2018-02-05T13:34:58",
            "end_date": "2018-02-05T13:34:58",
            "co_num": [
                "C03610724"
            ],
            "cause": true
        },
        {
            "chip": "2018.02.05.44",
            "start_date": "2018-02-05T21:20:39",
            "end_date": "2018-02-05T23:41:59",
            "co_num": [
                "C03610724"
            ],
            "cause": false
        },
        {
            "chip": "2018.02.05.53",
            "start_date": "2018-02-05T13:59:46",
            "end_date": "2018-02-05T16:01:35",
            "co_num": [
                "C03610724"
            ],
            "cause": true
        },
        {
            "chip": "2018.02.05.54",
            "start_date": "2018-02-05T01:04:53",
            "end_date": "2018-02-05T01:09:58",
            "co_num":["None"],
            "cause": false
        },
        {
            "chip": "2018.02.06.63",
            "start_date": "2018-02-05T23:44:23",
            "end_date": "2018-02-05T23:59:18",
            "co_num": [
                "C03610724"
            ],
            "cause": false
        }
    ]
},
{
    "scene": "IR0006633836",
    "scene_start_time": "2018-05-2418T14:20:00",
    "chips": [
        {
            "chip": "2018.05.25.50",
            "start_date": "2018-05-24T02:10:04",
            "end_date": "2018-05-24T06:39:41",
            "co_num": [
                "C03726697", "None"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.25.59",
            "start_date": "2018-05-24T03:02:01",
            "end_date": "2018-05-24T04:26:06",
            "co_num": [
                "C03728974",
                "C03729029",
                "C03704816",
                "C03728657",
                "C03719067"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.26.137",
            "start_date": "2018-05-24T18:02:47",
            "end_date": "2018-05-24T18:43:10",
            "co_num":["None"],
            "cause": false
        },
        {
            "chip": "2018.05.26.194",
            "start_date": "2018-05-24T15:08:40",
            "end_date": "2018-05-24T15:10:40",
            "co_num":["None"],
            "cause": false
        },
        {
            "chip": "2018.05.26.197",
            "start_date": "2018-05-24T18:20:53",
            "end_date": "2018-05-24T18:20:53",
            "co_num": [
                "C03726648"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.26.269",
            "start_date": "2018-05-24T21:07:35",
            "end_date": "2018-05-24T21:08:48",
            "co_num": [
                "C03726648"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.26.30",
            "start_date": "2018-05-24T14:20:17",
            "end_date": "2018-05-24T21:14:25",
            "co_num":[
                "C03704816",
                "C03719067",
                "C03728657"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.26.31",
            "start_date": "2018-05-24T15:19:35",
            "end_date": "2018-05-24T17:33:52",
            "co_num": [
                "C03704816",
                "C03719067",
                "C03728657", "None"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.26.377",
            "start_date": "2018-05-24T14:59:08",
            "end_date": "2018-05-24T15:25:06",
            "co_num": [
                "C03730107",
                "C03714722",
                "C03728407",
                "C03728209"
            ],
            "cause": false
        },
        {
            "chip": "2018.05.26.39",
            "start_date": "2018-05-24T18:13:52",
            "end_date": "2018-05-24T18:13:53",
            "co_num": [
                "C03728284"
            ],
            "cause": false
        }
    ]
}
]

Open in new window

        $.each(dataset, function (i) {
            $('#dropdownMenuButtonAnchor').append('<a class="dropdown-item" onclick="update()" href="#">' + dataset[i].scene  + '</a>');
    });

            $.each(dataset, function (j) {
            let firstIncident = dataset[0].scene;
            $("#incidentNumber").html(firstIncident);

        });


setTimeout(function() {
    update();
}, 100);

  /* change() ********************* */
  function update() {
    d3.selectAll('svg').remove();
    let changed = [];
    let start = moment().subtract(24, 'months').valueOf();
    let timeRange =     d3.select('input[name="options"]:checked').property("value");

if (timeRange < 12) {
    start = moment().subtract(timeRange, 'minutes').valueOf();
} else if (timeRange >= 12 && timeRange < 36) {
    start = moment().subtract(timeRange, 'hours').valueOf();
} else if (timeRange === 24) {
    start = moment().subtract(16, 'months').valueOf();
}

let end = moment().valueOf();

const coNumW = window.innerWidth,
        coNumH = window.innerHeight,
        margin = {top: coNumH * 0.15, right: coNumW * 0.05, bottom: coNumH * 0.12, left: coNumW * 0.12},
        w = coNumW - margin.left - margin.right,
        h = coNumH - margin.top - margin.bottom;

let x = d3.scaleTime().range([w, 0]),
    y = d3.scaleBand().range([h, 0]),
    xAxis = d3.axisBottom(x)
    yAxis = d3.axisLeft(y),
    filtered = [],
    dateFormat = d3.timeFormat("%Y-%m-%d %I:%M %p"),
    weekdayFormat = d3.timeFormat("%w");

    let newSvg = d3.select("body")
    .append("svg")
    .attr("width", coNumW)
    .attr("height", coNumH)
    .append("g").classed("no-select", true)
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// ********************************************* LOOPS *********************************************
   $('div#dropdownMenuButtonAnchor a').click(function(){

    let incident = $(this).text();
    $("#incidentNumber").html(incident);

            //dataset.forEach(function(d, i) {
                for (let i = 0;i < dataset.length;i++){
                    if (incident === dataset[i].scene) {
                        dataset[i].chips.forEach(function(c, j) {
                            changed.push(c);

                            $('.incidentInfo').append('<a class="dropdown-item" onclick="update()" href="#">' + c.co_num  + '</a>');

                          });


// ********************************************* LOOPS *********************************************

x.domain([new Date(start), new Date(end)]).range([0, w]);
y.domain(changed.map(d => d.chip)).padding(0.1);

newSvg.append("g")
        .attr("class", "x_Axis")
        .attr("transform", "translate(0, " + h + ")")
        .call(xAxis)

newSvg.append("g")
        .attr("class", "y_Axis")
        .call(yAxis);

let tasksChange = newSvg.append("g")
        .attr("class", "dataCont")
        .selectAll("g")
        .data(changed)
        .enter()
        .append("g")
        .on("mouseenter", showData);

    let parseDate = d3.timeParse('%Y-%m-%dT%H:%m:%s');
    tasksChange.append("rect")
            .attr("x", function(d) {
                return x(moment(d.start_date).valueOf()) + 2;
            })
            .attr("y", function(d) {
            return y(d.chip);
            })
            .attr("width", function(d) {
                return x(moment(d.end_date)) - x(moment(d.start_date)) +2;
            })
            .attr("height", function(d) {
                return y.bandwidth();
            });


            d3.selectAll("#inlineRadio2, #inlineRadio3, #inlineRadio4")
                .on("change", function(){
                    update();
            });

            d3.selectAll("#inlineRadio1")
                .on("change", function(){
                setInterval(update, 10);
                var svg = d3.select("svg");

                let start = moment().subtract(timeRange, 'minutes').valueOf();
                let end = moment().valueOf();

                x.domain([start, end]);
                xAxis.scale(x);

                    //move the xaxis left
                svg.select(".x_axis")
                  .transition()
                  .duration(100)
                  .ease(d3.easeLinear)
                  .call(xAxis);
              });


    function showData(d) {
        console.log("Start Date: " + moment(d.start_date).format());
        console.log("End Date: " + moment(d.end_date).format());
        console.log('CO: ', d.chip)
        console.log('************************* ')

    }
}
}
});
  }

Open in new window

JavaScriptjQueryJSON* D3.js

Avatar of undefined
Last Comment
Dawn

8/22/2022 - Mon
Dawn

ASKER
Will do...
Julian Hansen

Hint:You have posted a significant amount of code. In future try to narrow it down to what code is integral to the problem or at least give pointers as to where to start looking.
A short synopsis of your code will also help.

Let's look at your code you have this

setTimeout(function() {
	update();
}, 100);

Open in new window

In other words, every 100 milliseconds you are calling the update function.
In the update function you have this
$('div#dropdownMenuButtonAnchor a').click(function(){
		let incident = $(this).text();

Open in new window

So every 100 milliseconds you are binding ANOTHER click handler to your markup. That means every time it fires ALL handlers are going to fire.
Whether or not this is the cause of your problem is not clear but it is something you need to fix.

Move your click handler outside of the update function - move the function closing } to above the $(`div#dropdown...) line

You may need to change your .click to a .on handler - it is important to understand the difference between these two and why you would use one over the other.
If you are creating content dynamically that you need to bind a click event to then it will fail because the element needs to exist when you bind it. The .on() handler will allow you to bind the handler to a static parent and specify a child class / element to relate the event to.

You can also move your showData function outside of the event handler.

I updated your fiddle as best I could (see below)
Hint2: Tidy code is much easier to work with than untidy code. Take some time to format your code neatly and lay it out in an ordered way. I found it very difficult to figure out what your code was doing as the formatting and layout were very chaotic.
let dataset = [
    {
        "scene": "IR0006426320",
        "scene_start_time": "2018-02-05T15:03:30",
        "chips": [
            {
                "chip": "2018.02.05.150",
                "start_date": "2018-02-05T00:05:07",
                "end_date": "2018-02-05T01:26:23",
                "co_num":["None"],
                "cause": false
            },
            {
                "chip": "2018.02.05.192",
                "start_date": "2018-02-05T15:48:08",
                "end_date": "2018-02-05T17:22:34",
                "co_num": [
                    "C03619354",
                    "C03618763",
                    "C03619064",
                    "C03619325"
                ],
                "cause": false
            },
            {
                "chip": "2018.02.05.26",
                "start_date": "2018-02-05T16:38:56",
                "end_date": "2018-02-05T21:08:00",
                "co_num": [
                    "C03610724"
                ],
                "cause": false
            },
            {
                "chip": "2018.02.05.303",
                "start_date": "2018-02-05T13:34:58",
                "end_date": "2018-02-05T13:34:58",
                "co_num": [
                    "C03610724"
                ],
                "cause": true
            },
            {
                "chip": "2018.02.05.44",
                "start_date": "2018-02-05T21:20:39",
                "end_date": "2018-02-05T23:41:59",
                "co_num": [
                    "C03610724"
                ],
                "cause": false
            },
            {
                "chip": "2018.02.05.53",
                "start_date": "2018-02-05T13:59:46",
                "end_date": "2018-02-05T16:01:35",
                "co_num": [
                    "C03610724"
                ],
                "cause": true
            },
            {
                "chip": "2018.02.05.54",
                "start_date": "2018-02-05T01:04:53",
                "end_date": "2018-02-05T01:09:58",
                "co_num":["None"],
                "cause": false
            },
            {
                "chip": "2018.02.06.63",
                "start_date": "2018-02-05T23:44:23",
                "end_date": "2018-02-05T23:59:18",
                "co_num": [
                    "C03610724"
                ],
                "cause": false
            }
        ]
    },
    {
        "scene": "IR0006633836",
        "scene_start_time": "2018-05-2418T14:20:00",
        "chips": [
            {
                "chip": "2018.05.25.50",
                "start_date": "2018-05-24T02:10:04",
                "end_date": "2018-05-24T06:39:41",
                "co_num": [
                    "C03726697", "None"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.25.59",
                "start_date": "2018-05-24T03:02:01",
                "end_date": "2018-05-24T04:26:06",
                "co_num": [
                    "C03728974",
                    "C03729029",
                    "C03704816",
                    "C03728657",
                    "C03719067"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.26.137",
                "start_date": "2018-05-24T18:02:47",
                "end_date": "2018-05-24T18:43:10",
                "co_num":["None"],
                "cause": false
            },
            {
                "chip": "2018.05.26.194",
                "start_date": "2018-05-24T15:08:40",
                "end_date": "2018-05-24T15:10:40",
                "co_num":["None"],
                "cause": false
            },
            {
                "chip": "2018.05.26.197",
                "start_date": "2018-05-24T18:20:53",
                "end_date": "2018-05-24T18:20:53",
                "co_num": [
                    "C03726648"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.26.269",
                "start_date": "2018-05-24T21:07:35",
                "end_date": "2018-05-24T21:08:48",
                "co_num": [
                    "C03726648"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.26.30",
                "start_date": "2018-05-24T14:20:17",
                "end_date": "2018-05-24T21:14:25",
                "co_num":[
                    "C03704816",
                    "C03719067",
                    "C03728657"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.26.31",
                "start_date": "2018-05-24T15:19:35",
                "end_date": "2018-05-24T17:33:52",
                "co_num": [
                    "C03704816",
                    "C03719067",
                    "C03728657", "None"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.26.377",
                "start_date": "2018-05-24T14:59:08",
                "end_date": "2018-05-24T15:25:06",
                "co_num": [
                    "C03730107",
                    "C03714722",
                    "C03728407",
                    "C03728209"
                ],
                "cause": false
            },
            {
                "chip": "2018.05.26.39",
                "start_date": "2018-05-24T18:13:52",
                "end_date": "2018-05-24T18:13:53",
                "co_num": [
                    "C03728284"
                ],
                "cause": false
            }
        ]
    }
]
    
        $.each(dataset, function (i) {
            $('#dropdownMenuButtonAnchor').append('<a class="dropdown-item" onclick="update()" href="#">' + dataset[i].scene  + '</a>');
        });
        
            $.each(dataset, function (j) {
            let firstIncident = dataset[0].scene;
            $("#incidentNumber").html(firstIncident);
            
        });


setTimeout(function() {
    update();
}, 100);

  /* change() ********************* */
  function update() {
    d3.selectAll('svg').remove();
    let changed = [];
    let start = moment().subtract(24, 'months').valueOf();
    let timeRange = d3.select('input[name="options"]:checked').property("value");
    
    if (timeRange < 12) {
        start = moment().subtract(timeRange, 'minutes').valueOf();
    } else if (timeRange >= 12 && timeRange < 36) {
        start = moment().subtract(timeRange, 'hours').valueOf();
    } else if (timeRange === 24) {
        start = moment().subtract(16, 'months').valueOf();
    }

    let end = moment().valueOf();

    const coNumW = window.innerWidth,
            coNumH = window.innerHeight,
            margin = {top: coNumH * 0.15, right: coNumW * 0.05, bottom: coNumH * 0.12, left: coNumW * 0.12},
            w = coNumW - margin.left - margin.right,
            h = coNumH - margin.top - margin.bottom;

    let x = d3.scaleTime().range([w, 0]),
        y = d3.scaleBand().range([h, 0]),
        xAxis = d3.axisBottom(x)
        yAxis = d3.axisLeft(y),
        filtered = [],
        dateFormat = d3.timeFormat("%Y-%m-%d %I:%M %p"),
        weekdayFormat = d3.timeFormat("%w");

        let newSvg = d3.select("body")
        .append("svg")
        .attr("width", coNumW)
        .attr("height", coNumH)
        .append("g").classed("no-select", true)
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // ********************************************* LOOPS *********************************************
}

$('div#dropdownMenuButtonAnchor a').click(function(){
  let incident = $(this).text();
  $("#incidentNumber").html(incident);

  //dataset.forEach(function(d, i) {
  for (let i = 0;i < dataset.length;i++){
    if (incident === dataset[i].scene) {
      dataset[i].chips.forEach(function(c, j) {
        changed.push(c);
        $('.incidentInfo')
        	.append('<a class="dropdown-item" onclick="update()" href="#">' + c.co_num  + '</a>');
      });
                    

      // ********************************************* LOOPS *********************************************
        
      x.domain([new Date(start), new Date(end)]).range([0, w]);
      y.domain(changed.map(d => d.chip)).padding(0.1);
    
      newSvg.append("g")
        .attr("class", "x_Axis")
        .attr("transform", "translate(0, " + h + ")")
        .call(xAxis)

    	newSvg.append("g")
        .attr("class", "y_Axis")
        .call(yAxis);
            
    	let tasksChange = newSvg.append("g")
        .attr("class", "dataCont")
        .selectAll("g")
        .data(changed)
        .enter()
        .append("g")
        .on("mouseenter", showData);

			let parseDate = d3.timeParse('%Y-%m-%dT%H:%m:%s');
      tasksChange.append("rect")
        .attr("x", function(d) {
          return x(moment(d.start_date).valueOf()) + 2;
        })
        .attr("y", function(d) {
	        return y(d.chip);
  	    })
        .attr("width", function(d) {
    	    return x(moment(d.end_date)) - x(moment(d.start_date)) +2;
      	})
        .attr("height", function(d) {
        	return y.bandwidth();
      	});

				d3.selectAll("#inlineRadio2, #inlineRadio3, #inlineRadio4")
					.on("change", function(){
						update();
				});

				d3.selectAll("#inlineRadio1")
					.on("change", function(){
						setInterval(update, 10);
						var svg = d3.select("svg");

						let start = moment().subtract(timeRange, 'minutes').valueOf();
						let end = moment().valueOf();

            x.domain([start, end]);
            xAxis.scale(x);
                
            //move the xaxis left
            svg.select(".x_axis")
              .transition()
              .duration(100)
              .ease(d3.easeLinear)
              .call(xAxis);
					});
	    }
    }
});
function showData(d) {
	console.log("Start Date: " + moment(d.start_date).format());
	console.log("End Date: " + moment(d.end_date).format());
  console.log('CO: ', d.chip)
  console.log('************************* ')
}

Open in new window

Dawn

ASKER
Ok, I'll keep this simple :) In the code below (and fiddle here: https://jsfiddle.net/dtepdc/qcvrh5ez/), I'm simply trying to display the array items from "co_num" in the browser when the "incident" number matches "dataset.scene". The items are currently displayed, but entire blocks of items are displayed as opposed to one-by-one. I can see that this is because I still need to drill down into "co_num" and display those items as opposed to the entire array but that is where I'm getting stuck:

let dataset = [
    {
        "scene": "IR0006426320",
        "scene_start_time": "2018-02-05T15:03:30",
        "chips": [
            {
                "chip": "2018.02.05.150",
                "start_date": "2018-02-05T00:05:07",
                "end_date": "2018-02-05T01:26:23",
                "co_num":["None"],
                "cause": false
            },
            {
                "chip": "2018.02.05.192",
                "start_date": "2018-02-05T15:48:08",
                "end_date": "2018-02-05T17:22:34",
                "co_num": [
                    "C03619354",
                    "C03618763",
                    "C03619064",
                    "C03619325"
                ],
                "cause": false
          }   
     ]
   }
]
     

          let incident = "IR0006426320"
	       for (const x in dataset) {
		
                    if (incident === dataset[x].scene) {
                	for (const a in dataset[x].chips) {
                    $('.incidentInfo').append('<a class="dropdown-item" onclick="update()" href="#">' + dataset[x].chips[a].co_num  + '</a><br />');
                  }
                    
                }
            }
       

Open in new window

Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
ASKER CERTIFIED SOLUTION
Julian Hansen

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
Dawn

ASKER
Thank you so much! I can see how you did that in regards to the nested "co_num" array (as well as the more current javascript).
Julian Hansen

You are welcome - be aware that arrow functions have not gained full cross browser support status( i.e. that browser).
I used them for brevity but depending on the target environment you may need to downgrade them to the normal anonymous functions.
Dawn

ASKER
Will do, thanks again!
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Dawn

ASKER
Julian, I'm trying to remove duplicate items from within the rendered array.

For this block:

x.co_num.forEach(y => {

                            target.append($('<a>', {class: 'dropdown-item', href: '#'}).html(y).on('click', update));

Open in new window


I thought that I could use something like the code below but it's not working:

x.co_num.forEach(y => {
                                const deduped = [...new Set(y)];
                                
                            target.append($('<a>', {class: 'dropdown-item', href: '#'}).html(deduped).on('click', update));
                    });

Open in new window


Does "Set" need to happen before looping through "y"?
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Dawn

ASKER
Thank you! I realized I couldn't use Set with the code I had written since it was already a string. This makes total sense, thanks!