Remove parent and next-until Elements - javascript

I have a structure something like this:
<div class="list_wrapper">
<div class="row mainrow">
Main Row
Remove
</div>
<div class="row subrow">
Sub Row
</div>
<div class="row subrow">
Sub Row
</div>
<div class="row mainrow">
Main Row
Remove
</div>
<div class="row subrow">
Sub Row
</div>
</div>
Here, after mainrow, subrow can be inserted it is not mandatory. Now if I delete mainrow then its subsequent subrow should also be deleted, for that I'm trying this code but it is not working, current element which is list_remove_button on click deletes the closest mainrow but not the siblings subrow (of mainrow):
$('.list_wrapper').on('click', '.list_remove_button', function()
{
$(this).closest('div.row').remove();
$(this).children('.subrow').remove();
});

Once you get the closest .mainrow using .closest()
use .nextUntil() to get the next-siblings
and use .addBack() to add back the initial $main to the stack - before .remove()ing them all
$('.list_wrapper').on('click', '.list_remove_button', function() {
const $main = $(this).closest('.mainrow');
$main.nextUntil('.mainrow').addBack().remove();
});
<div class="list_wrapper">
<div class="row mainrow">
Main Row 1
Remove
</div>
<div class="row subrow">
Sub Row 1
</div>
<div class="row subrow">
Sub Row 1
</div>
<div class="row mainrow">
Main Row 2
Remove
</div>
<div class="row subrow">
Sub Row 2
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

Related

changing Div order in a div main container, javascript DOM manipulation

i want to move a div form the start to the end in a the same div:from 1-2-3 to 2-3-1
my code
const cards = document.querySelectorAll(".card");
const firstCard = document.querySelectorAll(".card")[0].innerHTML;
cards[0].remove();
document.getElementById("mainC").appendChild(firstCard);
<div id="mainC">
<div class="card"> 1 </div>
<div class="card"> 2 </div>
<div class="card"> 3 </div>
</div>
i want to move a div form the start to the end in a the same div:from 1-2-3 to 2-3-1
Based on your original code,we need to remove .innerHTML,then it will work
const cards = document.querySelectorAll(".card");
const firstCard = document.querySelectorAll(".card")[0];// remove .innerHTML and it will work
cards[0].remove();
document.getElementById("mainC").appendChild(firstCard);
<div id="mainC">
<div class="card"> 1 </div>
<div class="card"> 2 </div>
<div class="card"> 3 </div>
</div>
Another solution is to store the content into an array and change the array element order
let divs = []
document.querySelectorAll('#mainC .card').forEach(d =>{
divs.push(d.outerHTML)
})
divs.push(divs.shift())
document.querySelector('#mainC').innerHTML = divs.join('')
<div id="mainC">
<div class="card"> 1 </div>
<div class="card"> 2 </div>
<div class="card"> 3 </div>
</div>
you have used document.querySelectorAll(".card")[0].innerHTML which gives '1' which is not type "node" so it will give an error when appending as a child.
remove .innerHTML and it will work
here is an example that removes the first child and append it to the end.
const shuffle = () => {
const parent = document.querySelector("#mainContainer");
const childrens = [...parent.children];
parent.appendChild(childrens.splice(0,1)[0]);
};
<button type="button" onclick=shuffle()> suffel</button>
<div id="mainContainer">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
</div>

How to get the attribute value of the closest element

Here i have HTML structure and the same structure may repeat number of times with the same class names. what i'm trying to do is once i click on the .innerDiv i should be able to access the attr value of the .inid close to its parent element.
here is what i have tried, but its not working. i also tried adding the classname to the element i'm trying to get the value from. but its adding the class to all the element with .inid. how can i do this?
HTML
<div class="parent_div">
<div class="content-container">
<div class="second-most-innerdiv>
<div class="container-box">
<div class="innerDiv">Click here</div>
</div>
</div>
</div>
<div class="inid" data-attr="jkoadoas-Kjksjfks_skaj"></div>
</div>
<div class="parent_div">
<div class="content-container">
<div class="second-most-innerdiv>
<div class="container-box">
<div class="innerDiv">Click here</div>
</div>
</div>
</div>
<div class="inid" data-attr="jkoadoas-Kjksjfks_skaj"></div>
</div>
Jquery
$(this).on('click',function(){
$('.innerDiv').parents().find('.inid').addClass('testclass');
$('.innerDiv').parents().find('.inid').attr(data-attr);
});
To achieve expected result, use index of innerDiv and add class-testclass to element with class- inid
Find index of clicked innerDiv using index('.innerDiv)
Use that index to add class using eq
Add some sample css to testclass for testing
Syntax error in your code - closing quotes missing for class- second-most-innerdiv
Codepen - https://codepen.io/nagasai/pen/
working example
$('.innerDiv').on('click',function(){
$('.inid').eq($(this).index('.innerDiv')).addClass('testclass');
console.log($('.inid').eq($(this).index('.innerDiv')).attr('data-attr'))
});
.testclass{
background: red;
height: 10px;
width:10px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent_div">
<div class="content-container">
<div class="second-most-innerdiv">
<div class="container-box">
<div class="innerDiv">Click here</div>
</div>
</div>
</div>
<div class="inid" data-attr="jkoadoas-Kjksjfks_skaj"></div>
</div>
<div class="parent_div">
<div class="content-container">
<div class="second-most-innerdiv>
<div class="container-box">
<div class="innerDiv">Click here</div>
</div>
</div>
</div>
<div class="inid" data-attr="jkoadoas-Kjksjfks_skaj"></div>
</div>
Using JQuery closest() feature to find the parent div, then find the element with class "inid" within that parent element and get the value of the attribute.
$('.innerDiv').on('click',function(){
var inid = $(this).closest('.parent_div').find('.inid');
inid.addClass('testclass');
console.log('selected -> ' + inid.attr(data-attr));
});
Source: https://api.jquery.com/closest/

how to access correct tag through Jquery

There is a html page with a structure:
<div class="row sem">
<div class="subject"><h3>A</h3></div>
<div class="subject"><h3>B</h3></div>
</div>
<div class="row sem">
<div class="subject"><h3>C</h3></div>
<div class="subject"><h3>D</h3></div>
</div>
I have attached a hover event on the uppermost div with:
$(".row.sem").hover(function(){
//my code....
});
Now,when I hover on one of these divs,I want to access the inner content of only those h3 elements which are within my hovered div element.
For this,I tried:
var a = $(this).children(["h3"]);
for(ei in ee){
console.log(ei);
}
But,this printed much more stuff like fadein,fadeout,scroll....The this object does not contain the inner tags of the hovered div.
Please suggest what is wrong in this implementation.
Thanks.
.children() collects direct children elements while you're looking for h3. So you could use .find() method or even (more specific) .children('.subject').children('h3').
$(".row.sem").hover(function(){
// mouse enter
var a = $(this).find("h3");
a.each(function(){
console.log($(this).text());
});
}, function(){
// mouse leave
console.clear();
// ...
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row sem">
<div class="subject"><h3>A</h3></div>
<div class="subject"><h3>B</h3></div>
</div>
<div class="row sem">
<div class="subject"><h3>C</h3></div>
<div class="subject"><h3>D</h3></div>
</div>
see: https://api.jquery.com/children/
This will get the content of the h3 child elements of the .row.sem elements. You needed to get all the children of the div you are hovering over. You can access and modify the html content of these children with .html() and I suggest you look into that method.
$(".row.sem").hover(
function() {
console.log($(this).children().text());
}, function (){}
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row sem">
<div class="subject"><h3>A</h3></div>
<div class="subject"><h3>B</h3></div>
</div>
<div class="row sem">
<div class="subject"><h3>C</h3></div>
<div class="subject"><h3>D</h3></div>
</div>
Clear and simple.
$(".row.sem").hover(function() {
$(this).find("h3").each(function() {
console.log($(this).text());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row sem">
<div class="subject"><h3>A</h3></div>
<div class="subject"><h3>B</h3></div>
</div>
<div class="row sem">
<div class="subject"><h3>C</h3></div>
<div class="subject"><h3>D</h3></div>
</div>
If you check MDN documentation for in loop it says that it itarates over "enumerable properties".
Check this post also enumarable properties
Check this out.
$(".row.sem").hover(function(){
// i am list of all headers nested inside element with class "row" and "sem"
// elements(array)
var headers = $(this).find('h3');
// console first element's html from the array.
console.log($(headers[0]).html())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row sem">
<div class="subject"><h3>A</h3></div>
<div class="subject"><h3>B</h3></div>
</div>
<div class="row sem">
<div class="subject"><h3>C</h3></div>
<div class="subject"><h3>D</h3></div>
</div>

jQuery select closest child element by class

How would I use jQuery to get get the text from the rating selected div within the id=overall answer div?
I want to dynamically fetch the text "TESTING" from that div within the overall parent div.
<div class='answer' id="overall">
<div class='rating'>1</div>
<div class='rating'>2</div>
<div class='rating'>3</div>
<div class='rating'>4</div>
<div class='rating selected'>TESTING</div>
</div>
<div class='answer' id="effort">
<div class='rating'>1</div>
<div class='rating'>2</div>
<div class='rating'>3</div>
<div class='rating selected'>4</div>
<div class='rating'>TESTING</div>
</div>
I tried to do this and it is blank.
$(document.getElementById('overall')).find('.rating selected').text();
Your code would work but your selector is wrong. It would be...
$(document.getElementById('overall')).find('.rating.selected').text();
Notice the dot and no space between rating and selected.
However, I think you are over complicating things...
$('#overall .selected').text();
Example...
alert($('#overall .selected').text());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class='answer' id="overall">
<div class='rating'>1</div>
<div class='rating'>2</div>
<div class='rating'>3</div>
<div class='rating'>4</div>
<div class='rating selected'>TESTING - selected</div>
</div>
<div class='answer' id="effort">
<div class='rating'>1</div>
<div class='rating'>2</div>
<div class='rating'>3</div>
<div class='rating selected'>4</div>
<div class='rating'>TESTING - not selected</div>
</div>
$('#overall .rating.selected').html()

Unable to use $.after() to close a div tag

This problem is best illustrated by example:
http://jsbin.com/lavonexuse
The desired effect is for clicking "Insert Row" to insert a full-width row after the indicated column (indicated by the class .insertion-point). The problem I'm running into is that instead of closing the current row first, and starting a new one, it just embeds a new row within the main row.
How do I close out the current row after any given column, make a new row, close that one, then resume showing the "data" columns?
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item insertion-point">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
</div>
</div>
<button class="btn btn-primary insert-row">Insert Row</button>
</body>
</html>
CSS:
.item {
border: 1px solid #f00;
}
.pane {
background: #999;
height: 100px;
}
JavaScript:
$('.insert-row').on('click', function() {
code = '</div><!--end row--><div class="row"><div class="col-sm-12 pane"></div></div>';
$('.insertion-point').after(code);
});
EDIT:
The code string above probably should end with <div class="row"> to re-open the row. But I tried that and it still doesn't work.
The problem here is that visually it looks like my solution works. Though in reality, it's creating bad HTML.
Further explanation (I think this is hard to explain). Here is what's happening, and this is NOT what I want:
I need that inserted row to be at the same level as the row it was erroneously inserted into.
Desired HTML after jQuery manipulation
<div class="container">
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item insertion-point">
Data
</div>
</div>
<div class="row">
<div class="col-sm-12 pane"></div>
</div>
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
</div>
</div>
Further Ramblings
Maybe, since this is Bootstrap, there's some way I can use the grid system to have the same effect.
The code below should resolve your issue. Check out the code snippet and demo:
$('.insert-row').on('click', function() {
var row = $('<div/>',{class:"row"}),
code = '<!--end row--><div class="row"><div class="col-sm-12 pane">New</div></div>',
rest = $('.insertion-point').nextAll(),
dest = $('.insertion-point').closest('.row');
dest.after( row.append( rest ) ).after( code );
});
<script src="//code.jquery.com/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<div class="container">
<div class="row">
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item insertion-point">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
<div class="col-sm-4 item">
Data
</div>
</div>
</div>
<button class="btn btn-primary insert-row">Insert Row</button>
i worked out this four you: JsFiddle
$(document).ready(function() {
var firstRow = $('.row');
$('.insert-row').on('click', function() {
var code = $('<div/>', {clas: 'row'}).append($('<div/>', {class: "col-sm-12 pane"})),
row = $('<div/>', {class: 'row'}),
items = $('.insertion-point').nextAll();
row.append(items);
firstRow.after(row);
firstRow.after(code);
});
});
Update:
after seen the nextAll function by jQuery .. this will be much faster:
updated fiddle
I think what you need is appendTo which will append html onto the specified tag. In this case you want to append a div onto your row.
http://api.jquery.com/appendto/
Just get rid of the closing tag in the code variable and your code will work and be well formed
code = '</div><!--end row--><div class="row"><div class="col-sm-12 pane"></div></div>';
should be
code = '<div class="row"><div class="col-sm-12 pane"></div></div>';
Also you need to insert rows after / before other rows like so
$('.insert-row').on('click', function() {
code = '<div class="row"><div class="col-sm-12 pane"></div></div>';
$('.insertion-point').closest(".row").after(code);
});
The above code finds where you want to insert (which I changed to be an id selector since you want to insert after one unique element). However you want to find the closest parent element (or this one) that is a row so that you insert a row after that row. This way you can choose a row or a column to insert after and it will always insert a row after the closest row properly.
Lucky for you browsers are very forgiving when it comes to syntax errors in HTML. They will remove the initial closing tag (which is unnecessary) and use the rest of your HTML. But some browser may behave differently and that is what you have to be careful of.
You need to add a new row after the first by removing the elements after the insertion point and including them in the new row.
You can't treat the DOM like a text editor when inserting html.
$('.insert-row').on('click', function() {
var $insertEL=$('.insertion-point');
var code = '<div class="row"><div class="col-sm-12 pane"></div></div>';
/* create new row and append all siblings after insertion point element*/
var $newRow=$(code).append($insertEL.nextAll());
/* add new row to DOM*/
$insertEL.closest('.row').after($newRow);
});
DEMO
Got it!
Layout solved by using Bootstrap grid, very little jQuery DOM manipulation. I don't know why I didn't think of this earlier. Sheesh. I've been coding for hours non-stop, my brain is fried.
Solution: http://jsbin.com/zopiquzore
This is correct, yes?

Categories

Resources