We help IT Professionals succeed at work.

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

Dawn
Dawn asked
on
94 Views
Last Modified: 2019-03-05
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

Comment
Watch Question

Author

Commented:
Will do...
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
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

Author

Commented:
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

CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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).
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
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.

Author

Commented:
Will do, thanks again!

Author

Commented:
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"?
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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!
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.