JSFiddle - React, Tailwind, and code Playground

by maxbates

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.5/angular.min.js"></script>
<div ng-controller="myCtrl">
<textarea json-edit="myObject" rows="12"></textarea>
    <pre ng-bind="myObject | json"></pre>
</div>

CSS

.ng-invalid {
    outline: 0;
    border: 1px solid #FF0000;
}

JavaScript

var myApp = angular.module('myApp',[])
.controller('myCtrl', function ($scope) {
  $scope.myObject = {
      "firstName": "John",
      "lastName": "Smith",
      "isAlive": true,
      "age": 25,
      "height_cm": 167.64,
      "address": {
          "streetAddress": "21 2nd Street",
          "city": "New York",
          "state": "NY",
          "postalCode": "10021-3100"
      },
      "phoneNumbers": [
          { "type": "home", "number": "212 555-1234" },
          { "type": "fax",  "number": "646 555-4567" }
      ]
  };
})
.directive('jsonEdit', function () {
		return {
			restrict: 'A',
			require: 'ngModel',
			template: '<textarea ng-model="jsonEditing"></textarea>',
			replace : true,
			scope: {
				model: '=jsonEdit'
			},
			link: function (scope, element, attrs, ngModelCtrl) {

				function setEditing (value) {
					scope.jsonEditing = angular.copy(JSON2String(value));
				}

				function updateModel (value) {
                    scope.model = string2JSON(value);
				}

				function setValid() {
					ngModelCtrl.$setValidity('json', true);
				}

				function setInvalid () {
					ngModelCtrl.$setValidity('json', false);
				}

				function string2JSON(text) {
					try {
						return angular.fromJson(text);
					} catch (err) {
						setInvalid();
						return text;
					}
				}

				function JSON2String(object) {
					// better than JSON.stringify(), because it formats + filters $$hashKey etc.
					// NOTE that this will remove all $-prefixed values
					return angular.toJson(object, true);
				}

				function isValidJson(model) {
					var flag = true;
					try {
						angular.fromJson(model);
					} catch (err) {
						flag = false;
					}
					return flag;
				}

				//init
				setEditing(scope.model);

				//check for changes going out
				scope.$watch('jsonEditing', function (newval, oldval) {
					if (newval != oldval) {
						if (isValidJson(newval)) {
							setValid();
							updateModel(newval);
						} else...