Combining two different JavaScript functions to get JSON sibling data - javascript

I have two function.
One- that on 'Click' gets the id value.
second- gets the sibling data from an id.
I want to combine the two functions, so when i click a div, get that 'id' and display the sibling data from JSON
//this returns sibling data from JSON with id=2
const result = characters.find(item => {
// if this returns `true` then the currently
// iterated item is the one found
return item.id === 2
});
console.log(result);
//this allows me to click the different divs to get their id
var divs = document.querySelectorAll(".characterBox");
for(var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', function (event) {
console.log(this.getAttribute("id"));
});
}

You can put the logic directly into the anonymous function and use this.getAttribute("id") instead 2
var divs = document.querySelectorAll(".characterBox");
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', function(event) {
const result = characters.find(item => {
return item.id == this.getAttribute("id")
});
console.log(result);
});
}

Related

How to loop through and display buttons that have an onClick and pass a different variable to another function?

I have the following ReactJS code which I am using to render a number of buttons which will allow the user to navigate around the data returned from an API (a bunch of paginated images).
I have the multiple buttons displaying but they send i as 19 (the end value in the loop) to the handlePageClick() function.
How can I get the value of i to be passed to my handlePageClick() function?
handlePageClick( button ) {
console.log( button );
this.setState( prevState => {
return {
currentPage: button
}
}, () => {
this.loadMedia();
});
}
render() {
// figure out number of pages
const mediaButtonsNeeded = parseInt( this.state.totalMedia / this.state.perPage )
var mediaButtons = [];
for (var i = 0; i < mediaButtonsNeeded; i++) {
mediaButtons.push(<button onClick={() => this.handlePageClick(i)}>{i}</button>);
}
return (
<div>
<div>
<h1>Media test</h1>
{media}
{mediaButtons}
</div>
</div>
)
Since var is global scope variable declaration, your loop always rewrite i to next value.
Easiest solution is just replacing from var to let.
for (let i = 0; i < mediaButtonsNeeded; i++) {// your code...
This should work:
for (var i = 0; i < mediaButtonsNeeded; i++) {
mediaButtons.push(<button onClick={() => this.handlePageClick(i+"")}>{i}</button>);
}

How to grab variables from a function ? Specifically an array

If there is an array in a function, and I would like to grab one value out of this array, depending if it exists or not, how would I do that with JavaScript?
To explain this question well look at the code below . . .
If we have a function:
function updateData(dataObj) {
for (var i = 0; i < dataObj.length; i++) {
var id = dataObj[i]['id'];
}
grabID(dataObj);
}
I am trying to grab whichever id that has a value, so I created the function grabID:
function grabID(dataObj) {
for (var i=0; i< dataObj.length; i++) {
var id = dataObj[i]['id'];
if (typeof(id) == 'string') {
//take that id and use it in the function below this one
}
else {
continue;
}
}
}
Now this is the function that I want to place the id in, so I can draw a graph:
function drawGraph() {
var id = //the id grabbed in the grabID function
//use this id for drawing purposes
}
So the only help I need is how can I bring this id string from the grabID function. The parts that are commented are the parts that I need help with.
I hope this code helped explained what I am looking for exactly. I know I might have wrote unnecessary functions or lines of code, but this is the way I am thinking of in my head right now. The function updateData is not initially used to grab one id only (the id that has value). That is why I created another function called grabID.
You can call the grabID function and within it return the ID, then pass the result of the call to your drawGraph function:
function grabID(dataObj) {
for(var i=0; i< dataObj.length; i++)
{
var id = dataObj[i]['id'];
if(typeof(id) == 'string')
//take that id and use it in the function below this one
return id;
else
continue;
}
// return null if no ID was retrieved
return null;
}
function updateData(dataObj) {
for (var i = 0; i < dataObj.length; i++) {
var id = dataObj[i]['id'];
}
var id = grabID(dataObj);
if(id !== null) drawGraph(id);
}
function drawGraph(grabbedId)
{
var id = grabbedId; //the id grabbed in the grabID function
//use this id for drawing purposes
}
Try calling drawGraph from within your grabID function, like so. Use the id variable as a parameter to drawGraph.
function grabID(dataObj) {
for(var i=0; i< dataObj.length; i++){
var id = dataObj[i]['id'];
if(typeof(id) == 'string')
drawGraph(id)
else
continue;
}
}
}
function drawGraph()
{
var id = //the id grabbed in the grabID function
//use this id for drawing purposes
}

jQuery append issue without removing original elements

I just wrote some code for practicing my jQuery. When I wrote this code, I found out it works fine with only using append() and without removing any original tr elements in the table. How does it work — could someone explain it to me? here is the complete code. Thanks!
Here is my jQuery code:
$(document).ready(function () {
var list = a();
var last = $('#table').find("tr").length;
$('#table').find("tr").each(function (index, element) {
$(this).prepend($("<button/>").text("↑").bind('click', function () {
up($(this).parent(), last);
}));
$(this).prepend($("<button/>").text("↓").bind('click', function () {
down($(this).parent(), last);
}));
});
$('#table').before($('<button />').text("reset").on('click', function () {
reset(list);
}));
});
function up(tr, last) {
if (0 != tr.index()) {
var prevTr = tr.prev();
tr.after(prevTr);
}
}
function down(tr, last) {
if (last - 1 != tr.index()) {
var nextTr = tr.next();
tr.before(nextTr);
}
}
var reset = function (list) {
for (var i = 0; i < list.length; i++) {
$("#table").append(list[i]);
}
};
var a = function () {
var list = [];
$('#table tr').each(function () {
list.push($(this));
});
return list;
};
Be aware, appending already existing element just move it. I guess maybe you want to clone it:
jsFiddle
var reset = function (list) {
for (var i = 0; i < list.length; i++) {
$("#table").append(list[i].clone(true));
}
};
But then, reset function is misnamed...
$(document).ready(function () {
waits for the page and all elements to be loaded
var list = a();
var last = $('#table').find("tr").length;
sets up specific variables, in this case list is the function a() defined later in the page and last gets the length of the last tr in the table.
$('#table').find("tr").each(function (index, element) {
sets up a loop through each tr element on in the table with id #table
$(this).prepend($("<button/>").text("↑").bind('click', function () {
up($(this).parent(), last);
}));
Because you are inside the loop, $(this) represents the tr that the loop is currently on. It then prepends a button and adds a click listener on this button. When the button is pressed, it will call the function up, which is defined later on, with the buttons parent as the first parameter and last (defined earlier) as the second
$(this).prepend($("<button/>").text("↓").bind('click', function () {
down($(this).parent(), last);
}));
This adds another button, but calls down() instead of up()
});
End of the loop.
$('#table').before($('<button />').text("reset").on('click', function () {
reset(list);
}));
This adds a button before the table that when clicked calls the reset function with list as the only parameter, list is set to a().
});
function up(tr, last) {
if (0 != tr.index()) {
var prevTr = tr.prev();
tr.after(prevTr);
}
}
This function is called when moving an item up, it first checks to see if the index is not 0 (so not the first element as this couldn't be moved up) if it is not then it puts the previous tr after the variable tr. Which in this case is the parent to the button (or the current tr)
function down(tr, last) {
if (last - 1 != tr.index()) {
var nextTr = tr.next();
tr.before(nextTr);
}
}
Works exactly the same as the function above, but in the opposite direction.
var reset = function (list) {
for (var i = 0; i < list.length; i++) {
$("#table").append(list[i]);
}
};
This function is saved in the variable reset, it loops through each tr (defined in a()) and appends it to the table,
var a = function () {
var list = [];
$('#table tr').each(function () {
list.push($(this));
});
return list;
};
This function creates and returns an array which loops through each tr and adds to that array. So we know the original state and can return to it.

store value in JSON on button click

I am new in JSON, i am trying to save data using JSON. I have a list of element with some button when we click the button i want the corresponding value of button are save in JSON. I am also want to compare the title with already exists in JSON.
Demo Here
You can simply use a for loop to check if the element with that title is already there:
function alreadyAdded(itemTitle) {
for (var i = 0; i < objArray.length; i++) {
if (objArray[i].title === itemTitle) {
return true;
}
}
return false;
};
Also, you are not using a json object, just a JavaScript array.
Demo
try this
http://jsfiddle.net/Z3v4g/
var counter = 0;
var jsonObj = []; //declare object
$('.imgbtn').click(function () {
var title = $(this).parent().parent().find('span').html();
var image = $(this).parent().parent().find('img').prop('src');
for( var i=0; i<jsonObj.length; i++){
if( jsonObj[i].title == title ) return false;
};
counter++;
$('#lblCart').html(counter);
jsonObj.push({
id: counter,
title: title,
image: image,
description: 'Example'
});
});
I am assuming you want to store values in an array, and during a button click you want to check if the item already exists in the array. If this is true, then you can use the following code -
var counter = 0;
var jsonObj = []; //declare object
$('.imgbtn').click(function () {
var title = $(this).parent().parent().find('span').html();
var image = $(this).parent().parent().find('img').prop('src');
var match = $.grep(jsonObj, function (e) {
return e.title == title;
});
if (match.length > 0) {
// This title already exists in the object.
// Do whatever you want. I am simply returning.
return;
}
counter++;
$('#lblCart').html(counter);
jsonObj.push({
id: counter,
title: title,
image: image,
description: 'Example'
});
});
Notice that I have declared the array outside the callback function. This ensures that all the invocation of the callback operate on the same array object. Declaring it inside the callback was only making it available for a single callback invocation.
Also note that you are simply using an array to store plain JavaScript Objects.
Demo.
First:
var jsonObj = []; //declare object
This is not a JSON. This is an Array. JSON is just the notation of Javascript Object. To declare a object you should do:
var jsonObj = {};
or:
var jsonObj = new Object();
After this, you can approach what you asked doing this:
var counter = 0;
var jsonObj = new Object();
$('.imgbtn').click(function () {
var title = $(this).parent().parent().find('span').html();
var image = $(this).parent().parent().find('img').prop('src');
if (!(title in jsonObj)) { // if item is not in the object, (title in jsonObj) returns true of false
jsonObj[title] = { // When you have hundreds of items, this approach is way faster then using FOR loop, and if you need to alter the item or get one value, you can just call it by name: jsonObj['ABC'].image will return the path of the image
id: counter,
image: image,
description: 'Example'
}
counter++;
$('#lblCart').html(counter);
} else {
// Do what you want if the item is already in the list
alert('Item already in the list');
console.log(jsonObj[title]);
}
});
DON'T use FOR loops to do what you wan't, it will just slow down your application if the counter gets high.

Duplicating JQuery/Javascript functions

I have a jquery/javascript function that creates an array to be placed in a form's hidden field. However, this is a nested form and so I need to invoke this function many times to populate the hidden field for all the children: test_suite_run[test_runs_attributes][//id][packages_id]. This means that I need to run this function with a different child id each time.
I have added //id to indicate the only differences between the many function calls. I do not know how to duplicate this function without copying it many times manually and replacing //id with the indexes 0...n, for each nested child instance. Could this somehow be done by passing parameters to the javascript function?
Sorry if this a little confusing, I will be happy to explain in more detail if needed.
JQuery Function
$(document).ready(function () {
arr = new Array();
$(document).on('change', 'select[id ^="s_package//id"]', function () {
var arr = $('select[id ^="s_package//id"]').map(function () {
return this.value
})
result = ""
for (j = 0; j < arr.length - 1; j++) {
result += (arr[j] + ", ");
}
result += (arr[arr.length - 1])
$("input[name='test_suite_run[test_runs_attributes][//id][packages_id]']").val(result);
});
});
You can pass an array of ids to use in your function and iterate them:
function somethingMeaningful(ids) {
for (var i = 0, l = ids.length; i < l; i++) {
var id = ids[i];
// do something with this id
}
}
$(function() {
somethingMeaningful(['id1', 'id2', 'idn']);
});
It might also be possible to simplify your selector and calculate the id at runtime, depending on their actual format:
$(document).on('change', 'select[id^="s_package"]', function () {
var id = $(this).attr('id').slice('s_package'.length);
// Do stuff with real id
});

Categories

Resources