I'm trying to display some data in a <div> and IE9 is not keeping more than one carriage return. This works fine in Chrome, but not IE9 (it only adds the <br/>) Here's the code:
$.get(url,function(xml){
$("record",xml).each(function(){
var profile= $("profile",this).text().replace(/\r\n|\r|\n/g,'~').replace(/~~/g,'<\/p> <p>').replace(/~/g,'<br/>');
profileRpt += profile
});
});
Thought process on this was to normalize, then add <p> for double carriage returns and <br> for the single returns.
I've also tried the simple replacement,
var points= $("points",this).text().replace(/\n\r?/g, '<br />');
and again this worked fine in Chrome, but not in IE9.
Does anyone know of a way I can get this to work in IE9? Thanks!!
UPDATE
So it seems that jQuery is the culprit when used in IE, as it collapses the line breaks prior to any replace function.
Can anyone help with using an alternate (non-jQuery) method of retrieving the data from the xml response as I've done above? One that would preserve the line breaks?
Thanks for your help!
Try this:
function unifyLineFeeds = function(str) {
return str.replace("\r\n", "\n").replace("\r", "\n");
}
You can then use this function to output text as HTML following way:
// `text` var contains text with line ununified line feed characters.
text = unifyLineFeeds(text);
var lines = text.split("\n"),
count = lines.length,
lastIndex = count - 1;
var container = document.getElementById('someContainerToShowFormattedText');
for (var i = 0; i < count; i++) {
container.appendChild(document.createTextNode(lines[i]));
if (i < lastIndex) {
container.appendChild(document.createElement('br'));
}
}
var points = $("points", this).text().replace(/\r+/g, '').replace(/\n/g, '<br>');
Related
I am creating a live content editor for an element using textarea, but its output isn't like what the expected if the inputted value is symbol like > or < or mix up of those symbols and texts, instead of just texts, then it will not replacing instead of doubled it up.
Here is the Fiddle
And here is the jquery codes:
$("#changer").on("change keyup paste", function () {
// get current element
var thehtml = $("#tochange").html();
var thetext = $("#tochange").contents().filter(function () {
return this.nodeType === 3;
}).text().trim();
var thechange = $(this).val();
// if has element, then keep it, add text and put back
var thepurehtml = thehtml.replace(thetext, "");
var theoutput = thechange;
if ($.trim(thepurehtml) != '') {
var theoutput = thechange + thepurehtml;
}
$("#tochange").html("").html(theoutput);
return;
});
What's causing it and how to fix it up?
PS: I need to have the functionality of this line var theoutput = thechange + thepurehtml; because it is sometimes the edited element have html element other than just a blank or text node.
However i am going to delete this answer, As i don't have enough reputation to comment i am posting as answer.
So #SoursopTree, what you actually want to achieve?
What i found is when you enter < or > the line $.trim(thepurehtml) is returning empty string (null) and null!='', so the next statement var theoutput = thechange + thepurehtml; here thechange=> and thepurehtml=>. so you are getting two symbols instead of one.
You said you need to have the functionality of this line var theoutput = thechange + thepurehtml;
I can not find the solution. I've tried to assume that count of \n symbols is the same with lines count, but sometimes this method works incorrectly (e.g. after paste text from clipboard)
i've tried different jQuery plugins, but still unsuccessfully.
any idea?
Why not just do this:
Take the text content only up to selectionStart then make it an array by splitting at eol
p = $('#Form_config').val().substr(0, $('#Form_config')[0].selectionStart).split("\n");
// line is the number of lines
line = p.length;
// col is the length of the last line
col = p[p.length-1].length;
Try to use this:
var pos = getCaretPos(document.formName.textareaName);
function getCaretPos(obj)
{
obj.focus();
if(obj.selectionStart) return obj.selectionStart;//Gecko
else if (document.selection)//IE
{
var sel = document.selection.createRange();
var clone = sel.duplicate();
sel.collapse(true);
clone.moveToElementText(obj);
clone.setEndPoint('EndToEnd', sel);
return clone.text.length;
}
return 0;
}
The descision is not so simple and requieres large amount of javascript code. So, finally i've used CodeMirror Project by Marijn Haverbeke (https://github.com/marijnh/CodeMirror)
<script type="text/javascript">
function addbutton() {
var o = document.getElementsByTagName('li');
for(var i=0;i<o.length;i++)
{
var keyword= o[i].innerHTML;
var regobj = /<a (.*)>(.*)<(.)a>/g;
keyword = keyword.replace(new RegExp("<br>", "g")," ");
keyword = keyword.replace(regobj,"$2");
keyword = keyword.substring(0,100);
var str = "<br>"+ "<a class='but' target='blank' ";
str += "href=\"http://www.google.com.tr/search?q=";
str += decodeURIComponent(keyword);
str += "\">ara</a>";
o[i].innerHTML = o[i].innerHTML + str;
}
}
</script>
addbutton() adds a search button to end of the li tags, but when i run, it's looping for only 43 times. so it's adding the search button for the first 43 li tags. what is your thoughts, why is looping broken?
edit:
more information,
-i tried function on a page that contains 131 li tags. and function is working for the first 43 li tag,
-i tried for both of google chrome and firefox, results are same.
i tried to alert(o.length). there is no problem, it return true number, "131".
Well, there's certainly a bug on this line:
str += decodeURIComponent(keyword);
That should be
str += encodeURIComponent(keyword);
That may be the problem, decodeURIComponent may be blowing up on some input text because you're using it on strings that aren't URL-encoded.
Barring that:
You'll need to look at the actual text in the li elements as they're being processed. It's clearly not just a numbers thing, the code works just fine in Chrome.
I recommend using Chrome's Dev tools (Shift+Ctrl+I) to set a breakpoint in the function and walk through it with your actual test data. Or use the Firebug add-on for Firefox to do the same.
the questions says it all :)
eg. we have >, we need > using only javascript
Update: It seems jquery is the easy way out. But, it would be nice to have a lightweight solution. More like a function which is capable to do this by itself.
You could do something like this:
String.prototype.decodeHTML = function() {
var map = {"gt":">" /* , … */};
return this.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);?/gi, function($0, $1) {
if ($1[0] === "#") {
return String.fromCharCode($1[1].toLowerCase() === "x" ? parseInt($1.substr(2), 16) : parseInt($1.substr(1), 10));
} else {
return map.hasOwnProperty($1) ? map[$1] : $0;
}
});
};
function decodeEntities(s){
var str, temp= document.createElement('p');
temp.innerHTML= s;
str= temp.textContent || temp.innerText;
temp=null;
return str;
}
alert(decodeEntities('<'))
/* returned value: (String)
<
*/
I know there are libraries out there, but here are a couple of solutions for browsers. These work well when placing html entity data strings into human editable areas where you want the characters to be shown, such as textarea's or input[type=text].
I add this answer as I have to support older versions of IE and I feel that it wraps up a few days worth of research and testing. I hope somebody finds this useful.
First this is for more modern browsers using jQuery, Please note that this should NOT be used if you have to support versions of IE before 10 (7, 8, or 9) as it will strip out the newlines leaving you with just one long line of text.
if (!String.prototype.HTMLDecode) {
String.prototype.HTMLDecode = function () {
var str = this.toString(),
$decoderEl = $('<textarea />');
str = $decoderEl.html(str)
.text()
.replace(/<br((\/)|( \/))?>/gi, "\r\n");
$decoderEl.remove();
return str;
};
}
This next one is based on kennebec's work above, with some differences which are mostly for the sake of older IE versions. This does not require jQuery, but does still require a browser.
if (!String.prototype.HTMLDecode) {
String.prototype.HTMLDecode = function () {
var str = this.toString(),
//Create an element for decoding
decoderEl = document.createElement('p');
//Bail if empty, otherwise IE7 will return undefined when
//OR-ing the 2 empty strings from innerText and textContent
if (str.length == 0) {
return str;
}
//convert newlines to <br's> to save them
str = str.replace(/((\r\n)|(\r)|(\n))/gi, " <br/>");
decoderEl.innerHTML = str;
/*
We use innerText first as IE strips newlines out with textContent.
There is said to be a performance hit for this, but sometimes
correctness of data (keeping newlines) must take precedence.
*/
str = decoderEl.innerText || decoderEl.textContent;
//clean up the decoding element
decoderEl = null;
//replace back in the newlines
return str.replace(/<br((\/)|( \/))?>/gi, "\r\n");
};
}
/*
Usage:
var str = ">";
return str.HTMLDecode();
returned value:
(String) >
*/
Here is a "class" for decoding whole HTML document.
HTMLDecoder = {
tempElement: document.createElement('span'),
decode: function(html) {
var _self = this;
html.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);/gi,
function(str) {
_self.tempElement.innerHTML= str;
str = _self.tempElement.textContent || _self.tempElement.innerText;
return str;
}
);
}
}
Note that I used Gumbo's regexp for catching entities but for fully valid HTML documents (or XHTML) you could simpy use /&[^;]+;/g.
There is nothing built in, but there are many libraries that have been written to do this.
Here is one.
And here one that is a jQuery plugin.
I have a text area that I need to parse. Each new line needs to be pulled out and an operation needs to be performed on it. After the operation is done the operation needs to be run on the next line. This is what I have at the moment. I know the indexOf search won't work because it's searching character by character.
function convertLines()
{
trueinput = document.getElementById(8).value; //get users input
length = trueinput.length; //getting the length of the user input
newinput=trueinput; //I know this looks silly but I'm using all of this later
userinput=newinput;
multiplelines=false; //this is a check to see if I should use the if statement later
for (var i = 0; i < length; i++) //loop threw each char in user input
{
teste=newinput.charAt(i); //gets the char at position i
if (teste.indexOf("<br />") != -1) //checks if the char is the same
{
//line break is found parse it out and run operation on it
userinput = newinput.substring(0,i+1);
submitinput(userinput);
newinput=newinput.substring(i+1);
multiplelines=true;
}
}
if (multiplelines==false)
submitinput(userinput);
}
So for the most part it is taking the userinput. If it has multiply lines it will run threw each line and seperatly and run submitinput. If you guys can help me I'd be eternally thankful. If you have any questions please ask
Line breaks within the value of a textarea are represented by line break characters (\r\n in most browsers, \n in IE and Opera) rather than an HTML <br> element, so you can get the individual lines by normalizing the line breaks to \n and then calling the split() method on the textarea's value. Here is a utility function that calls a function for every line of a textarea value:
function actOnEachLine(textarea, func) {
var lines = textarea.value.replace(/\r\n/g, "\n").split("\n");
var newLines, i;
// Use the map() method of Array where available
if (typeof lines.map != "undefined") {
newLines = lines.map(func);
} else {
newLines = [];
i = lines.length;
while (i--) {
newLines[i] = func(lines[i]);
}
}
textarea.value = newLines.join("\r\n");
}
var textarea = document.getElementById("your_textarea");
actOnEachLine(textarea, function(line) {
return "[START]" + line + "[END]";
});
If user is using enter key to go to next line in your text-area you can write,
var textAreaString = textarea.value;
textAreaString = textAreaString.replace(/\n\r/g,"<br />");
textAreaString = textAreaString.replace(/\n/g,"<br />");
textarea.value = textAreaString;
to simplify the answers, here is another approach..
var texta = document.getElementById('w3review');
function conv (el_id, dest_id){
var dest = document.getElementById(dest_id),
texta = document.getElementById(el_id),
val = texta.value.replace(/\n\r/g,"<br />").replace(/\n/g,"<br />");
dest.innerHTML = val;
}
<textarea id="targetted_textarea" rows="6" cols="50">
At https://www.a2z-eco-sys.com you will get more than what you need for your website, with less cost:
1) Advanced CMS (built on top of Wagtail-cms).
2) Multi-site management made easy.
3) Collectionized Media and file assets.
4) ...etc, to know more, visit: https://www.a2z-eco-sys.com
</textarea>
<button onclick="conv('targetted_textarea','destination')" id="convert">Convert</button>
<div id="destination">Had not been fetched yet click convert to fetch ..!</div>