My skills in Javascript are limited and for practicing i'm trying to programatically fill some elements using JS code, using Chrome's Developer Tools. I navigate to a site, access the console and try to manipulate DOM elements using JS code.
Usually elements a user can input data are INPUT, TEXTAREA , SELECT and so on. But latelly i've been seeing elements that are user-editable, but are simply DIVs. In other words, a DIV acting like an INPUT or TEXTAREA, and this got me confused.
Here is an example : i extracted this source from a page to post topics in a Facebook Group.
Note that the div that has the 'Write something' innerhtml works as a textarea in the page. You can reproduce this code in any Facebook Group, ie https://www.facebook.com/groups/914737511952904/ (you might need to join the group before see the box to post a topic).
<div class="_1mwp _1mwq _5bu_ _5yk1"><div class="_5yk2" tabindex="-2">
<div class="_5rp7">
<div class="_1p1t">
<div class="_1p1v" id="placeholder- 2bc29">Write something... </div>
</div>
</div>
</div>
If this element was a TEXTAREA, i could easily do something like
document.getElementById('elementId').value = 'New text';
But the 'textarea' element in the above case is actually a DIV and nothing else.
How can i insert text on it using JS ? An how can a DIV act like a textarea or an input ?
Thanks !
How can I insert text on it using JS?
That's quite simple. Just use the innerHTML property to assign the text value.
document.getElementById('elementId').innerHTML = "Text inserted"
However you can do the same using just CSS, and then retrieving the text from the div invoking the same property.
How can a DIV act like a textarea or an input?
A very practical way is using the contentEditable property over the div, but you can use CSS styles as well, and in some cases with some JavaScript code.
You have a simple example here using CSS styles and contentEditable property:
https://jsfiddle.net/ThinkingStiff/AbKTQ/
How can I insert text on it using JS?
element.textContent = "text content"
SNIPPET 1
var div = document.querySelector('div');
div.textContent = "line of text by textContent"
<div></div>
An how can a DIV act like a textarea or an input?
You can add contneteditable to an element that's not originally editable.
<div contenteditable></div>
See Snippet on how to set contenteditable by JS
SNIPPET 2
var editor = document.querySelector('div');
editor.setAttribute('contenteditable', true);
<div>This is a div. Click on me and start typing.</div>
Related
What is the best way to style up content in the HTML textarea element. My goal is to have parts of text in my textarea red (for example), so I would do <span style="color: red">My text part</span> but this way the textarea shows everything including my HTML code <span> ... </span> as its value.
Next thing I tried is to overlay div with my textarea in which would be my desired code width <span> ... </span> code shown correctly with red styled text and without HTML code. User will edit textarea's value which would be processed and shown in my div. But this method seems to me too dirty. What is your advises?
Styling text inside a textarea is not possible, you can check this. You could use a plugin like TinyMCE, which will show a text editor in the place of your textarea, and there you can put the style that you want to the text.
I've got this HTML-Content. I knew that this is not correct HTML but I can't change it because it's user generated by a WYSIWG-Editor and this mistake was done hundered of times by users:
<div>
<H2 style="COLOR: #0000ff"> <DIV align=left>TEXT<br /></H2></STRONG>
</DIV>
</div><br />
Problem is that the Div AFTER the H2 Tag is closed AFTER the closing Tag from the H2.
What happens is that the H2 autocloses the enclosed DIV and the original closes the Div above.
As I can't change the Sourcecode in those masses of Content-Files, is there a way to prevent this behaviour with CSS???
CSS won't fix this. If this is generated by the editor specifically then you need a new editor. If you're setting content in JavaScript based on the content of an editable region you might be in luck. Browsers auto-close tags as the content is assigned. Say you have JavaScript to handle that content, and you're assigning that HTML to an element. When it's assigned to the element it will add the closing tag, and then when you go to programmatically close the tag at the correct time you'll get the duplicate close. I found when I do this I need to store the HTML into a string var temporarily, and then assign the HTML when it's all complete. If you need a quick lightweight html5 editor I have one at http://www.makrit.net/5edit
I am making an editor with live preview which means that when I type HTML codes inside the textarea, it will automatically show inside the iFrame and I currently have the following code to select the active element in the iFrame: document.getElementById("IFRAME").contentWindow.document.activeElement but how can I make it so that when I click an element inside the iFrame, it will select the element's source that I wrote in the textarea? A concept would be nice too.
My initial concept was:
When I click on an element inside the iframe, it will get the innerHTML of the activeElement and search for it in the textarea but the problem with that is what if the user has more than one of same elements with the same innerHTML? So that wouldn't work.
Rough Code (Just For Concept):
HTML:
<iframe id="IFRAME"></iframe>
<textarea id="TEXTAREA" onkeyup="update()">
<div id="clickme">
</div>
</textarea>
JAVASCRIPT:
function update() {
document.getElementById('IFRAME') = document.getElementById('TEXTAREA').innerHTML;
}
function IFRAME_ELEMENT_CLICKED() {
// When "clickme" is clicked from inside the iframe, select the innerHTML generated in the TEXTAREA
// document.getElementById("IFRAME").contentWindow.document.activeElement ....
}
In my opinion, while you generate preview onto the iFrame from textarea, you should create dom elements by including a specifier which acts as a link between the content in the textarea and that of the iFrame. You can probably start assigning an id to each tag that you generate onto the iFrame which can be the cursor position/char index etc., in the text area (This needs more manipulation that what I mention here as you need to re-assign the IDs in iFrame, as not always everyone types text at the end in the textarea).
This way you would be able to capture the exact position of content on textarea when someone makes a selection on the iFrame.
I have html that I can't change (as its coming from a clients database)
something like below. as you can see it is not wrapped in a tag, and I can't select the div, as I only want to target stuff under the sub_header (if it's present) with white-space:pre-line;
<span class="sub_header">Example:</span>
<br/>
Some text
That I need to wrap with white-space:pre-line;
As it displays on one line in html
all the way done to the div
</div>
Is this even possible?
$('div.container').css('white-space', 'pre-line');
$('div.container span.sub_header').css('white-space', 'normal');
That code should apply the CSS to the parent div (which I assumed has a class of container but change it to whatever) but not the child span. There are more elegant ways to do it (get inner content, exclude the span, then wrap it in another div styled as you need) but this will do in a jiffy assuming they are all in this format.
looking for something like this? http://jsfiddle.net/pKyG7/4/
<div>
<span class="sub_header">Example:</span><br/>
<div style="font:arial; font-size:26px; white-space:pre-line;">Some text
That I need to wrap with white-space:pre-line;
As it displays on one line in html
all the way done to the div.</div>
</div>
Here's a jQuery solution: http://jsfiddle.net/9PzeS/
$($('.sub_header + br')[0].nextSibling).wrap('<span style="white-space:pre-line"></span>');
Not sure if it's ideal and needs some error handling, but it seems to work.
Edit - Slightly more readable version:
var textNode = $('.sub_header + br')[0].nextSibling;
$(textNode).wrap('<span style="white-space:pre-line"></span>');
$('.sub_header + br')[0] selects the br tag in your example and gets the dom node. nextSibling is a vanilla js property that selects the next sibling, including text nodes.
I then wrap that with a span with the correct style.
I'm trying to create a couple of buttons above a textarea to insert some HTML code -- a VERY poor-man's HTML editor. I have a couple of INPUT elements, and I'm using jQuery to set a click handler that will call's jQuery's append() or html() or text() functions.
The handler fires, it shows a debug alert(), but the text I'm trying to append doesn't show up in the textarea. When I inspect the textarea in Firebug, I see the text I'm appending as a child of the textarea -- but it's dimmed, as when an element's style is set to display:none. But Firebug's CSS inspector doesn't show any change to the display or visibility properties.
When I set the click handler to 'append()', and then click multiple times, in Firebug I see the text being added over and over again -- but each new chunk is still invisible. If I choose 'Edit HTML' in Firebug and then type some chars next to the appended text, the entire text block -- the text added by jQuery and the stuff I added in Firebug -- suddenly appear.
This also happens if I don't use a click handler, but call my append function using an inline handler like onclick="javascript:insert('bold');"
Anyone have any idea why the appended text is not displayed?
Here's the relevant code:
The HTML:
<input type='button' id='bold' value='B' onclick='javascript:insert("bold")' />
<textarea name='PersonalGreeting' id='PersonalGreeting'>default text</textarea>
The Javascript:
function insert( cmd ) {
switch ( cmd ) {
case 'bold':
$('#PersonalGreeting').append('<b>bold text here</b>');
break;
}
}
I would guess that jQuery is trying to append HTML DOM elements to the textarea.
Try using the val method to get and set the textarea's value, like this:
$('#PersonalGreeting').val($('#PersonalGreeting').val() + '<b>bold text here</b>');
The basic problem is that you can't put HTML inside a <textarea>. In fact, you can't append HTML elements to one at all. You could use the .val() method to change the text shown inside, but that won't make it bold. That will just make it have <b> showing as part of the text.
An off-the-shelf WYSIWYG editor like TinyMCE is free and easy to implement. Rather than reinvent the wheel (which is a lot harder than it might look), try an existing wheel out.
SLaks and VoteyDisciple are correct. You're usage of append is faulty as you are perceiving it as a string function.
From http://docs.jquery.com/Manipulation/append
Append content to the inside of every
matched element. This operation is the
best way to insert elements inside, at
the end, of all matched elements. It
is similar to doing an appendChild to
all the specified elements, adding
them into the document.
Reinventing the wheel on this one is likely more headache than its worth unless this is an attempt to create a superior, competing product or for your own experimentation.
Also, I would shy away from use of obtrusive JavaScript as you have shown in your example with onclick='javascript:insert("bold")' embedded in the input element. Instead, you'll have a more elegant solution with something like the following:
HTML
<input type="button" value="B" class="editor-command" >
<input type="button" value="I" class="editor-command" >
<input type="button" value="U" class="editor-command" >
JavaScript (not tested)
$(document).ready(function() {
var textarea = $('#PersonalGreeting')
$(".editor-command").each(function(i, node) {
textarea.val(textarea.val() + '<$>text here</$>'.replace(/\$/g, node.value);
});
});
If the main issue is the textarea not being visible, I would try this:
$('#PersonalGreeting').append('<b>bold text here</b>').show();
Might be worth a shot.
edit: In the vain of not trying to reinvent the wheel, I've had success with WYMEditor
You could do this:
$('#PersonalGreeting').append('[b]bold text here[/b]');
But that won't actually render the text as bold. To be honest I'm not actually sure how to render text as bold inside a textarea, I imainge some js trickery.