15

What is the best method to change this object

{
    src: 'img.jpg',
    title: 'foo'
}

into a valid HTML tag string like this

<img src="img.jpg" title="foo" />

Solution 1

With jQuery this is easy; but complicated:

$('<img/>').attr(obj).wrap('<div/>').parent().html();

Any better ideas?

3
  • 3
    Easy but complicated? Does not sound right. If you don't like using methods why not just concatenate a string then and insert it via the .html() method? Commented Jun 27, 2013 at 3:40
  • 1
    You need to write a translator or use a pre-existing library such as: json2html.com Commented Jun 27, 2013 at 3:41
  • I meant what the method does is complicated - it wraps the img tag in a div to get the html code of that div. And the element is really created, it tries to load the img.jpg in my browser even if I don't attach it to the DOM. Commented Jun 27, 2013 at 3:42

6 Answers 6

21

Why not:

$('<img/>', obj).get(0).outerHTML;

Fiddle

You do not need to wrap it in a div using multiple functions and get the html, just use get(0) to get the DOM element and outerHTML to get the element's html representation.

Unless you are using browsers really old you can rely on outerHTML

Here is a JSPerf to compare the performance diff between the approaches.

Sign up to request clarification or add additional context in comments.

8 Comments

How safe is it to rely on outerHTML?
Okay, IE 4 sounds pretty safe :)
still +1 for coming first.
@PSL: Yes, thank you very much! I just wait if someone comes up with a simple "implode" function which is not creating an element internally before I accept your answer. I thought about the outerHTML solution before I posted the question here but discarded it because of compatibility without checking it.
|
8

Perhaps slightly more concise than PSL's?

$('<img />',object)[0].outerHTML;

1 Comment

Well no difference though. jquery internally uses array itself. jsperf.com/get-vs-array. But i would've used [0] as well, but didn't want to edit.. :) +1 though...
5

Simple with jquery

$("<div>").append($('<img />',object)).html();

5 Comments

If anyone checked that this works it is definitely a good answer
@Marc what is not a string object is really an object
The return value of $('<img />',object); is a jQuery object but I need a string containing the HTML code. This is for a template system and I can use jQuery to generate the string but cannot use the object.
$('<img />', obj)[0] or $('<img />', obj).get(0) ?!
$('<img />',object)[0].outerHTML
2

If you are only doing one element, then this solution is overkill, but I thought I would post it anyway as I don't know what your project is.

Have you considered a JavaScript template engine? I've been playing around with Swig lately, as it is quite lightweight, but there are many options. Basically, you create a template, pass a JavaScript object, and the compiled template is executed, returning a string of HTML.

Example from Swig Documentation

Template

<h1>{{ pagename|title }}</h1>
<ul>
{% for author in authors %}
  <li{% if loop.first%} class="first"{% endif %}>
    {{ author }}
  </li>
{% else %}
  <li>There are no authors.</li>
{% endfor %}
</ul>

JavaScript to Render Template

var template  = require('swig');
var tmpl = template.compileFile('/path/to/template.html');
tmpl.render({ // The return value of this function is your output HTML
    pagename: 'awesome people',
    authors: ['Paul', 'Jim', 'Jane']
});

Output

<h1>Awesome People</h1>
<ul>
  <li class="first">Paul</li>
  <li>Jim</li>
  <li>Jane</li>
</ul>

Comments

1

Making html elements based out of objects containing attribute-attribute values such as

{
    src: 'img.jpg',
    title: 'foo'
}

almost completely falls into the paradigm of cook.js.
The command which you would issue with cook would be:

img ({
    src: 'img.jpg',
    title: 'foo'
})

If the attribute details are stored as given in your example,
in a variable obj then:

img(obj)

For more details check it out at cook.relfor.co.

1 Comment

to get the outerhtml property use .outerHTML, this would look like img(''').outerHTML
0

Here's how you make it as a string:

var img = '<img ',
    obj = { src : 'img.jpg', title: 'foo' };

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    img += prop + '=' + '"' + obj[prop] + '" ';
  }
}

img += '/>';

http://jsfiddle.net/5dx6e/

EDIT: Note that the code answers the precise question. Of course it's unsafe to create HTML this way. But that's not what the question asked. If security was OP's concern, obviously he/she would use document.createElement('img') instead of a string.

EDIT 2: For the sake of completeness, here is a much safer way of creating HTML from the object:

var img = document.createElement('img'),
    obj = { src : 'img.jpg', title: 'foo' };

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    img.setAttribute(prop, obj[prop]);
  }
}

http://jsfiddle.net/8yn6Y/

6 Comments

This is a bad idea. Your code does not take into account escaping values for HTML! Depending on where that data comes from, you could be opening yourself up for XSS attacks, or at least some broken code.
@Brad The code accomplishes precisely what the question asked. It creates a string of HTML with the given object. Your downvote is misplaced.
It creates a string of potentially invalid HTML. My downvote is not misplaced at all.
@Brad Explain how there is a potential for invalid HTML resulting from this code? There is literally one and only one possible result.
{title: '"/><script>alert(\'XSS!\');</script>'}
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.