Skip to content

Commit

Permalink
added attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewmueller committed Dec 10, 2012
1 parent 1582f02 commit 5ca624f
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 10 deletions.
55 changes: 52 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# json-to-dom

Fill in DOM nodes with JSON. Supports arrays.
Fill in DOM nodes with JSON. Supports arrays and attributes.

## Example

Expand Down Expand Up @@ -73,8 +73,6 @@ document.body.innerHTML = body.innerHTML;

## Design

json-to-dom assumes the tags you are interested in are **classes** and that you are looking to replace `innerText`. *I'm looking for ways to make this more flexible.*

### Arrays

#### json-to-dom will iterate over the selected block, even if you don't have any matched tags:
Expand Down Expand Up @@ -161,6 +159,8 @@ var email = {
to : 'matt@matt.com',
message : 'Reply with your bank credentials so we can send you the money'
}

render(document.querySelector('.email'), email)
```

outputs:
Expand All @@ -174,6 +174,55 @@ outputs:
</div>
```

### Setting attributes

json-to-dom will also work with attributes. The supported attributes are:

* `data-html` : will set the `innerHTML`
* `data-text` : will set the `innerText` (the default)
* `data-[attr]` : will set the `attr` (ex. `data-value`)

When you use data attributes, you have access to the other keys in the object block.

```html
<div class="note">
<a class="title" data-href="url"></a>
</div>
```

```js
var note = {
title : "This is a note",
url : "http://notes.com"
}

render(document.querySelector('.note'), note);
```

outputs:

```html
<div class="note">
<a class="title" href="http://notes.com">This is a note</a>
</div>
```

If you'd like to not add the `innerText`, simply use a data attribute with the name of the class:

```html
<div class="note">
<a class="title" data-href="title"></a>
</div>
```

outputs:

```html
<div class="note">
<a class="title" href="this is a note"></a>
</div>
```

## License

MIT
51 changes: 46 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ var isArray = require('isArray'),

module.exports = json_to_dom;

/**
* Dataset mappings
*/

var map = {
'text' : 'innerText',
'html' : 'innerHTML'
};

/**
* json-to-dom
*
Expand All @@ -19,7 +28,8 @@ module.exports = json_to_dom;
* @return {DomNode}
*/

function json_to_dom(el, val, key) {
function json_to_dom(el, val, key, obj) {
obj = obj || {};
var node = el;

if(key && typeof key == 'string')
Expand All @@ -40,14 +50,45 @@ function json_to_dom(el, val, key) {
} else if(isObject(val)) {
for(var k in val) {
if(val.hasOwnProperty(k)) {
json_to_dom(node, val[k], k);
json_to_dom(node, val[k], k, val);
}
}
} else {
var keyNode = node.querySelector('.key');
if(typeof key != 'number') return node.innerText = val;
else if(keyNode) keyNode.innerText = val;
var keyNode = node.querySelector('.key'),
dataset = node.dataset,
values = [];

Object.keys(dataset).forEach(function(attr) {
var dsv = dataset[attr],
val = obj[dsv] || val;
delete dataset[attr];
attr = map[attr] || attr;
if(keyNode) set(keyNode, attr, val);
else if(typeof key != 'number') set(node, attr, val);
values.push(dsv);
});

if(!values.length || !~values.indexOf(key)) {
if(keyNode) set(keyNode, 'innerText', val);
else if(typeof key != 'number') set(node, 'innerText', val);
}
}

return el;
}

/**
* Set
*/

function set(node, attr, val) {
switch(attr) {
case 'innerHTML':
case 'innerText':
node[attr] = val;
break;
default:
node.setAttribute(attr, val);
}
return node;
}
25 changes: 23 additions & 2 deletions test/json-to-dom.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
var render = require('json-to-dom'),
var render = require('json-to-dom'),
assert = require('component-assert');

var note = {
title : 'this is a note',
url : 'http://note.com',
date : new Date(),
tags : [ 'javascript', 'travel' ],
authors : [
Expand Down Expand Up @@ -100,13 +101,33 @@ describe('render', function() {

it('should handle arrays as the initial value', function() {
html.innerHTML = '<div class="people"><span class="first">First Name</span><span class="last">Last Name</span></div>';
// console.log(html.firstChild);
html = render(html.firstChild, [
{ first : "matt", last : "mueller" },
{ first : "andrew", last : "quinn" }
]);
var expected = '<div class="people"><span class="first">matt</span><span class="last">mueller</span><span class="first">andrew</span><span class="last">quinn</span></div>';
assert(html.outerHTML === expected);
});

it('should replace attributes with data-attr', function() {
html.innerHTML = '<div class="authors"><input class="name" data-value="name" type="text"/></div>';
html = render(html, note);
var expected = '<div class="authors"><input class="name" type="text" value="matt"><input class="name" type="text" value="andrew"></div>';
assert(html.innerHTML === expected);
});

it('should replace attributes with anything in the object', function() {
html.innerHTML = '<a data-href="url" class="title"></a>';
html = render(html, note);
var expected = '<a class="title" href="http://note.com">this is a note</a>';
assert(html.innerHTML === expected);
});

it('should replace attributes with anything in the object', function() {
html.innerHTML = '<a data-href="url" class="title" data-alt="title"></a>';
html = render(html, note);
var expected = '<a class="title" href="http://note.com" alt="this is a note"></a>';
assert(html.innerHTML === expected);
});
});

0 comments on commit 5ca624f

Please sign in to comment.