How to prevent event-bubbling from a textarea while keeping it editable? - javascript

I have a listview in jQuery mobile where each entry contains several lines of text.
Clicking on the entry is supposed to replace some parts of the text with a <textarea> to make it editable. Clicking on the entry again should again replace the textarea with plain text (now edited).
While editing the text, the user should be able to click around within the textbox to select parts of the text or move the cursor around. To prevent click events from the textarea from bubbling, I use stopPropagation() on the event and that works quite nicely.
However, while this works in Chrome & Safari, both Firefox and Internet Explorer do not move the cursor nor let the user select parts of the text within the textarea.
Is there something I am missing here? (For Firefox, I am using version 19.0.2 on Windows 7, if that is relevant. I have tried using preventDefault or returning false, but that did not work - and why should it?)
I have created a JSFiddle here
The html code is
<ul id="listid" data-role="listview" data-filter="true" data-iconpos="center" data-split-icon="arrow-u" data-theme="c" data-split-theme="b" data-inset="true">
<li><a href="#" id="link1">
<h2>Title</h2>
<p>Here is some item<br />with several lines<br />
<span id="comment1">And this line is supposed to be editable</span>
<textarea style='display: none; width: 95%;' id="textarea1"></textarea>
</p></a>
This does something else
</li>
</ul>
and the respective JavaScript is (loaded on body.onLoad here, but that is just for the JsFiddle):
window.toggled = false;
$("#link1").click( function(e){
var textarea = $("#textarea1").toggle();
var comment = $("#comment1").toggle();
if(window.toggled){
comment.html(textarea.val());
}
else{
textarea.val(comment.html());
}
toggled = !toggled;
});
$("#textarea1").click(function(e){
if(console && console.log){ console.log(e);}
e.stopPropagation();
});
Please ignore the not-quite-so-elegant solution for toggling the textarea.

IE is not happy with the textarea inside an anchor tag. See http://jsfiddle.net/zCfRu/
<a href="#" id="link1">
<h2>Title</h2>
<p>Here is some item<br />with several lines<br />
<span id="comment1">And this line is supposed to be editable</span>
</p>
</a>
<textarea style='display: none; width: 95%;' id="textarea1"></textarea>

Related

Replacing text on web page using HTML or Javascript

I am customizing an HTML page provided and hosted by a third-party, so I am severely restricted in what I can do to the page. On the page there is a navigation menu that looks like this.
<ul class='nav'>
<li class='active'>
<a href='/affiliate'>
<span id='affiliate-nav-homepage'>
<span class='default'>Home Page</span>
</span>
</a>
</li>
<li>...
Question: How can I make the above snippet display the text "Home" instead of "Home Page", if all I am allowed to do is add a <style> element in the page <head>; and add some HTML code (which may include Javascript) near the start of the page?
I have a considered going down one of these two paths, but both paths are problematic.
1) Use CSS to hide their text ("Home Page"). Add my own text ("Home") using :before or :after pseudo-selectors.
display: none is probably not a good way to hide the text, because browsers that don't understand :before and :after will still understand display: none and I will end up with no text at all.
Are there better CSS alternatives for me? Change font size to 0? change text color? Manipulate z-index somehow? It is OK if some older browsers display the text "Home Page". It is not OK if some browsers display "Home Page Home", or if some browser do not display any text at all.
-- OR --
2) Use Javascript to manipulate the DOM
The difficulty with Javascript is that I can only insert it near the start of the page body before the elements that I want to modify. I could hook an event that fires after the entire page is loaded, but I want to avoid the page text flashing (the text "Home Page" being displayed briefly and then changing to "Home"). Is there such an event and how would I hook it?
Thank you for you help.
Anti flashing fix:
.default { display: none; }
Changing text and showing, when document is ready:
body.onload = function (){
//getElementsByClassName not working in old browsers, so ...
var el = document.getElementById('affiliate-nav-homepage').getElementsByTagName('span')[0];
el.innerHTML = 'Home';
el.style.display = 'block';
};
Additional You can hide all content and show it after all javascript changes by this method.
This is not elegant solution, but as You say, You have limited options to resolve Your problem.
In JavaScript
window.addEventListener("load", function(){
document.querySelector("span.default").textContent = "Home";
//using document.querySelector to select the span with classname default
//using textContent to change the content of the node.
}, false);
In a script block will do it.
This will execute on page load. This will be executed so fast that in almost all cases you won't see text jumping.
Example:
window.addEventListener("load", function(){
document.querySelector("span.default").textContent = "Home";
}, false);
<ul class='nav'>
<li class='active'>
<a href='/affiliate'>
<span id='affiliate-nav-homepage'>
<span class='default'>Home Page</span>
</span>
</a>
</li>
</ul>
When your page loading becomes slowed by other resources, #Mateusz Mania's idea of using CSS to hide the element and bring it up again is actually pretty nice. I would suggest using opacity: 0 or visibility: hidden instead of display:none since the latter will remove the element from the page and when it becomes visible again it will make the content jump down below it.
Exploring the CSS option
#affiliate-nav-homepage:before{
content: "Home";
}
.default {
display: none;
}
<ul class='nav'>
<li class='active'>
<a href='/affiliate'>
<span id='affiliate-nav-homepage'>
<span class='default'>Home Page</span>
</span>
</a>
</li>
</ul>

Textarea not clickable in firefox

A expanding textarea is not clickable in the firefox browser. Chrome, IE and mobile browsers work.
<div id="image-upload" class="panel">
<ul class="imagelist-uploader">
<li>
<textarea class="inputbox image-comment" name="comment_list[0]" placeholder="Description">Default Text</textarea>
</li>
</ul>
</div>
I added the simple code to jsfiddle. Click with chrome at the default text to watch the behavior.
http://jsfiddle.net/9hksezsu/
I think it has something do to with the jscode.
Thank you very much for help.
In your Javascript code, LINE 60 : remove "disableSelection()" and everything works fine ;)
It's because of your list. Remove the textarea from the list and it will work fine.
Remove your ul class and it will work fine.

Pressing enter key on Ordered/Unordered list adds <br> after each <li> element

Am working with contentEditable element that has some text formatting associated with it. But with the use of ordered or unordered list items, chrome and firefox adds <br> everytime I press enter after the first <li>.
The generated html text looks something like the following:
Hello
<ul>
<li>World<br></li>
<li>the great<br></li>
<li> <br></li>
</ul>
How can I remove the off-the-grid <br> tags being added to each li tag? Is it possible to do it using CSS or just using javascript?
Use CSS :
ul li br {
display: none;
}
The default action of pressing enter will not generate <br>, see http://jsfiddle.net/fudesign2008/2As6J/.
Is there any bug in js code of your project.

Elements in <li> in contenteditable sometimes don't receive keypress event

I created a contenteditable div. I want to lock text editing (in the example below, I want to lock "yes") within one of the children. Here's the HTML:
<div id="foo" contenteditable="true">this is a test
<div contenteditable="false">
<ul>
<li>
<a id="test" contenteditable="true" href="stackoverflow.com">a link here</a>
</li>
</ul>
yes
</div>
...
</div>
and JavaScript code:
document.getElementById('foo').addEventListener("keypress", function(e){
alert("div " + e.which);
});
document.getElementById('test').addEventListener("keypress", function(e){
alert("a " + e.which);
});
Link to demo: http://jsfiddle.net/wCs8J/1/
The problem is, when you click on the right side of <li> (when the cursor is default arrow), you'll be able to edit text in <a>. However, <a> doesn't receive keypress, only main div receives it. Why? And what should I do to make it working?
Taking the ContentEditable off the #foo continued to broadcast events from #test just fine
http://jsfiddle.net/Maslow/wCs8J/2/
Perhaps it's a browser specific problem?

When I move hovered node to new place it is still displayed as hovered. How can I unhover it?

In IE7 and IE8 when I move hovered link to new place it is still displayed as hovered. In Firefox and Chrome link is displayed as unhovered. In the example below if you click on the link it will be moved to the second row but will still be red. Is it possible to fix such behavior?
<style>
a { color:blue; }
a:hover { color:red; }
</style>
<div id="div1">
First Row
<a id="a1" href="javascript:void(0);" onclick="document.getElementById('div2').appendChild(this);">Click It</a>
</div>
<div id="div2">
Second Row
</div>
Live example
I don't like it, but cloning the node and removing the original seems to work:
<a id="a1" href="javascript:void(0);" onclick="document.getElementById('div2').appendChild(this.cloneNode(true)); this.parentNode.removeChild(this);">Click It</a>
Live example
There, instead of actually moving the node, we do a deep clone of it (cloneNode(true)) and append that instead. Then we remove the original (this.parentNode.removeChild(this)). This seems to avoid keeping the state information IE is keeping.

Categories

Resources