In wanting to learn Polymer, Google’s open-source framework focused on bringing web components to the web, I decided to rewrite an Angular directive, the json-editor.

It is a simple textarea (specifically, Polymer core-input element) for editing JSON objects, with a few simple improvements:

  • Adding whitespace (i.e. matching /\s+/ ) will not move cursor to end of input.
  • Use the autofit attribute to have the textarea scale and fit as needed.

JSON can be passed in via attribute using Polymer’s data binding, for example:

<json-editor rows="5" json="{{myJsonData}}" autofit></json-editor>

Putting it on codepen is a little tricky, since polymer doesn’t make its component library accessible accessible via CDN (just the javascript), but here’s a link and the code

Working Example

 1 <link rel="import" href="../polymer/polymer.html">
 2 <link rel="import" href="../core-input/core-input.html">
 3 
 4 <!--
 5 Simple textarea for editing JSON objects, with a few simple improvements.
 6 
 7 Adding whitespace (i.e. matching /\s+/ ) will not move cursor to end of input.
 8 
 9 Use the autofit attribute to have the textarea scale and fit as needed.
10 
11 ##### Example
12 
13     <json-editor rows="5" json="{{myJsonData}}" autofit></json-editor>
14 
15 @element json-editor
16 @blurb Simple textarea for editing JSON objects
17 @status alpha
18 @homepage http://maxbates.github.io/json-editor
19 -->
20 <polymer-element name="json-editor" attributes="json">
21   <template>
22     <link rel="stylesheet" href="json-editor.css">
23     <div class="json-editor {{ {'has-focus': focused, 'has-error': errored} | tokenList }}">
24       <template if="{{errored}}">
25         <div class="help">{{errored}}</div>
26       </template>
27       <core-input multiline
28                   placeholder="Enter JSON"
29                   on-focus="{{onFocus}}"
30                   on-blur="{{onBlur}}"
31                   rows="{{rows}}"
32                   inputValue="{{text}}">
33       </core-input>
34     </div>
35   </template>
36   <script>
37     (function () {
38       'use strict';
39 
40       var whitespaceResetRegex = /\s+/g;
41 
42       Polymer({
43         text : '',
44         focused : false,
45         errored : false,
46 
47         //default values instead of using attributes attribute in element declaration
48         publish: {
49           rows: 1,
50           autofit: false
51         },
52 
53         //declare in attributes at top so can set it with binding, hint it here
54         created : function () {
55           this.json = {};
56         },
57 
58         //change watchers
59         jsonChanged : function (oldval, newval) {
60           this.text = JSON.stringify(newval, null, 2);
61         },
62         textChanged : function (oldval, newval) {
63           if (this.autofit) {
64             this.rows = newval.split('\n').length;
65           }
66 
67           try {
68             //check to make sure we've added new characters, not just whitespace
69             //e.g. adding a space results in a valid json, and moves cursor to end of box
70             if (newval.replace(whitespaceResetRegex, '') !=  oldval.replace(whitespaceResetRegex, '')) {
71               this.json = JSON.parse(newval);
72               this.errored = false;
73             }
74           } catch(evt) {
75             this.errored = evt;
76           }
77         },
78 
79         //event handlers
80         onFocus : function (evt) {
81           this.focused = true;
82         },
83         onBlur : function (evt) {
84           this.focused = false;
85         }
86       });
87 
88     })();
89   </script>
90 </polymer-element>

This was my first time playing with Polymer, and there was a good amount of new syntax to learn, because while the concepts are similar to those of Angular, the ideology is different when working under the paradigm “everything is a component”, and striving to build apps without requiring much (if any) custom javascript.

All in all, curious to see where Angular goes with 2.0, and how it ties into web components and all the other goodness of ES6. There’s been talk both about the two frameworks coming together, and staying separate and addressing their separate needs. I’m still in camp Angular, and once web components are widely supported, and Angular’s syntax for declaring them simplifies, I think it’ll come more in line with Polymer’s current syntax, and we’ll see some melding.