I need to ask for some help with this one so here goes...
I'm creating a WYSIWYG editor using a contenteditable textarea. It automatically creates paragraphs and you can also add in subtitles.
What I would like to be able to do is when the button #addStorySubtitle is clicked, if the currently selected p tag is empty or only contains a zero width space , then it will be replaced with the contents of innerDivSubtitle. However, if the p tag has content, use innerDivSubtitle to create a new block level element underneath.
The part I seem to be having trouble with is detecting is the p tag is empty.
Thanks all!
$('#addStorySubtitle').click(function(e){
var innerDivSubtitle = $('<div class="addStorySubtitleWrap" contenteditable="false"><span class="removeStorySubtitle"></span><textarea name="addstorysubtitle" class="addStorySubtitle autoSize" placeholder="Really good subtitle" contenteditable="true"></textarea></div><p><p>');
var sel = window.getSelection();
if ($(sel.anchorNode.parentNode) === "") {
alert('empty'); //just for help
$(sel.anchorNode.parentNode).replaceWith(innerDivSubtitle);
} else {
alert('not empty'); //just for help
$(sel.anchorNode.parentNode).after(innerDivSubtitle);
}
});
UPDATE
Thanks for all of your helpful replies!
It turns out that the zero width space detection was causing the issue and I had to use unicode to detect it. Here's what I did to fix it...
var nodCon = $(sel.anchorNode.parentNode).html();
if (nodCon === "" || nodCon === "\u200b"){
alert('empty');
}
I hope this will help you?
if($('p').html() == "" || $('p').html == ""){
//Do something
}
You can check whether the element has content like this:
checkElementContents(document.getElementById('p1'));
checkElementContents(document.getElementById('p2'));
function checkElementContents(element) {
if (element.innerHTML) {
console.log(element.id + " is not empty");
} else {
console.log(element.id + " is empty");
}
};
<p id="p1"></p>
<p id="p2"> </p>
Be careful with spaces, carriage return etc...
function isEmpty(ele)
{
var count = ele.html().replace(/\s*/, '');
if(count>0)
return false;
return true;
}
console.log(isEmpty($('p')));
Check if empty the following way:
if ($("Your p tag").val().length == 0) { /* Empty */ }
Related
I have to restrict user from deleting such words that are in a particular HTML tag (consider I have a custom tag) in a textarea.
<div>
You can Delete Me
<t>
DontDeleteMe
</t>
</div>
The words which are not in a t tag can be deleted.
I tried few logics nothing helps.
Is there any possibilities to get the selection range of ctrl+del keywords do?
case 46:
{ //DEL
if (range.startOffset == startNode.getLength()) {
var ancestor = endNode.$;
while (ancestor != null) {
var next = ancestor.nextSibling;
if (next != null) {
console.log("Next = " + next);
var node = new CKEDITOR.dom.node(next);
cancelEvent = node.isReadOnly();
break;
}
ancestor = ancestor.parentNode;
}
}
break;
}
Unfortunately, your description is quite poor when it comes to describing exactly what you need with examples so nobody really knows what you want to happen to the text.
Here's my Fiddle I just made.
It notes selected text and the ID of the first highlighted text container.
Select the text and press CTRL + Del.
If you use a text area, you can just let the user delete it but then copy it inside again. But why use a text area if the user shouldnt interfere with it? Did i misunderstand the feature you want?
$(document).on('keydown', function(evt) {
if (evt.ctrlKey && evt.keyCode == 46) { // Ctrl + Del key pressed
if (evt.target.id == 'customTextArea') { // Custom tag selected
$('#customTextArea').text('Don't delete me!'); // Copy old text in text area
}
}
});
I've searched through the site and while there's a lot of similar questions being asked, the responses while have helped somewhat I'm still running into an issue and can't quite figure it out.
I am trying to two things:
check if a div exists on the page
if it does exist get the inner text value then split that value to get the 3rd element within it to output to a new variable (which will be called elsewhere)
Here's the HTML div of the page & the JavaScript function:
function listSizer() {
var ListSizeYes = document.getElementById('divMsgPage');
if (typeof(ListSizeYes) != 'undefined' || ListSizeYes != null) {
return document.getElementById('divMsgPage').innerText.split(' ')[2];
}
var ListSizeNo = document.getElementById('divMsgPage');
if (typeof(ListSizeNo) == 'undefined' || ListSizeNo == null) {
console.log('no list size on page')
}
}
var listSizeOutput = listSizer()
console.log(listSizeOutput)
<div id="divMsgPage" class="l txtr pdt4 displayi fntsi mgr16">
1 - 40 of 71<span id="hideResultsMob" class="fntsi mgl4">Results</span>
</div>
The issue I'm running into is when this element doesn't exist on the page in the console I'm getting the error " Cannot read property 'innerText' of null". I would expect on a page when that div doesn't exist for the function to go into the 2nd variable and not try to return the innerText but return in the console that 'no list size on page exists'.
If I change the logic from or i.e || in the if statement to && the error goes away but there's no output to the console when the div doesn't exist.
I'm relatively new to JS so I'm sure I've overlooked something simple.
Also, it does have to be pure JS and not jQuery due to other restrictions.
Any input would be appreciated.
Thanks in advance!
The first conditional is passing because typeof(ListSizeYes) != 'undefined' is true.
When document.getElementById finds no element, it returns null instead of undefined. And typeof(null) is not undefined, it's object.
You can fix your code changing it a little bit:
function listSizer() {
var div = document.getElementById('divMsgPage');
if (div != null) {
return div.innerText.split(' ')[2]; //careful here because you might get `undefined` if there are not 2 spaces in the string.
}
else{
console.log('no list size on page');
return null;
}
}
var listSizeOutput = listSizer()
console.log(listSizeOutput)
<div id="divMsgPage" class="l txtr pdt4 displayi fntsi mgr16">
1 - 40 of 71<span id="hideResultsMob" class="fntsi mgl4">Results</span>
</div>
It can be simplified to this test for a falsy result since your tests are incorrect (null is not undefined):
function listSizer(id) {
var ListSizeYes = document.getElementById(id);
if (ListSizeYes) {
return ListSizeYes.innerText.split(' ')[2]; // assuming there is such a text
}
console.log('no list size with id "'+id+'" on page');
return null;
}
var listSizeOutput = listSizer("divMsgPage")
console.log(listSizeOutput)
listSizeOutput = listSizer("divMsgPageX")
console.log(listSizeOutput)
<div id="divMsgPage" class="l txtr pdt4 displayi fntsi mgr16">
1 - 40 of 71<span id="hideResultsMob" class="fntsi mgl4">Results</span>
</div>
You can simply refactor your code like this.
function listSizer() {
var ListSizeYes = document.getElementById('divMsgPage');
if (ListSizeYes)
return document.getElementById('divMsgPage').innerText.split(' ')[2];
else
console.log('no list size on page')
}
var listSizeOutput = listSizer()
console.log(listSizeOutput)
try this code , i tried removing content and remove div and works
function listSizer() {
var div = document.getElementById('divMsgPage');
if ( div && div.innerText.split(' ')[2]!==undefined ) {
console.log( div.innerText.split(' ')[2]); //careful here because you might get `undefined` if there are not 2 spaces in the string.
}
else{
console.log('no list size on page')
}
}
var listSizeOutput = listSizer()
<div id="divMsgPage" class="l txtr pdt4 displayi fntsi mgr16">
1 - 40 of 71<span id="hideResultsMob" class="fntsi mgl4">Results</span>
</div>
Here is the JSFiddle demo: http://jsfiddle.net/qox0yxb4/
I am using type() to create a typewriter affect (each character is printed on the screen with a delay in between). I use addTextToScreen(textForScreen) to add text to the queue which is then added to the screen through type(). When I call addTextToScreen() from within the JavaScript, the text seems to be formatted as it does NOT overflow on the x-axis, however when I accept input from an HTML <input> tag (printText()), the text overflows on the x-axis.
Here are the JavaScript methods:
var i = 0,
isTag=false,
text;
var typeTime = 45;
function type() {
if (text === textOnScreen){
setTimeout(function(){type();}, typeTime);
return;
}
text = textOnScreen.slice(0, i+1);
i++;
document.getElementById('paraText').innerHTML = text;
var char = text.slice(-1);
console.log(char);
if( char === '<' ) isTag = true;
if( char === '>' ) isTag = false;
if (isTag) return type();
setTimeout(function(){type();}, typeTime);
}
function addTextToScreen(textForScreen){
textOnScreen = textOnScreen + textForScreen;
}
type();
function printText(event) {
if(event.keyCode == 13){
printText = document.getElementById("inputText").value.toString();
addTextToScreen("<br>" + printText.toString());
x = document.getElementById("inputText");
x.value = "";
}
}
I also noticed that whenever I paste text into the input box (the text can be from anywhere) it seems to be formatted, and it does NOT overflow.
Add this css property to #paraText:
word-wrap:break-word;
JS Fiddle Demo
Josh suggested using break-all, here is the difference.
The magic CSS rule you're missing is word-break: break-all;. Add that, and it works just like you'd expect.
Proof
I want to highlight an element that contains a string written in a textbox. This is the part of the code that's supposed to do it:
$("#rightContainer .magnifier").click(function () {
var a = $("#searchBox").val();
if (a != "") {
var foundin = $('div:contains(a)');
foundin.addClass("highlighted");
alert(a);
}
})
The problem is that the whole page gets highlighted. I'm assuming this happens because I have a main container which has its children containers, so the contains method selects the whole main container. Is this the case or is it because of something else, and does anyone have a better way of doing this? Thanks in advance.
The :contains selector will return any element which contains the text you're searching for, in this case "a". This has nothing to do with the variable named a. Perhaps you meant to do something like this:
$("#rightContainer .magnifier").click(function () {
var a = $("#searchBox").val();
if (a != "")
{
var foundin = $("div:contains('" + a + "')");
foundin.addClass("highlighted");
alert(a);
}
})
If I understand correctly, you only want the div highlighted which is wrapping that searchbox and not any other div. Use closest() to find that div.
$("#rightContainer .magnifier").click(function () {
var a = $("#searchBox").val();
if (a != "")
{
$("#searchBox").closest('div').addClass('highlighted');
}
})
I have this HTML button:
<button id="myButton" onClick="lock(); toggleText(this.id);">Lock</button>
And this is my toggleText JavaScript function:
function toggleText(button_id)
{
if (document.getElementById('button_id').text == "Lock")
{
document.getElementById('button_id').text = "Unlock";
}
else
{
document.getElementById('button_id').text = "Lock";
}
}
As far as I know, button text (<button id="myButton">Lock</button>) is just like any link text
(Lock). So the fact that it's a button doesn't matter. However, I can't access the button text and change it.
I tried ('button_id'), (button_id), == "Lock", == 'Lock', but nothing works.
How can I access and change a button text (not value) or a link text?
Change .text to .textContent to get/set the text content.
Or since you're dealing with a single text node, use .firstChild.data in the same manner.
Also, let's make sensible use of a variable, and enjoy some code reduction and eliminate redundant DOM selection by caching the result of getElementById.
function toggleText(button_id)
{
var el = document.getElementById(button_id);
if (el.firstChild.data == "Lock")
{
el.firstChild.data = "Unlock";
}
else
{
el.firstChild.data = "Lock";
}
}
Or even more compact like this:
function toggleText(button_id) {
var text = document.getElementById(button_id).firstChild;
text.data = text.data == "Lock" ? "Unlock" : "Lock";
}
document.getElementById(button_id).innerHTML = 'Lock';
You can simply use:
document.getElementById(button_id).innerText = 'Your text here';
If you want to use HTML formatting, use the innerHTML property instead.
Remove Quote. and use innerText instead of text
function toggleText(button_id)
{ //-----\/ 'button_id' - > button_id
if (document.getElementById(button_id).innerText == "Lock")
{
document.getElementById(button_id).innerText = "Unlock";
}
else
{
document.getElementById(button_id).innerText = "Lock";
}
}