Append elements with childs and classes using jQuery - javascript

I'm trying to create a grid table using jQuery.
So instend of adding those elements into html page:
<div id="grid" class="gridTable">
<div class="row">
<span class="cell head"></span>
<span class="cell head"></span>
<span class="cell head"></span>
</div>
<div class="row">
<span class="cell"></span>
<span class="cell"></span>
<span class="cell"></span>
</div>
<div class="row">
<span class="cell"></span>
<span class="cell"></span>
<span class="cell"></span>
</div>
<div class="row">
<span class="cell"></span>
<span class="cell"></span>
<span class="cell"></span>
</div>
</div>
I want to add only the grid container:
<div id="grid" class="gridTable"><div>
and inside of this container to add my rows dynamically using jQuery append() or other method:
<div class="row">
<span class="cell head"></span>
<span class="cell head"></span>
<span class="cell head"></span>
</div>
repeating each time I want. I have tried something like:
$('.gridTable').append( $("<div></div>").addClass('row') );
but I don't know how to add .cell child of appended elements.
See full html code in fiddle:

Store appended element in variable and use it after append. To do this work, you need to write new element in selector and use .appendTo() to appending element.
var row = $('<div></div>').addClass("row").appendTo(".gridTable");
row.append("<span class='cell head'>col</span");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="grid" class="gridTable"></div>
If you want to create all row and column of table dynamicaly, see bottom code.
for (var i = 0; i < 4; i++){
var row = $('<div></div>').addClass("row").appendTo(".gridTable");
for (var j = 0; j < 3; j++){
if (i == 0)
row.append("<span class='cell head'>head</span");
else
row.append("<span class='cell'>col</span");
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="grid" class="gridTable"></div>

You can create a function that returns a row object with specified number of cells and call it for each row:
TIP:
Adjust the function as you like (e.g. It can take a parameter for cell classes)
var grid = $('#grid');
/**
* Returns a jQuery object of a row
* param cells {number} The number of cells
*/
function getRow(cells, customClass) {
var c = '';
for (var i=0;i<cells;i++) {
c += '<span class="cell ' + customClass + '">Cell</span>';
}
var row = $('<div class="row">' + c + '</div>');
return row;
}
// Add 5 rows
var rows = 5;
for (var r=1;r<=rows;r++) {
var customClass = (r == 1) ? 'head' : '';
grid.append(getRow(3, customClass));
}
.cell {
display:inline-block;
padding:5px 10px;
border:1px solid #d8d8d8;
}
.head { font-weight:bold }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div id="grid" class="gridTable"></div>

Related

JavaScript, HTML search engine - how to get parent of an element?

My problem is:
Search script is working, but it only hides h3 elements from the code.
<h3 class="post-subtitle" style="display: flex;">Protokoły tunelowania VPN</h3>
<h3 class="post-subtitle" style="display: flex;">Certyfikat cyfrowy</h3>
I need the code to hide the whole div with "post" ID instead of just h3 element.
How do i do that?
HTML Code for Search Bar:
<div id="kontener" class="container">
<div style="text-align:center" id="search-bar">
<input type="text" id="searchbar" onkeyup="searchBar()" class="shadow-lg">
</div>
</div>
HTML Code on Website
<!-- First element -->
<div id="post">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
<a href="URL">
<h2 class="post-title"><i class="far fa-sticky-note fa-xs" aria-hidden="true"></i> ASO</h2>
<h3 class="post-subtitle" style="display: flex;">Protokoły tunelowania VPN</h3>
</a>
<p class="post-meta">11 Maj, 2021</p>
</div>
</div>
</div>
<hr>
</div>
<!-- End of First element -->
<!-- Second element -->
<div id="post">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
<a href="URL">
<h2 class="post-title"><i class="far fa-sticky-note fa-xs" aria-hidden="true"></i> ELSK</h2>
<h3 class="post-subtitle" style="display: flex;">Certyfikat cyfrowy</h3>
</a>
<p class="post-meta">26 Kwiecień, 2021</p>
</div>
</div>
</div>
<hr>
</div>
<!-- End of Second element -->
JavaScript code:
<script>
function searchBar() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('post-subtitle');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].style.display="none";
}
else {
x[i].style.display="flex";
}
}
}
</script>
You just need to target couple of parent nodes, either by .parentElement / .parentNode or use .closest function.
Example:
<script>
function searchBar() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('post-subtitle');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].closest('#post').style.display="none";
// Or this below (note each parentElement targets parent tag)
// x[i].parentElement.parentElement.parentElement.parentElement.parentElement.style.display="none";
}
else {
x[i].closest('#post').style.display="flex";
}
}
}
</script>

Jquery dynamically wrap bootstrap columns in rows

I have some code formatted as following:
<div id="section">
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
</div>
There can be any number (even or odd) of columns in this section.
What I want is for it to be re-formatted like this:
<div id="section">
<div class="row">
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
</div>
<div class="row">
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
</div>
<div class="row">
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
</div>
<div class="row">
<div class="col-xs-6"></div>
</div>
</div>
Here is my attempt to do so:
for (var x = 0; x < $('#section').children().length; x+=2) {
var firstSection = $('#section').children().eq(x);
if ($('#section').children().length >= x + 1) {
var secondSection = $('#section').children().eq(x + 1);
var finalSection = '<div class="row">' + firstSection.parent().html() + secondSection.parent().html() + '</div>';
secondSection.remove();
}
else {
var finalSection = '<div class="row">' + firstSection.html() + '</div>';
}
firstSection.remove();
$('#section').append(finalSection);
}
If anyone wants some extra fun, you could try allowing this to handle variable column widths as well! (Although I don't need that for my project).
Hers is an example that loops through the columns, similar to what you are attempting now.
It uses find(), append() and clone() to accomplish this task. As an added feature I wrapped it into a function that accepts the row size as an argument.
//breaks up the section into rows of size 'rowSize', 2 by default.
function breakitup(rowSize = 2) {
var $section = $("#section"); //get the section
var $row = $("<div class='row'>"); //make a template for a row
var cols = $section.find("div"); //get the columns
var working; //tmp variable for the current row
for (var i = 0; i < cols.length; i++) {
if (i % rowSize == 0) working = $row.clone(); //clone the template when appropriate
$(working).append(cols[i]); //add the column to the row
if ($(working).children().length == rowSize)
$section.append(working); //add the row to the section as appropriate
}
$section.append(working); //add the last row
}
//call our fancy function
breakitup();
.row {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="section">
<div class="col-xs-6">test</div>
<div class="col-xs-6">test2</div>
<div class="col-xs-6">test3</div>
<div class="col-xs-6">test4</div>
<div class="col-xs-6">test5</div>
<div class="col-xs-6">test6</div>
<div class="col-xs-6">test7</div>
</div>
You can use .wrapall(), .add() and :even selector:
$('#section > div:even').each(function(idx, ele) {
$(ele).add($(this).next()).wrapAll($('<div/>', {class: 'row'}));
});
console.log($('#section').html());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="section">
<div class="col-xs-6">1</div>
<div class="col-xs-6">2</div>
<div class="col-xs-6">3</div>
<div class="col-xs-6">4</div>
<div class="col-xs-6">5</div>
<div class="col-xs-6">6</div>
<div class="col-xs-6">7</div>
</div>

Why do I get undefined when I change from querySelector to querySelectorAll? [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 3 years ago.
When I change from querySelector to querySelectorAll I get undefined. I know that the spelling for the class name is correct. So, I posted the rest of the code assuming that there is something else that I must be missing.
//TAKES INPUT FORM AND PLACES TEXT ON CARD
var input1 = document.querySelector('.form1');
var input2 = document.querySelectorAll('.form2');
var textOnCard = document.getElementById('btn');
btn.addEventListener('click', function() {
document.getElementById('flashcard__front').innerHTML = input1.value
document.getElementById('flashcard__back').innerHTML = input2.value
});
//FUNCTION THAT ALLOWS CARD TO ROTATE
var flashcard = document.querySelector('.flashcard');
flashcard.addEventListener('click', function() {
flashcard.classList.toggle('flip');
});
//CREATES A NEW INPUT FIELD
var inputHtml = '<div class="container mt-5"><div class="row"><div class="col-lg-12 text-center"><form id="form" action=""><div><input type="text" class="form1">'+ ' ' + '<input type="text" class="form2">' + ' ' + '</div></form></div></div>'
var addInputField = document.getElementById('addInputField');
addInputField.addEventListener('click', function() {
textOnCard.insertAdjacentHTML("afterend", inputHtml)
});
//make array apppear on screen
var flashcardFront = [];
var flashcardBack = [];
var number = 0;
var rightArrow = document.getElementById('rightArrow');
var leftArrow = document.getElementById('leftArrow');
textOnCard.addEventListener('click', function(){
flashcardFront.push(input1.value);
flashcardBack.push(input2.value);
flashcard__front.innerHTML = flashcardFront[0];
flashcard__back.innerHTML = flashcardBack[0];
console.log(Array.from(input1));
})
rightArrow.addEventListener('click', function(){
if (number < flashcardFront.length - 1 && number < flashcardBack.length - 1){
number++;
} else {
number = 0
}
console.log(number);
document.getElementById('flashcard__front').innerHTML = flashcardFront[number];
document.getElementById('flashcard__back').innerHTML = flashcardBack[number];
});
leftArrow.addEventListener('click', function(){
if (number > flashcardFront.length && number > flashcardBack.length){
number--;
} else {
number = 0
}
console.log(number);
document.getElementById('flashcard__front').innerHTML = flashcardFront[number];
document.getElementById('flashcard__back').innerHTML = flashcardBack[number];
});
<div class="container mt-5">
<div class="row">
<div class="col-lg-12 text-center">
<input type="text" class="form1">
<input type="text" class="form2">
<button class="btn btn-primary text-center" id="btn">SUBMIT</button>
</div>
</div>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-lg-12 text-center">
<input type="text" class="form1">
<input type="text" class="form2">
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<button class="btn btn-primary" id="addInputField">ADD A NEW INPUT</button>
</div>
</div>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-lg-12">
<div class="flashcard">
<div class="flashcard__side flashcard__side--front">
<h1 id="flashcard__front" class="text-center m-3"></h1>
</div>
<div class="flashcard__side flashcard__side--back">
<h1 id="flashcard__back" class="text-center m-3"></h1>
</div>
</div>
</div>
</div>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-lg-12">
<h3 id="testField" class="pl-5"></h3>
</div>
</div>
<div class="row">
<div class="col-md-6">
<i class="fas fa-arrow-left" id="leftArrow"></i>
</div>
<div class="col-md-6">
<i class="fas fa-arrow-right" id="rightArrow"></i>
</div>
</div>
</div>
For context, I am trying to recreate the flashcard feature from quizlet.com for practice.
Because .querySelectorAll() returns a node-list (an array-like container object), not an individual node. So, this line:
var input2 = document.querySelectorAll('.form2');
Creates a collection of all the elements with a class of form2.
Later, when you do this:
document.getElementById('flashcard__back').innerHTML = input2.value
You are saying that you want to get the value of the collection, but the collection doesn't have a value property, individual nodes do, so the flashcard__back element gets .innerHTML of undefined.
You'll have to identify which node within the list you want by passing an index to the node-list and then you can work with properties/methods of nodes.

Creating simple new parent elements with incrementing class numbers without changing the HTML

I'm trying to create a few elements with class names to have a number on the end that increments by 1 for each new element. E.g. <div class='someClass1'></div>, then <div class='someClass2'></div>, <div class='someClass3'></div>, etc...
However, I can only get the child elements to have incrementing class names, e.g. <span class='0'>here</span>, <span class='1'>here</span>, <span class='2'>here</span>, etc, which is done by changing the inner HTML.
How can I get the parent 'someClass' to have incrementing class numbers? I tried newNode.classList.add("someClass + noAdded"); but returns a syntax error. Thanks for any help here - my code is as follows:
var testy = document.getElementById('testy'); // <div id='testy'></div>
var noAdded = 0;
function addToPage() {
var newNode = document.createElement("div"); // <div></div>
newNode.classList.add("someClass"); // <div class='someClass'></div>
newNode.innerHTML = '<span class="' + noAdded + '">here</span>'; // <span class='0'>here</span>
testy.appendChild(newNode); // <div id='testy'><span class='0'>here</span></div>
noAdded++;
}
addToPage();
addToPage();
addToPage();
Results in:
<div id="testy">
<div class="someClass">
<span class="0">here</span>
</div>
<div class="someClass">
<span class="1">here</span>
</div>
<div class="someClass">
<span class="2">here</span>
</div>
</div>
Concatenate the value of the variable noAdded to the string someClass.
Change
newNode.classList.add("someClass");
To
newNode.classList.add("someClass"+noAdded);
var testy = document.getElementById('testy'); // <div id='testy'></div>
var noAdded = 0;
function addToPage() {
var newNode = document.createElement("div"); // <div></div>
newNode.classList.add("someClass"+noAdded); // <div class='someClass'></div>
newNode.innerHTML = '<span class="' + noAdded + '">here</span>'; // <span class='0'>here</span>
testy.appendChild(newNode); // <div id='testy'><span class='0'>here</span></div>
noAdded++;
}
addToPage();
addToPage();
addToPage();
.someClass0{color:red;}
.someClass1{color:green;}
.someClass2{color:blue;}
<div id="testy">
</div>

How to re-arrange html elements order of display with javascript or jQuery?

I am trying to re-arrange the order of item based on a certain value that particular div or element holds for example here is the following snippet
$(document).ready(function() {
$("button").on("click", function() {
var spanElemenet = document.getElementsByClassName("rs");
var stringInp = [];
var numConv = [];
var sorted;
for (var counter = 0; counter < spanElemenet.length; counter++) {
stringInp[counter] = spanElemenet[counter].innerHTML;
}
numConv = stringInp.map(Number);
for (var i = 1; i < (spanElemenet.length); i++) {
for (var j = 0; j < (spanElemenet.length) - 1; j++) {
if (numConv[j] > numConv[j + 1]) {
sorted = numConv[j];
numConv[j] = numConv[j + 1];
numConv[j + 1] = sorted;
}
}
}
//This loop is just to display output of sorted list
for(var k = 0; k< spanElemenet.length;k++)
{
$("#output").append(numConv[k] + "<br>");
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="item">One : <span id="s1" class="rs">400</span></div>
<div class="item">Two : <span id="s2" class="rs">1200</span></div>
<div class="item">Three : <span id="s3" class="rs">5000</span></div>
<div class="item">Four : <span id="s4" class="rs">1096</span></div>
<div class="item">Five : <span id="s5" class="rs">99 </span></div>
</div>
<button>Re order me</button>
<div id="output">
</div>
Until now i am able to get value from HTML and sort them in ascending order the main part is to now display the whole elements inside container based on this order and also along with its div element
The O/P i am expecting would be like this :
<div id="container">
<div class="item">Five : <span id="s5" class="rs">99 </span></div>
<div class="item">One : <span id="s1" class="rs">400</span></div>
<div class="item">Four : <span id="s4" class="rs">1096</span></div>
<div class="item">Two : <span id="s2" class="rs">1200</span></div>
<div class="item">Three : <span id="s3" class="rs">5000</span></div>
</div>
<button>Re order me</button>
To do what you require you simply need to implement your own sort() logic on the .item elements, which reads and compares the text from their child .rs elements. Something like this:
$("button").on("click", function() {
$('#container .item').sort(function(a, b) {
return parseInt($(a).find('.rs').text(), 10) - parseInt($(b).find('.rs').text(), 10);
}).appendTo('#container');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="item">One : <span id="s1" class="rs">400</span></div>
<div class="item">Two : <span id="s2" class="rs">1200</span></div>
<div class="item">Three : <span id="s3" class="rs">5000</span></div>
<div class="item">Four : <span id="s4" class="rs">1096</span></div>
<div class="item">Five : <span id="s5" class="rs">99 </span></div>
</div>
<button>Re order me</button>

Categories

Resources