I have problem with getting value of a div with class="idC". I need this value to remove object from my array. I know I probably gonna need to use parseInt but all I'm getting with this code is rowid: undefined when I use console.log("rowid: " + bikeId.value). bikeRow.remove(); works fine. It removes the row I want to.
const buttonDel = document.querySelectorAll(".deleteC");
buttonDel.forEach(button => {
console.log("jazda");
button.addEventListener('click', () => {
const bikeRow = button.parentNode;
const bikeId = bikeRow.firstChild;
if (!window.confirm())
return;
console.log("rowid: " + bikeId.value);
bikeRow.remove();
//bikeStorage.removeBike(bikeId.value);
})
})
<div class="bikeRows">
<div class="bikeRow">
<div class="idC"></div>${bike.id}</div>
<div class="frameC">${bike.frame}</div>
<div class="suspC">${bike.susp}</div>
<div class="wheelC">${bike.wheel}</div>
<div class="typeC">${bike.constructor.name}</div>
<div class="deleteC"><button class="delButton" id="${bike.id}">Delete</button></div>
</div>
</div>
You have invalid HTML and you really should delegate
I added the ID as a data-attribute to the row like this
<div class="bikeRow" data-id="${bike.id}">
Makes the code much simpler to debug and extend
document.querySelector(".bikeRows").addEventListener("click", e => {
const tgt = e.target.closest("button");
if (!tgt.matches(".delButton")) return; // not a delete button
if (!window.confirm("Sure?")) return; // they cancelled
const bikeRow = tgt.closest("div.bikeRow"),
id = bikeRow.dataset.id; // the ID to remove from the storage
bikeRow.remove();
//bikeStorage.removeBike(id);
})
<div class="bikeRows">
<div class="bikeRow" data-id="ID1">
<div class="idC">ID1</div>
<div class="frameC">Frame 1</div>
<div class="suspC">Susp 1</div>
<div class="wheelC">Wheel 1</div>
<div class="typeC">Constructor name 1</div>
<div class="deleteC"><button class="delButton">Delete</button></div>
</div>
<div class="bikeRow" data-id="ID2">
<div class="idC">ID 2</div>
<div class="frameC">Frame 2</div>
<div class="suspC">Susp 2</div>
<div class="wheelC">Wheel 2</div>
<div class="typeC">Constructor name 2</div>
<div class="deleteC"><button class="delButton">Delete</button></div>
</div>
<div class="bikeRow" data-id="ID3">
<div class="idC">ID 3</div>
<div class="frameC">Frame 3</div>
<div class="suspC">Susp 3</div>
<div class="wheelC">Wheel 3</div>
<div class="typeC">Constructor name 3</div>
<div class="deleteC"><button class="delButton">Delete</button></div>
</div>
</div>
Related
How do you remove any duplicate childNodes from a parent element so that there is never more than 1 element with the same innerText within the parent? HTML example below of what the before and the intended after is.
HTML
<div id="parent">
<div class="child">hello</div>
<div class="child">hello</div>
<div class="child">world</div>
<div class="child">world</div>
</div>
Goal
<div id="parent">
<div class="child">hello</div>
<div class="child">world</div>
</div>
Try this.
var children = document.querySelectorAll(".child")
var tmpTexts = []
for (const c of children) {
if (tmpTexts.includes(c.innerText)) continue
tmpTexts.push(c.innerText)
c.parentNode.removeChild(c)
}
<div id="parent">
<div class="child">hello</div>
<div class="child">hello</div>
<div class="child">world</div>
<div class="child">world</div>
</div>
Here’s another way of doing it:
const children = document.querySelectorAll('.child');
function filterChildren(text, i, textArray) {
if ( textArray.indexOf(text) <= textArray.lastIndexOf(text) && textArray.indexOf(text) !== i ) {
children[i].parentNode.removeChild( children[i] )
}
}
Array
.from(children)
.map( child => child.innerHTML )
.forEach(filterChildren);
<div id="parent">
<div class="child">hello</div>
<div class="child">hello</div>
<div class="child">world</div>
<div class="child">world</div>
</div>
I would like to sort a few divs in ascending order based on their data-id. How can I do that?
<div class="container" data-id="1000">
<div id="H1"></div>
<div id="sub">sub 1</div>
<div id="sub">sub 2</div>
</div>
<div class="container" data-id="3000">
<div id="H1"></div>
<div id="sub"></div>
<div id="sub"></div>
</div>
<div class="container" data-id="2000">
<div id="H1"></div>
<div id="sub"></div>
<div id="sub"></div>
</div>
I've found the solution to my problem a while ago:
function sortOut() {
// get the classname chapcontainer
var classname = document.getElementsByClassName('container');
// create a variable and put the classes it into an array.
var divs = [];
for (var i = 0; i < classname.length; ++i) {
divs.push(classname[i]);
}
// Sort the divs based on data-id.
divs.sort(function(a, b) {
return +a.getAttribute("data-id") - +b.getAttribute("data-id");
});
};
divs.sort does the trick. More info about this function can be found here:
https://www.w3schools.com/jsref/jsref_sort.asp
I'm trying to toggle a div's class in pure javascript (unfortunately I cannot use jQuery). I've got some code working but it doesn't work for multiple instances of the div and I'd appreciate some help for that.
I can't give each element it's own specific ID, so I'd need a way to target only the div with a class of 'truncate' that is the parent of the particular button that is clicked. Currently I have hidden the results by default and am just toggling the 'show' class
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div id="button">Show more</div>
</div>
collapse= document.getElementById('button');
collapse.onclick = function() {
collapse.parentElement.classList.toggle("show");
};
/* HIDE PLATES BY DEFAULT */
.truncate .result {
display: none;
}
/* SHOW RESULTS WHEN SHOW CLASS APPLIED */
.truncate.show .result {
display: block !important;
}
Thank you - help appreciated as always.
I think you need getElementsByClassName
(function() {
var collapse = document.getElementsByClassName('button');
for (var elIndex = 0; elIndex < collapse.length; elIndex++) {
collapse[elIndex].onclick = function() {
this.parentElement.classList.toggle("show");
};
}
})();
/* HIDE PLATES BY DEFAULT */
.truncate .result {
display: none;
}
/* SHOW RESULTS WHEN SHOW CLASS APPLIED */
.truncate.show .result {
display: block !important;
}
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div class="button">Show more</div>
</div>
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div class="button">Show more</div>
</div>
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<div class="button">Show more</div>
</div>
You should replace the id of Show more to class.
And use the following code.
collapse =document.getElementsByClassName('button');
for(let i = 0; i < collapse.length; i++){
let oneElement = collapse[i];
oneElement.addEventListener('click', function() {
oneElement.parentElement.classList.toggle("show");
})
}
Parse (loop over) all of your div.truncate elements and give themselves their own functionality via the Accordionize Function.
const Accordionize = el => {
const results = el.querySelectorAll('.result')
const toggleButton = el.querySelector('button')
let open = false
const _toggle = () => {
const action = open ? 'remove' : 'add'
results.forEach(item => item.classList[action]('show'))
open = !open
}
toggleButton.addEventListener('click', _toggle)
}
// get all div.truncate and apply them to their own instance of Accordionize
document.querySelectorAll('.truncate').forEach(Accordionize)
.truncate {
border: 2px solid red;
margin: 5
}
.result {
display: none;
}
.show {
display: block
}
<div class="truncate">
<div class="result">Result 1</div>
<div class="result">Result 2</div>
<button>Show more1</button>
</div>
<div class="truncate">
<div class="result">Result 3</div>
<div class="result">Result 4</div>
<button>Show more2</button>
</div>
<div class="truncate">
<div class="result">Result 5</div>
<div class="result">Result 6</div>
<button>Show more3</button>
</div>
<div class="truncate">
<div class="result">Result 7</div>
<div class="result">Result 8</div>
<button>Show more4</button>
</div>
I have an array of items, 9 be exact attached to my state:
state = {
menuItems: [
{
id: 0,
name: 'Foods',
iconSrc: 'food.jpg'
},
{
id: 1,
name: 'Drinks',
iconSrc: 'drinks.jpg'
},
{
id: 2,
name: 'Snacks',
iconSrc: 'snacks.jpg'
}
]
and want to loop over them, however i have 9 items in the array and want to do the following: group every three items in the array under a new div, like so:
<div class="row-container">
<div class="col-4">
<div class="col-2">Item 1</div>
<div class="col-2">Item 2</div>
<div class="col-2">Item 3</div>
</div>
<div class="col-4">
<div class="col-2">Item 4</div>
<div class="col-2">Item 5</div>
<div class="col-2">Item 6</div>
</div>
<div class="col-4">
<div class="col-2">Item 7</div>
<div class="col-2">Item 8</div>
<div class="col-2">Item 9</div>
</div>
</div>
How do I achieve that using the map function within React?
You can get use of modulus(Reminder). Modulus will tell you the reminder of the division for given integer.
The remainder operator returns the remainder left over when one
operand is divided by a second operand. It always takes the sign of
the dividend, not the divisor. It uses a built-in modulo function to
produce the result, which is the integer remainder of dividing var1
by var2
Example
this.state.menuItems.map((item, index) => {
if (((index + 1) % 3) === 1) {
return (
<div className="col-4">
<div className="col-2">{item.name}</div>
);
} else if (((index + 1) % 3) === 2) {
return (<div className="col-2">{item.name}</div>);
} else if (((index + 1) % 3) === 0) {
return (
<div className="col-2">{item.name}</div>
</div>
);
}
});
You can try to transform the array into subset of arrays containing three elements and then map them to spit what you want.
Look here for an example Split array into chunks of N length
If i understand your question correctly, this should work, let me know if this is what you meant please
renderMenuItems() {
let items = this.state.menuItems.map((item, index) => {
return (
<div class="col-4" key={item.id}>
<div class="col-2">{item.id}</div>
<div class="col-2">{item.name}</div>
<div class="col-2">{item.iconSrc}</div>
</div>
);
});
return items;
}
Then inside of your render:
<div class="row-container">
{this.renderMenuItems()}
</div>
This would create:
<div class="row-container">
<div class="col-4">
<div class="col-2">0</div>
<div class="col-2">Foods</div>
<div class="col-2">food.jpg</div>
</div>
<div class="col-4">
<div class="col-2">1</div>
<div class="col-2">Drinks</div>
<div class="col-2">drinks.jpg</div>
</div>
<div class="col-4">
<div class="col-2">2</div>
<div class="col-2">Snacks</div>
<div class="col-2">snacks.jpg</div>
</div>
</div>
I need to sort items that are within div with the same id and class. I have problems to return the value of tkEmail tag. I can not get the value.
example:
item 1
Order: 0 Value: 1
HTML:
<div id="sortable">
<div class='sortear' tkEmail='1'>Item 1</div>
<div class='sortear' tkEmail='2'>Item 2</div>
</div>
<br>
<div id="sortable">
<div class='sortear' tkEmail='3'>Item 3</div>
<div class='sortear' tkEmail='4'>Item 4</div>
</div>
JS:
$(document).ready(function () {
$('div#sortable').sortable({
update: function () { novaOrdem() },
});
});
function novaOrdem(){
$('div#sortable').each(function (i) {
alert($(this).attr('tkEmail'))
});
}
Ids have to be unique and you're not actually checking the child divs in the call to each. $('div#sortable').children() will get you what you want. Also, tkEmail is not valid and it would be better practice to use a data attribute e.g. data-tk-email:
HTML:
<div id="sortable">
<div class='sortear' data-tk-email='1'>Item 1</div>
<div class='sortear' data-tk-email='2'>Item 2</div>
<div class='sortear' data-tk-email='3'>Item 3</div>
<div class='sortear' data-tk-email='4'>Item 4</div>
</div>
JQuery:
$(document).ready(function() {
$('div#sortable').sortable({
update: function() {
novaOrdem()
},
});
});
function novaOrdem() {
var items = $('div#sortable').children();
$.each(items, function() {
alert($(this).html() + ', Order: ' + $(this).index() + ', Value: ' + $(this).data('tkEmail'))
});
}
Fiddle Demo