.text() affects html elements inside h1 - javascript

I have the following markup:
<h1>A text <span class="createTask glyphicon glyphicon-plus"></span></h1>
What I want to do is when I double click an h1 to change its text.
To do this I wrote the following code inside a document ready function
$("h1").on("dblclick",function(){
var newTitle = prompt("Enter a new title");
if(newTitle){
$(this).text(newTitle);
}
})
However this code instead of just changing the text of the h1 it removes the glyphicon span.
Any Ideas why?
Also note that I cannot change the markup.

Using $(this).text() (.html() is the correct syntax), you are changing the entire h1 content, including the glyph inside it.
If you want to keep the glyph (with the span), seperate them from the h1 like so:
<h1>A text </h1><span class="createTask glyphicon glyphicon-plus"></span>
Or, as you requested - without changing the markup:
$(this).html(newTitle + "<span class='createTask glyphicon glyphicon-plus'>");

You need to update the first text node within the h1: $(this).contents().get(0).nodeValue = newTitle;.
$("h1").on("dblclick", function() {
var newTitle = prompt("Enter a new title");
if (newTitle) {
$(this).contents().get(0).nodeValue = newTitle;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<h1>A text <span class="createTask glyphicon glyphicon-plus"></span></h1>

Add another span inside the h1 element and then
<h1>
<span id="text">A text </span>
<span class="createTask glyphicon glyphicon-plus"></span>
</h1>
$("h1").on("dblclick",function() {
var newTitle = prompt("Enter a new title");
if (newTitle){
$(this).find('#text').text(newTitle);
}
})

You can use Node.previousSibling to get previous sibling of SPAN DOM element and then its nodeValue can be set.
$("h1").on("dblclick", function() {
var newTitle = prompt("Enter a new title");
if (newTitle) {
var span = $(this).find('span').get(0); //get the DOM element
span.previousSibling.nodeValue = newTitle;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<h1>A text <span class="createTask glyphicon glyphicon-plus">+++++</span></h1>

.text() replaces the contents of the element with the specified text.
Since the icon span is inside the element it will be replaced.
You can target the text node directly and replace its text.
this.firstChild.nodeValue = newTitle;

Related

Only apply styling to selected text in content editable <p>

Problem
Hi, I have some code that when a button is clicked, all of the content in a contentEditable <p> tag will have a font-weight of 600 (bold).
What I'm wondering is how can I make it so when the button is pressed, rather than style all the content in the p tag to 600 font weight, only style the selected text. For example, if you only highlight the first two words of the p tag and press the button, only the first two words will have their font-weight changed.
Image example
In the example, when the button is pressed, only the first two words would have their font-weight changed.
Link to the fiddle containing code: https://jsfiddle.net/AidanYoung/9tg4oas5/
here is your solution.
function changeBold() {
const text = window.getSelection().toString();
var btn = document.createElement('span');
btn.innerHTML = text;
btn.style.fontWeight = 'bold';
document.execCommand('insertHTML', false, btn.outerHTML);
}
<p contenteditable="true" id="contenttxt">
Some text in this paragraph tag
</p>
<button onclick="changeBold()">Bold selected text</button>
You can use the span label and add ID
function changeBold() {
document.getElementById("strongC").style.fontWeight = "600";
}
<p contenteditable="true" id="contenttxt">
<span id="strongC">Some text</span>
in this paragraph tag
</p>
<button onclick="changeBold()">Bold selected text</button>

Creating a read more button with html and javascript

I am using html, css and javascript to create a read more button. I have a paragraph and if this button is pressed, more text will de displayed.
This is my html code
<p class="details">Text that is displayed><span class="read-more">More text</span></p>
<button class="read-more-button">Read more</button>
//on the bottom of the page I also added the scripts
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
In my css file I make the paragraph between the span tag not visible
.details .read-more{
display:none;
}
In my javascript
const readMoreBtn = document.querySelector('.read-more-button');
const text = document.querySelector('.details');
readMoreBtn.addEventListener('click',(e)=>{
details.classList.toggle('read-more');
})
The problem is that when I press the Read more button nothing happens, the paragraph between the span tag is not displayed. Am I missing something here?
You need to target .read-more class, not .details.
Also, there is a undefined variable in event listener.
The correct JS code should be:
const readMoreBtn = document.querySelector('.read-more-button');
const text = document.querySelector('.read-more');
readMoreBtn.addEventListener('click',(e)=>{
text.classList.toggle('read-more');
})
You're toggling the class of p.details. You should toggle the class of `.read-more'.
const readMoreBtn = document.querySelector('.read-more-button');
const moreText = document.querySelector('.read-more');
readMoreBtn.addEventListener('click',(e) => {
moreText.classList.toggle('read-more');
// Consider changing the button text to collapse or removing it altogether perhaps?
})
.details .read-more{
display:none;
}
<p class="details">Text that is displayed<span class="read-more">More text</span></p>
<button class="read-more-button">Read more</button>

Convert all headings to anchor links

All the h1 tags in my webpage contain a custom tool-tip and an anchor(which are added with jquery). The html looks like this:
<h1 id="heading1">
<span>
Intro
<div class="tooltip">
<i class="icon-decline">X</i>
<div class="tooltip-arrow"></div>
<div class="tooltip-inner">
<input type="text" readonly="readonly" value="http://someurl/somemore/#heading1">
</div>
</div>
<a href="http://someurl/somemore/#heading1" class="anchor"><i class="icon-chain-link">#</i>
</a>
</span>
</h1>
For smaller devices after hiding the tool-tip and the anchor I want convert the string within the h1 to an anchor link with the native link of the heading. I want something like this:
<h1 id="heading1">
<span>
Intro
<div class="tooltip">
<i class="icon-decline">X</i>
<div class="tooltip-arrow"></div>
<div class="tooltip-inner">
<input type="text" readonly="readonly" value="http://someurl/somemore/#heading1">
</div>
</div>
<a href="http://someurl/somemore/#heading1" class="anchor"><i class="icon-chain-link">#</i>
</a>
</span>
</h1>
Unfortunately until now I haven't found a way to target solely the text string and the jquery wrapInner() method, that I'm using, wraps all the the elements inside the h1. This is my code until now:
//the function to hide the tooltip, the anchor and convert the h1 to link
function makeResponsive(){
if ($(window).width() < 780) {
$('h1').wrapInner('');
$('div.tooltip').css('display', 'none');
$('a.anchor').hide();
} else {
$('a.anchor').show();
}
}
//run on document load and on window resize
$(document).ready(function () {
//on load
makeResponsive();
//on resize
$(window).resize(function(){
makeResponsive();
});
});
Here is a working example with an additional h2 tag. First problem: I can't set the id from the h tag as location.hash Second problem: Want to convert only the text string of the h tag to a link
If a tag contains an id attribute, you don't need an anchor for it.
If this page http://www.example.com/page1.html contains a tag like <section id="general_information">, all you need to link directly to that section is a link like ...
Following the example are you forgetting this part:
$('a.anchor').click(function(event) {
event.stopPropagation();
var thistool = $(this).parent().find('div.tooltip');
$('div.tooltip').not(thistool).hide();
thistool.toggle();
thistool.find('input').select();
});
$('.icon-decline').on('click', function() {
$(this).parent().hide();
});
$('div.tooltip').on('click', function(event) {
event.stopPropagation();
});
$(document).on('click', function() {
$('div.tooltip').hide();
});
Demo: https://jsfiddle.net/hmyf4mp7/4/
So here is my solution:
if ($(window).width() < 780) {
$('h1 > span, h2 > span, h3 > span').each(function() {
window.location.hash = this.parentElement.id;//set the local id as hash
$(this).contents().eq(0).wrap('<a class="native" href="' + window.location.hash + '"></a>');
});//get ONLY the text within the h tags and wrap it with a tags that have the local hash
In devices with width less than 780px for each span within the h tags I set the hash equal to the id of their parent. Then i get the first content of the span, which is the text and wrap it with an a that has the complete URL of the location.
In devices with width more than 780px I just find and unwrap the a tags that wrap the text.
} else {
$('a.native').contents().unwrap();
}
Here is a Demo with the complete code.

Javascript medium-editor markdown append image and update content

<div class="editable" contenteditable="true"></div>
<textarea name="markdown" class="markdown" /></textarea>//display none
new MediumEditor('.editable', {
extensions: {
markdown: new MeMarkdown(function (md) {
document.querySelector(".markdown").textContent = md;
}),
img: new imgButton()
}
$('.editable').append("<img src='abc' />");
I have a div use medium-editor & medium-editor markdown
when user type inside of .editable, textarea will sync.
I also have a button click, it will append an image into .editable
my problem is markdown only update when .editable keypress
so if I append text, textarea wont sync, unless I press any key inside of .editable again
anyone know how to tell markdown to update after append image
try this
function updateTextArea(index,editable){
var textarea = editable.parentNode.querySelector('textarea[medium-editor-textarea-id="' + editable.getAttribute('medium-editor-textarea-id') + '"]');
if (textarea) {
textarea.value = editable.innerHTML.trim();
}
}
$('.editable').append("<img src='abc' />");
$('.editable').each(updateTextArea);
The updateTextArea function will update a text area corresponds to editable area.
Here is the code I tried
var editor = new MediumEditor('.editable', {
buttonLabels: 'fontawesome'
});
function updateTextArea(index,editable){
var textarea = editable.parentNode.querySelector('textarea[medium-editor-textarea-id="' + editable.getAttribute('medium-editor-textarea-id') + '"]');
if (textarea) {
textarea.value = editable.innerHTML.trim();
}
}
$("#addImage").click(function(){
$('.editable').append("<img src='abc' />");
$('.editable').each(updateTextArea);
});
$('.editable').change(updateTextArea);
<link href="http://yabwe.github.io/medium-editor/bower_components/medium-editor/dist/css/themes/tim.min.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css" rel="stylesheet"/>
<link href="http://yabwe.github.io/medium-editor/bower_components/medium-editor/dist/css/medium-editor.min.css" rel="stylesheet"/>
<script src="http://yabwe.github.io/medium-editor/bower_components/medium-editor/dist/js/medium-editor.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<h1>Medium Editor</h1>
<textarea class="editable medium-editor-textarea" name="markdown" id="markdown"><p>Textarea is now supported</p></textarea>
<input type="button" id="addImage" value="Add Image">
<input type="button" value="Alert textarea content" onclick="alert(document.getElementById('markdown').value)">
</div>
If you use the setContent() method of the editor (documentation here), this will allow you to add content and the editor will detect the change and fire all the proper events. This should include notifying the markdown extension that the content has changed and that should update the markdown.
So, instead of this:
$('.editable').append('<img src="abc" />');
Try this:
editor.setContent(editor.getContent() + '<img src="abc" />');
This also leverages the getContent() method (documentation here).
NOTE: These examples assume you're only using a single editor element for MediumEditor. If you are passing multiple elements into a single instance of MediumEditor, you may need to specify a value for the index parameter to both setContent() and getContent()

Remove and replace another onclick function in a div through Pure Javascript?

I have this below span div and I copy this to another place in the DOM. But the onclick function I need to remove and place another onclick function.
<span class="plus childNode1" onclick="expand_collapseChildnodes('childNode1')" id="abc"></span>
Here I have to remove the onclick="expand_collapseChildnodes('childNode1')" for the copied element and replace it with onclick="checkNodes('childNode1')"
Consider a sample HTML page:
<html>
<head>
</head>
<body>
<div id ="d1">
<span class="plus childNode1" onclick="expand_collapseChildnodes('childNode1')" id="abc"></span>
</div>
<div id ="d2">
</div>
</body>
</html>
Now to move the element with id abc from DOM element with id d1 to another with id d2
//get the element
var element = document.getElementById("abc");
//detach from source
document.getElementById("d1").removeChild(element);
//remove onclick attribute
element.removeAttribute("onclick");
//add the modified attribute
element.setAttribute("onclick", "sampleFunc()");
//attach the element to another source
document.getElementById("d2").appenChild(element);
http://jsfiddle.net/KvnKZ/1/
var div=document.getElementsByTagName("div");
var span=document.getElementById("abc");
var newSpan=span.cloneNode(true);
newSpan.setAttribute("id","newID"); //change id
newSpan.setAttribute("onclick","myFunc()"); //change onclick event handler
div[0].appendChild(newSpan);
document.getElementById("abc").onclick = function (){checkNodes('childNode1');}

Categories