<!DOCTYPE html>
<html>

<head>
  <link href="//cdn.jsdelivr.net/picnicss/4.1.1/picnic.min.css" rel="stylesheet">
  <link rel="stylesheet" href="//rawgit.com/magnumjs/mag.js/master/src/old/mag.comps.css">

  <script src="//rawgit.com/magnumjs/mag.js/master/mag.min.js"></script>
  <meta charset="utf-8">
  <title>Mag.JS</title>
</head>

<body>
  <h1>Hello Mag.JS!</h1>
  <a target="_tab" href="https://github.com/magnumjs/mag.js">GitHub</a>
  <hr/>



  <div id="CommentBox">
    <h1>Comments</h1>
    <div id="messaging">
      <div class="messages">
      </div>
    </div>
    <div id="message">
      <div><i></i> <span></span>
      </div>
    </div>
    <div id="CommentForm">
      <form class="commentForm">
        <input name="author" type="text" placeholder="Your name" />
        <input name="text" type="text" placeholder="Say something..." />
        <input class="add" type="submit" value="Post" />
      </form>
    </div>
    <div id="CommentList">
      <div class="comment">
      </div>
    </div>
    <div id="Comment">
      <h2 class="commentAuthor">
        </h2>
      <span></span>
    </div>
  </div>

  <script src="//rawgit.com/magnumjs/mag.js/master/src/old/mag.addons.js"></script>
  <script src="//rawgit.com/magnumjs/mag.js/master/src/old/mag.comps.js"></script>
  
  <script src="CommentService.js"></script>
  <script src="CommentList.js"></script>
  <script src="Comment.js"></script>
  <script src="CommentForm.js"></script>
  <script src="CommentBox.js"></script>

  <script src="app.js"></script>
</body>

</html>
var CommentBox = {}

CommentBox.controller = function(props) {

  var commentService = new props.CommentService(props)

  // load default or initial comments from service - sync with state
  this.data = props.CommentService.list(props.data);

  // callback handler on submit event
  props.handleCommentSubmit = function(comment) {
    mag.addons.sync.call(this, props.CommentService.save(comment), 'data')
  }.bind(this)

}


CommentBox.view = function(state, props) {

  mag.module('CommentList', CommentList, {
    data: Array.isArray(state.data) ? state.data : [],
    CommentService: props.CommentService,
  })

  mag.module('CommentForm', CommentForm, {
    onCommentSubmit: props.handleCommentSubmit,
    CommentService: props.CommentService
  })

}
#Mag.JS

## plunk boilerplate

** Mag.JS React 2 Mag : CommentBox **

https://facebook.github.io/react/docs/tutorial.html

Original MagJS implementation:
http://jsbin.com/davapupufo/edit?html,js,output


- CommentBox
  - Messaging
    - Messages
      - Message 
  - CommentForm
  - CommentList
    - Comment
// data model - uniform access principle


// model & service
var CommentService = function(data) {
  data = data || {}
  this.author = data.author
  this.text = data.text
}

CommentService.comments = [];

CommentService.list = function(comments) {
  //local storage implementation

  var Deferred = mag.deferred()

  setTimeout(function() {

    if (comments) {
      CommentService.comments = comments;
    }
    Deferred.resolve(CommentService.comments)
  }, 1000)

  return Deferred.promise;
}
CommentService.save = function(comment) {

  var Deferred = mag.deferred()

  setTimeout(function() {

    CommentService.list().then(function(data) {
      CommentService.comments = data.concat([comment]);

      Deferred.resolve(CommentService.comments)
    }, 500)
  })

  return Deferred.promise;
}
var CommentList = {
  view: function(state, props) {

    state.comment = props.data.map(function(comment) {
      // clone component returns a promise instance
      return mag.module('Comment', Comment, new props.CommentService(comment), true)
    }).reverse()

  }
}
var Comment = {
  view: function(state, props) {
    state.commentAuthor = props.author
    state.span = props.text
  }
}
var CommentForm = {
  controller: function(props) {

    //setup init state for ui model
    this.author = '';
    this.text = '';

    this.disableSubmit = mag.prop(false);

    // clear any visible errors
    mag.comps.messaging.MessageModel.removeAllMessage();

    props.handleSubmit = function(e) {
      e.preventDefault();
    // clear any visible errors
    mag.comps.messaging.MessageModel.removeAllMessage();
    
      if (this.author && this.text) {

        // disable submit field
        this.disableSubmit(true);

        // pass state to model
        props.onCommentSubmit(new props.CommentService(this))

        //empty the fields
        this.author = ''
        this.text = ''

      } else {
        mag.module('messaging', mag.comps.messaging.Messaging, {
          message: 'All fields are required!',
          className: 'error'
        })
      }
    }.bind(this)

  },
  view: function(state, props) {
    state.add = {
      _onclick: props.handleSubmit
    }

    mag.addons.disable.call(state, 'add', state.disableSubmit);

  }
}
var props = {
  CommentService: CommentService,
  data: [{
    "author": "Pete Hunt",
    "text": "This is one comment"
  }, {
    "author": "Michael Glazer",
    "text": "willLoad & didLoad lifecycle events needed"
  }]
}

// intialize application
mag.module("CommentBox", CommentBox, props)