replace parent div from its div child - javascript

I need for help, how to change parent div from each child div i have html like bellow
<div id="parent1">
<div class="toParent3">
</div>
<div class="toParent2">
</div>
<div class="toParent4">
</div>
</div>
<div id="parent2">
//content
</div>
<div id="parent3">
//content
</div>
i want to do ,when the first load i wanna show only #parent1 and its child, and then when child's #parent1 is clicked, I want to change whole #parent1 to #parent2 and hide all div except #parent2

You can use append, this code is only for parent2 as per your example.
$('.toParent2').click(function(){
$('.parent2').append($('.toParent2'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent1">
<div class="toParent3">
Child to parent 3
</div>
<div class="toParent2">
Child to parent 2
</div>
<div class="toParent4">
Child to parent 4
</div>
</div>
<div class="parent2">
//content
</div>
<div class="parent3">
//content
</div>

here's a vanilla js solution that is a bit more generic.
let all = document.getElementsByClassName('movable');
function hideParents() {
Array.prototype.forEach.call(document.getElementsByClassName('_parent_'), (e) => {
e.classList.add('hidden');
});
}
Array.prototype.forEach.call(document.getElementsByClassName('toParent1'), (e) => {
console.log('lols', e.addEventListener);
e.addEventListener('click', () => {
hideParents();
Array.prototype.forEach.call(all, (e2) => {
setTimeout(() => {
const p = document.getElementById('parent1');
p.appendChild(e2);
p.classList.remove('hidden');
});
});
});
});
Array.prototype.forEach.call(document.getElementsByClassName('toParent2'), (e) => {
e.addEventListener('click', () => {
hideParents();
Array.prototype.forEach.call(all, (e2) => {
setTimeout(() => {
const p = document.getElementById('parent2');
p.appendChild(e2);
p.classList.remove('hidden');
});
});
});
});
Array.prototype.forEach.call(document.getElementsByClassName('toParent3'), (e) => {
e.addEventListener('click', () => {
hideParents();
Array.prototype.forEach.call(all, (e2) => {
setTimeout(() => {
const p = document.getElementById('parent3');
p.appendChild(e2);
p.classList.remove('hidden');
});
});
});
});
._parent_.hidden {
display: none;
}
<div class="_parent_" id="parent1">
I'm parent1
<div class="movable toParent3">To3
</div>
<div class="movable toParent2">To2
</div>
<div class="movable toParent1">To1
</div>
</div>
<div class="_parent_ hidden" id="parent2">
I'm parent2
</div>
<div class="_parent_ hidden" id="parent3">
I'm parent3
</div>
not that removing setTimeout() there's a glitch happening, the elements are moved correctly but the DOM is refreshed too early
here's another solution, that replaces the text of the parent instead of moving the children.

Related

How to manipulate div class on rendered element using map() javascript

How do I use javascript to add class=open into rendered <div class="card flex-row"> using map().
On the inspect element browser i see the reaction on click but that action didn't adding the determined class
Here is my code :
function fetchingData() {
fetch("http://localhost:3001/quote/sendquote")
.then((response) => {
if (!response.ok) {
throw Error;
}
return response.json();
})
.then((data) => {
console.log(data);
const rend = data.person
.map((data) => {
return `
<div class='card flex-row'>
<img src='https://png.pngtree.com/png-vector/20191023/ourlarge/pngtree-user-vector-icon-with-white-background-png-image_1849343.jpg' class='book'>
<div class='flex-column info'>
<div class='title' id="person">Dear ${data.frstname}</div>
<div class='author'></div>
<div class='hidden bottom summary'>
<input id="quote" type="text" value="">
</div>
</div>
<div class='flex-column group'>
<div class='members'>
<span class='current'>14</span> /
<span class='max'>30</span>
</div>
<div class='hidden bottom'>
<button class='simple'>Submit</button>
</div>
</div>
</div>`;
})
.join("");
console.log(rend);
document.querySelector(".center").insertAdjacentHTML("afterbegin", rend);
})
.catch((err) => {
console.log("rejected", err);
});
}
fetchingData();
<div class='container'>
<div class='center list flex-column'>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script>
let old = $(".card").get(0);
$(".card").click(function() {
if (old != null && $(old).hasClass("open")) $(old).toggleClass("open");
$(this).toggleClass("open");
old = this;
});
</script>
<script>
</script>

filtering category with detach()

Help me with detach () function.
I figured out how it works, but I need help in applying it, in my case now it deletes all the selected categories, but you need to do the opposite so that all categories except the selected one are deleted. Is it necessary to somehow put everything except the selected one into a class and use detach () or what is better?
html
<div class="blog-filter">
<div class="blog-filter_item active js-filter-blog-list" data-filter="all">All</div>
</div>
<div class="blog-filter-container">
<div class="container">
<h1 class="blog-filter-title">Choose Category</h1>
<div class="item-wrapper">
<div class="blog-filter_item active" data-filter="all">All</div>
#foreach($categories as $category)
<div class="blog-filter_item" data-filter=".category_{{$category->id}}">{{ $category->title }} ({{ $category->articles_count }})</div>
#endforeach
</div>
</div>
</div>
<div class="blog-list">
#foreach($articles as $article)
<div class="blog-article category_{{ $article->blog_category_id }}">
<h2 class="blog-article__title">{{ $article->title }}</h2>
</div>
#endforeach
</div>
js
var divs;
$('.blog-article').each(function(i){
$(this).data('initial-index', i);
});
document.querySelectorAll('.blog-filter_item').forEach(el => {
el.addEventListener('click', () => {
document
.querySelector('.blog-filter_item.active')
.classList.remove('active');
el.classList.add('active');
var dataFilter = $(el).attr('data-filter');
$(divs).appendTo('.blog-list').each(function(){
var oldIndex = $(this).data('initial-index');
$('.blog-article').eq(oldIndex).before(this);
});
divs = null;
if (dataFilter == 'all') {
$('.blog-article').show();
}
else {
divs = $(dataFilter).detach();
$('.blog-article').show();
}
});
});
Solution:
divs = $('.blog-article').not(dataFilter).detach();

OnClick() handler in map function is changing the state of all elements instead of only clicked element

I am creating a Next js site mcqs and answer.
Initially only questions are rendered with the title and options.
There is a button to show the answer of given question but when button is clicked it is changing the state of all elements in the map function instead of element that is clicked.
export default function Chapter({ chapter }) {
const [right, setRight] = useState(false)
function handleOnClick() {
setRight(!right)
}
<main className='main_q'>
<h1>{chapter.items[0].name}</h1>
{chapter.items[0].questions.items.map((question, index) => {
return (
<div key={question.id} className='question_container'>
<div className='question_q_t'>
<div className='question_q'>Q</div>
<div className='question_t'>
<Markdown>{question.title}</Markdown>
</div>
</div>
<div className='option_container'>
<div className='option_a_o'>
<div className='option_a'>A</div>
<div className='option_o'>
<Markdown>{question.optionA}</Markdown>
</div>
</div>
<div className='option_a_o'>
<div className='option_a'>B</div>
<div className='option_o'>
<Markdown>{question.optionB}</Markdown>
</div>
</div>
<div className='option_a_o'>
<div className='option_a'>C</div>
<div className='option_o'>
<Markdown>{question.optionC}</Markdown>
</div>
</div>
<div className='option_a_o'>
<div className='option_a'>D</div>
<div className='option_o'>
<Markdown>{question.optionD}</Markdown>
</div>
</div>
</div>
<a
className='solution_link'
target='_blank'
href={`/${question.chapter.subject.category.slug}/${question.chapter.subject.slug}/${question.chapter.slug}/${question.id}`}
>
See Solution
</a>
<button onClick={handleOnClick}>Answer</button>
{right && <div>{question.rightAnswer}</div>}
</div>
)
})}
</main>
}
Put each question div into its own component, and make a right state in that component:
const Question = ({ question }) => {
const [right, setRight] = useState(false)
return (
<div key={question.id} className='question_container'>
// etc
Or make an array of right states in the parent:
export default function Chapter({ chapter }) {
const qs = chapter.items[0].questions.items;
const [rights, setRights] = useState(qs.map(q => false));
const makeHandleClick = (i) => {
setRights(
rights.map((r, j) => j === i ? r : !r)
);
};
// ...
<button onClick={makeHandleClick(i)}>Answer</button>
{rights[i] && <div>{question.rightAnswer}</div>}

ReactJs, How can I add class name to Map of same divs

this is my code i'm trying to add a class on click to a clicked div but i have more than 1 div have the same classname so when i click to any
div the toggle class added to all divs not the one which i clicked what i want to know how can i specify the div which i want to add toggle class to it
Code:
const [isActive, setActive] = useState(false);
const toggleClass = () => {
setActive(!isActive)
console.log('sad')
}
return (
<div className="command_wrapper">
<div className="command_list">
{
Commands.map((item, index) => {
return (
<div className="command" >
<div className="command_face" onClick={toggleClass}>
<h1>{item.Command}</h1>
<p>{item.Description}</p>
</div>
<div className={isActive ? "command_body" : "disapper"}>
<div className="command_usage">
<h1>Usage</h1>
<p>{item.Usage}</p>
</div>
<div className="command_required">
<h1>Required Permissions</h1>
<p>{item.premissions}</p>
</div>
</div>
</div>
)
})
}
</div>
</div>
```
You can pass the item inside toggle function and verify if item passed is activated or just save the item clicked.
const [itemActive, setItemActive] = useState();
const toggleClass = (item) => {
setItemActive(item)
}
return (
<div className="command_wrapper">
<div className="command_list">
{
Commands.map((item, index) => {
return (
<div className="command" >
<div className="command_face" onClick={() => toggleClass(item)}>
<h1>{item.Command}</h1>
<p>{item.Description}</p>
</div>
<div className={item === itemActive ? "command_body" : "disapper"}>
<div className="command_usage">
<h1>Usage</h1>
<p>{item.Usage}</p>
</div>
<div className="command_required">
<h1>Required Permissions</h1>
<p>{item.premissions}</p>
</div>
</div>
</div>
)
})
}
</div>
</div>
```
If item has any unique property, you can save just then, like an ID or name. I think it will be better.
/*const [isActive, setActive] = useState(false);
const toggleClass = () => {
setActive(!isActive)
console.log('sad')
}*/
function handleClick(el){
//toggle the class which indicates selection ex. 'active'
el.classList.toggle('active');
//other stuff todo
}
return (
<div className="command_wrapper">
<div className="command_list">
{
Commands.map((item, index) => {
return (
<div className="command" >
//destruct event objet{event.target}
<div onClick={({target})=>handleClick(target)}>
<h1>{item.Command}</h1>
<p>{item.Description}</p>
</div>
....
...
</div>
)
})
}
</div>
</div>

on check checkbox hide/show div in view

I'm trying to show MeetingDiv when IsAnonymous is checked and when IsMeeting is checked, MeetingTextBox should be shown.
Tried .click, .change and live and nothing worked. I don't know where I'm wrong.
<div class="col-md-4 sidePad" >
#Html.Label("Is Anonymous")
#Html.CheckBoxFor(p => p.IsAnonymous, new { id = "CBAnonymous"})
</div>
<div class="col-md-6" id="MeetingDiv" style="display:none">
#Html.Label("Is Meeting")
#Html.CheckBoxFor(p => p.IsMeeting, new { id = "CBMeeting"})
</div>
<div class="col-md-6" id="MeetingTextBox" style="display:none">
#Html.Label("Meeting Name")
#Html.TextBoxFor(p => p.MeetingName, new { id = "TBMeetingName"})
</div>
<script>
$(function () {
$("#CBAnonymous").click(function () {
if ($(this).prop("checked")) {
$("#MeetingDiv").show();
} else {
$("#MeetingDiv").hide();
}
});
});
</script>
Try this
$('#CBAnonymous').change(function(){
if(this.checked)
$("#MeetingDiv").show();
else
$("#MeetingDiv").hide();

Categories