tags:

views:

119

answers:

3

On the my page I have html like this:

hi<br>bye<br>sigh<br>hello <em>tie</em><br>lie 

with jquery, how can I convert it to html like this (basically using p's instead of br's):

<p>hi</p><p>bye</p><p>sigh</p><p>hello <em>tie</em></p><p>lie</p> 

My first attempt at doing this was this code:

$(container).contents().filter(function() {
                var val = this.nodeValue;
                return this.nodeType == TEXT_NODE && $.trim(val).length > 0;
            })
            .wrap('<p></p>')
            .end()
            .filter('br')
            .remove();

This worked for the most part, except that hello and <em>tie</em> would not be in the same p element.

Does anyone know how I can do this properly?

+1  A: 

simple javascript solution

var obj = document.getElementById('container');
var str = obj.innerHTML;
var ar = str.split('<br />');
var result = "";
for(var i = 0; i < ar.length; i++)
{
 result .= '<p>'+ar[i]+'</p>';
}
obj.innerHTML = result;

I don't know how to do this with jQuery...

TriLLi
It is do-able in jQuery, but its going to be longer than this anyways. Sometimes the library doesn't help.
Austin Fitzpatrick
thanks, this looks good, is it cross browser compatible?
Kyle
A lot of people don't know the difference anymore. http://stackoverflow.com/questions/423823/whats-your-favorite-programmer-ignorance-pet-peeve/2657095#2657095
harpo
No. When you fetch `innerHTML` the browser may give you a `br` tag in various different serialisation formats. You are likely to get `<br>` or `<BR>` or even conceivably `<br/>`, but nothing would give you `<br />`.
bobince
yes probably you are right, but if you want more advanced version you can use Regular expression for splitting string. I have just added example how to solve one problem. with regex you can split string like this (<br>)|(<BR>)|(<br />)|(<BR />) I'm not so sure is this working now, i don't have time to check but this should be probably right answer.
TriLLi
(If you've touched the element's data with jQuery, you could even get `<BR jQuery123=456>` in IE...)
bobince
you can write regular expression for catching br tag with any attribute in it. if you need help writing regex I can help you later, now I need to sleep, working day tomorrow.
TriLLi
I really don't think this is a good approach ...
SamB
A: 
'<p>'+html.replace(/<br\s?\/?>/gi,'</p><p>')+'</p>'

never tested. but thats the idea.

Funky Dude
This isn't "doing it with jQuery" but it gets my vote anyway.
fsb
This doesn't look like a good way either...
SamB
care to explain SamB?
Funky Dude
+1  A: 

You were along the right lines, only there's not a convenient way(*) to wrap a range of children rather than just one at a time. You'd have to do it yourself, eg.:

// Take a range of children in a parent element and wrap them in a new element.
//
function wrapChildren(tagname, parent, child0, child1) {
    var wrapper= document.createElement(tagname);
    for (var i= child1-child0; i-->0;)
        wrapper.appendChild(parent.childNodes[child0]);
    parent.insertBefore(wrapper, parent.childNodes[child0]);
}

// Find `<br>`s and wrap the stretches between them.
//
var container= document.getElementById('container');
var lastbr= container.childNodes.length;
for (var i= lastbr; i-->0;) {
    var child= container.childNodes[i];
    if (child.nodeType===1 && child.tagName.toLowerCase()==='br') {
        wrapChildren('p', container, i+1, lastbr);
        container.removeChild(child);
        lastbr= i;
    }
}
wrapChildren('p', container, 0, lastbr);

(*: jQuery or otherwise. Well, there is surroundContents in DOM Range, but support is poor.)

bobince
what about wrapAll? http://api.jquery.com/wrapAll/
Kyle
hmm, I hadn't spotted that one. You can *nearly* do it very nicely with `wrapAll`+`nextUntil`, except that it won't select the text nodes (a lot of jQuery can't do anything with text nodes, unfortunately).
bobince