I have a <div contenteditable> and 2 divs with contenteditable="false". When I set the cursor between them to add text, it does not let me. I want to be able to write text between them. I fix the poblem by adding a <span> </span>. But if I backspace, the <span> </span> can get deleted and get back to the same problem. If I do <span contenteditable="false"> </span> I won't be able to add texts.
How to fix that problem definitively?
Note: the codes inside the div#editable aren't static, they are dynamic. I(the user) can add a span, div, p, h1, any Html Element I want.
Code:
<div contenteditable>
<div contenteditable=false></div><div contenteditable=false></div>
</div>
Script:
this.divNew.children().each(function () {
var child = $(this);
if (!child.is("br")) {
child.after($("<span>").addClass("gvwb-span-empty-newline").append(" "));
}
});
$("#editable").children().each(function () {
var child = $(this);
if (!child.is("br")) {
child.after($("<span>").addClass("gvwb-span-empty-newline").append(" "));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editable" contenteditable style="border: 1px solid black;">
Hello world<br>
<div contenteditable="false" style="height: 10px; background: blue"></div><div contenteditable="false" style="height: 10px; background: red"></div>
Hello world 2 <br>
</div>
I suggest you an empty <div> in between the two non-editable.
Just set its height to 1em with CSS.
/*
$("#editable").children().each(function () {
var child = $(this);
if (!child.is("br")) {
child.after($("<span>").addClass("gvwb-span-empty-newline").append(" "));
}
});
*/
#editable>div:nth-of-type(2){
height:1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editable" contenteditable style="border: 1px solid black;">
Hello world<br>
<div contenteditable="false" style="height: 10px; background: blue"></div>
<div></div>
<div contenteditable="false" style="height: 10px; background: red"></div>
Hello world 2 <br>
</div>
Related
I want to make that when the user clicks onto the bordered container, the 'Name' text should show the container's name only and the 'Subject' text should show the container's subject only, but this code shows all the elements inside the container for the 'Name' and the 'Subject' too.
I mean there are two elements inside one container. One with class 'name' and one with the class 'subject'. When I click onto the bordered container I want to get the 'name' text's and write it into the element with the class resname. And the same thing with the subject. Any idea how to solve it?
var name = document.querySelectorAll('.name');
var gname = $('.resname');
var gsub = $('.ressubject');
$('.container').click(function() {
gname.text($(this).text());
gsub.text($(this).text());
});
.container {
border: 1px solid red;
cursor: pointer;
padding: 5px;
}
.resname, .ressubject {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header">
<span class="name">firstname</span>
</div>
<div class="body">
<span class="subject">firstsubject</span>
</div>
</div>
<br>
<div class="container">
<div class="header">
<span class="name">secondname</span>
</div>
<div class="body">
<span class="subject">secondsubject</span>
</div>
</div>
<hr><br>
<div class="result">
<span>Name: <span class="resname"></span></span><br>
<span>Subject: <span class="ressubject"></span></span>
</div>
is that what you want?
const container = document.querySelector('.container');
const output = document.querySelector('.output');
const outputItemName = output.querySelector('.output-item > span[data-name]');
const outputItemSubject = output.querySelector('.output-item > span[data-subject]');
container.addEventListener('click', (e) => {
const containerItem = e.target.closest('.container-item');
if (!containerItem) return;
const { name, subject } = containerItem.dataset;
outputItemName.innerText = name;
outputItemSubject.innerText = subject;
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container-inner>* {
margin-bottom: 16px;
}
.container-inner>*:last-of-type {
margin-bottom: 0;
}
.container-item {
padding: 8px;
border: 1px solid black;
cursor: pointer;
}
.output {
margin-top: 16px;
}
<div class="container">
<div class="container-inner">
<div class="container-item" data-name="First name" data-subject="First subject">
<div class="container-item-name">First name</div>
<div class="container-item-subject">First subject</div>
</div>
<div class="container-item" data-name="Second name" data-subject="Second subject">
<div class="container-item-name">Second name</div>
<div class="container-item-subject">Second subject</div>
</div>
</div>
</div>
<div class="output">
<div class="output-inner">
<div class="output-item">
<span>Name:</span>
<span data-name></span>
</div>
<div class="output-item">
<span>Subject:</span>
<span data-subject></span>
</div>
</div>
</div>
I have to make a set of buttons that appear and disappear.
How it is supposed to work:
I click on link 1 (link 2 is invisible at this point).
link 2 should then appear.
the problem here is there can be multiple elements of the same type with the same classes and I can't figure out how to distinguish between just showing the "link2"
that corresponds to the clicked "link1" without triggering the other "link2".
there is some code showing the progress I have made.
thank you in advance!
<style>
.hideaction{
visibility: hidden;
}
.showaction{
visibility: visible;
}
</style>
<script>
$(document).ready(function(){
$(".elem_action_showing").click(function(){
$(".elem_action_hiding").removeClass("hideaction").addClass("showaction");
});
</script>
</head>
<body>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
</body>
The solution should work irregardless of how many ".elem_card" and ".hideaction" elements are there.
The issue is because you're selecting all .elem_action_hiding elements. To fix this use DOM traversal to find only the one which is related to the .elem_action_showing which was clicked. Try this:
$(".elem_action_showing").click(function() {
$(this).closest('.elem_showing').prev().find(".elem_action_hiding").toggleClass("hideaction showaction");
});
.hideaction {
visibility: hidden;
}
.showaction {
visibility: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
Is there any way to modify DOM based on amount div after specific class?
For example, if I have a div with a class called row and after that I have 4 div elements. Is there a way to change these 4 div element class depending on how many div elements there are?
Code:
<div class="row">
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
</div>
Another example I have a div class row again, but this time I want 3 div elements after that, then I would want these div elements to have a class called col-1-of-3, not col-1-of-4. If I would have just 2 div elements after that then class col-1-of-2 and if just one div element then no class at all.:
Code:
<div class="row">
<div class="col-1-of-3">
some content
</div>
<div class="col-1-of-3">
some content
</div>
<div class="col-1-of-3">
some content
</div>
</div>
Also these div elements with classes called col-1-of-4, col-1-of-3 and col-1-of-2 have their own div elements inside them, but they should stay like they were.
Is it possible to achieve with JavaScript or PHP?
You would need to write conditional blocks to handle this if I'm understanding you correctly (wanting a JS or PHP solution).
Note: It goes without saying that a similar solution can be completed with a CSS-only approach, as outlined here: Can CSS detect the number of children an element has?
Here's an example (using jQuery) with 3 sets of row's, with varying children (2, 3, 4):
$(function() {
var $rows = $(".row");
$rows.each(function() {
$row = $(this);
var $children = $(">div", $row),
total = $children.size();
$children.addClass("col-1-of-" + total);
});
});
.row {
border: 1px solid #000;
margin: 10px;
}
.row > div {
margin: 10px;
}
.row .col-1-of-2 {
border: 1px solid #f00;
}
.row .col-1-of-3 {
border: 1px solid #0f0;
}
.row .col-1-of-4 {
border: 1px solid #00f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
</div>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
</div>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
</div>
When you run the snippet, you must inspect the elements. I've added borders so you can see the difference.
Theres a number of ways to achieve this. I'd maybe add another class name so you can easily identify groups of divs, and differentiate between parent and child divs. Does this help you get where you're going? Basically find the number of children in a row and then concatenate that number into the class name.
var x = document.getElementsByClassName('row')[0].childElementCount
var element = document.getElementsByClassName('row')[0];
element.classList.add(`col-1-of-${x}`);
.row {
width: 100%;
display:flex;
flex-grow: 1;
margin-bottom: 2px;
}
.col {
float:left;
background: rgba(255,0,0,.2);
text-align: center;
margin-right: 2px;
}
.col:first-child:nth-last-child(1),
.col:first-child:nth-last-child(1) ~ .col{
width: calc(100% / 1);
}
.col:first-child:nth-last-child(2),
.col:first-child:nth-last-child(2) ~ .col{
width: calc(100% / 2);
}
.col:first-child:nth-last-child(3),
.col:first-child:nth-last-child(3) ~ .col{
width: calc(100% / 3);
}
.col:first-child:nth-last-child(4),
.col:first-child:nth-last-child(4) ~ .col{
width: calc(100% / 4);
}
.col:first-child:nth-last-child(5),
.col:first-child:nth-last-child(5) ~ .col{
width: calc(100% / 5);
}
<div class="row">
<div class="col">1</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
</div>
so this is with float, can be used in a sass/scss mixin to create code automagically. there should be also a flex solution but i dont have it at hand at the moment
This must be very simple, but I still cannot figure it out... Below is an example and what I tried - all I want is to get the value of <a id="{value}".. after clicking on the <div class="text" DIV.
.h {
background: lightblue;
}
.pb {
display: inline-block
}
.cb {
clear: both
}
.text {
background: #ffc;
border: 1px solid #000
}
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m75813" href="#m75183">#</a></div>
</div>
<div class="text" onclick="alert(parentNode.parentElement.firstChild.childNodes[1].a.id);">
After clicking on the yellow background, the value from [a id="m75813"] (ie. 'm75813') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
As the element has an ID, you can just look it up by that ID. IDs have to be unique (but keep reading, I suspect you don't want to do that):
alert(document.getElementById('m75813').id);
.h {
background: lightblue;
}
.pb {
display: inline-block
}
.cb {
clear: both
}
.text {
background: #ffc;
border: 1px solid #000
}
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m75813" href="#m75183">#</a></div>
</div>
<div class="text" onclick="alert(document.getElementById('m75813').id);">
After clicking on the yellow background, the value from [a id="m75813"] (ie. 'm75813') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
but if you have lots of these with various IDs and it's the ID you're trying to find, you can do it by going up to the parent node and using querySelector to find the a element:
alert(this.parentNode.querySelector('a').id);
.h {
background: lightblue;
}
.pb {
display: inline-block
}
.cb {
clear: both
}
.text {
background: #ffc;
border: 1px solid #000
}
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m75813" href="#m75183">#</a></div>
</div>
<div class="text" onclick="alert(this.parentNode.querySelector('a').id);">
After clicking on the yellow background, the value from [a id="m75813"] (ie. 'm75813') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m54684" href="#m54684">#</a></div>
</div>
<div class="text" onclick="alert(this.parentNode.querySelector('a').id);">
After clicking on the yellow background, the value from [a id="m54684"] (ie. 'm54684') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
In both cases, I would suggest modern event handling rather than using onxyz-attribute-style handlers. For example: Let's assume all those article elements are in some kind of container. We can hook click on the container and then find which div the click passed through, and find the a related to that div:
document.getElementById("container").addEventListener("click", function(e) {
var element = e.target;
while (element != this) {
if (element.matches("div.text")) {
alert(element.parentNode.querySelector("a").id);
break;
}
element = element.parentNode;
}
});
document.getElementById("container").addEventListener("click", function(e) {
var element = e.target;
while (element != this) {
if (element.matches("div.text")) {
alert(element.parentNode.querySelector("a").id);
break;
}
element = element.parentNode;
}
});
.h {
background: lightblue;
}
.pb {
display: inline-block
}
.cb {
clear: both
}
.text {
background: #ffc;
border: 1px solid #000
}
<div id="container">
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m75813" href="#m75183">#</a></div>
</div>
<div class="text">
After clicking on the yellow background, the value from [a id="m75813"] (ie. 'm75813') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m54684" href="#m54684">#</a></div>
</div>
<div class="text">
After clicking on the yellow background, the value from [a id="54684"] (ie. '54684') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
</div>
You can do this:
<div class="text" onclick="alert(document.getElementById('m75813').id);">
After clicking on the yellow background, the value from [a id="m75813"] (ie. 'm75813') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
What's happening is that your queries are returning text nodes (which includes whitespace like newlines) as well as HTML nodes, so your elements aren't at the index you expect. querySelector('a') is the simpler approach, but if you did want to select your target via it's place in the DOM structure, you could use firstChildElement and children instead of firstChild and childNodes, respectively, because they exclude text nodes:
this.parentElement.firstElementChild.children[1].firstElementChild.id
.h {
background: lightblue;
}
.pb {
display: inline-block
}
.cb {
clear: both
}
.text {
background: #ffc;
border: 1px solid #000
}
<article>
<div class="h">
<div class="pb">user</div>
<div class="pb">date <a id="m75813" href="#m75183">#</a></div>
</div>
<div class="text" onclick="alert(this.parentElement.firstElementChild.children[1].firstElementChild.id);">
After clicking on the yellow background, the value from [a id="m75813"] (ie. 'm75813') should apppear. Sentence text.<br> Other sample.<br> Hello world.
</div>
</article>
Could someone please help me to get the onmoseover event to hold the display:block; behavior until I've onmouseover a different event? In other words I would like to keep an event visible until I've onmouseover a different event. I fill the answer is a simple one. I'm 2 days new to javascript.
CSS
.box {
width: 900px;
height: auto;
margin-top: 20px;
padding: 0px 0px 15px 0px;
border: 5px solid black;
margin-left: auto;
margin-right:auto;
}
HTML
<div class="box" style='width:400px; height:auto;>
<p style="display:inline;"
onmouseover="document.getElementById('sometext1').style.display = 'block';"
onMouseOut="document.getElementById('sometext1').style.display = 'none';">
<span>some text1</span></p>
<p style="display:inline;"
onmouseover="document.getElementById('sometext2').style.display = 'block';"
onMouseOut="document.getElementById('sometext2').style.display = 'none';">
<span>some text2</span></p>
<p style="display:inline;"
onmouseover="document.getElementById('sometext3').style.display = 'block';"
onMouseOut="document.getElementById('sometext3').style.display = 'none';">
<span>some text3</span></p>
<div id="sometext1" style="display: none;">
<p>paragraph of content for sometext1</p>
</div>
<div id="sometext2" style="display: none;">
<p>paragraph of content for sometext2</p>
</div>
<div id="sometext3" style="display: none;">
<p>paragraph of content for sometext3</p>
</div>
</div>
First html must be like this:
<div class="box" style='width:400px; height:auto;>
<p id="text1" onmouseover="mouseoverHandler(this.id)" style="display:inline;"><span>some text1</span></p>
<p id="text2" onmouseover="mouseoverHandler(this.id)" style="display:inline;"><span>some text1</span></p>
<p id="text3" onmouseover="mouseoverHandler(this.id)" style="display:inline;"><span>some text1</span></p>
<div id="sometext1" style="display: none;">
<p>paragraph of content for sometext1</p>
</div>
<div id="sometext2" style="display: none;">
<p>paragraph of content for sometext2</p>
</div>
<div id="sometext3" style="display: none;">
<p>paragraph of content for sometext3</p>
</div>
</div>
Write functions for event listeners in js file:
var previousId = null;
function mouseoverHandler(e){
if (previousId != e) {
document.getElementById('some' + e).style.display = 'block';
if (previousId != null) {
document.getElementById('some' + previousId).style.display = 'none';
}
}
previousId = e;
}
Just think about your paragraph elements as identifiers for div and have relation between them.