JSFiddle - React, Tailwind, and code Playground

by eddiriarte

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div ng-app="app" ng-controller="mergeController">
  <table class="table table-condensed table-striped">
    <thead>
      <tr>
        <th>Property</th>
        <th>Object A</th>
        <th>Object B</th>
        <th>Merged Object</th>
      </tr>
    </thead>
    <tr ng-repeat="property in diffObj.props">
      <th>{{property}}</th>
      <td>
        <div class="merge-action" ng-click="diffObj.toMerge(property, 'objA', $event)">
          {{diffObj.getValue(property, 'objA')}}
        </div>
      </td>
      <td>
        <div class="merge-action" ng-click="diffObj.toMerge(property, 'objB', $event)">
          {{diffObj.getValue(property, 'objB')}}
        </div>
      </td>
      <td>{{diffObj.getValue(property, 'objC')}}</td>
    </tr>
  </table>

  <input class="btn btn-primary pull-right col-xs-3" id="submit" type="button" value="Save Merge" ng-click="merge()">

</div>

CSS

.merge-action {
  padding: 2px 6px;
}

.merge-action:hover,
.merge-action.active {
  color: white;
  background: #9b59b6;
}

JavaScript

var app = angular.module('app', []);

app.controller("mergeController", [
  '$scope',
  function($scope) {

    $scope.test = true;

    $scope.objA = {
      name: 'my name',
      online: true,
      friends: [{
        id: 1,
        title: 'A'
      }, {
        id: 2,
        title: 'B'
      }, {
        id: 3,
        title: 'C'
      }]
    }

    $scope.objB = {
      name: 'other',
      online: false,
      friends: [{
        id: 4,
        title: 'D'
      }, {
        id: 5,
        title: 'E'
      }, {
        id: 6,
        title: 'F'
      }]
    }

    function Diff() {
      this.objA = {};
      this.objB = {};
      this.objC = {};
      this.props = [];
      this.settings = {};
      this.initialize = function(objA, objB) {
        var me = this,
          propsB = Object.keys(objB);
        me.props = Object.keys(objA);
        me.objA = objA;
        me.objB = objB;
        angular.forEach(propsB, function(item) {
          if (me.props.indexOf(item) === -1) {
            me.props.push(item);
          }
        });
      };
      this.getValue = function(prop, obj) {
        if (this[obj].hasOwnProperty(prop)) {
          return this.doFormat(this[obj][prop]);
        }
        return "";
      };
      this.doFormat = function(value) {
        if (typeof value === 'undefined' || value === null) {
          return "";
        }

        if (typeof value === 'boolean') {
          return (!!value) ? 'yes' : 'no';
        }

        if (typeof value === 'object' && Array.isArray(value)) {
          var list = [];
          angular.forEach(value, function(item) {
            list.push('Friend(' + item.id + ', ' + item.title + ')');
          });
          return (list.length >= 1) ? list.join(', ') : '----';
        }

        return value;
      };
      this.toMerge = function(prop, obj, $event) {
        var me = this
        mrg = me.settings;

        if (!mrg.hasOwnProperty(prop)) {
          mrg[prop] = {
            type:...