Mobx without a framework

by amindunited

HTML

<script src="https://npmcdn.com/[email protected]/lib/mobx.umd.js"></script>
<body>
  <div id="mount">
    <div id="taskListView">
      <h2>
        Tasks List
      </h2>
    </div>
    <div id="taskCreatorView">
      <h2>
        Add A Task
      </h2>
      <input type="text"/>
      <button>
        Add
      </button>
    </div>
  </div>
</body>

CSS

ul {
  list-style-type: none;
  margin: 0px;
  padding: 0px;
}
#mount {
  display: flex;
}
#taskListView, #taskCreatorView {
  width: 50%;
  background-color: #efefef;
  border: solid 1px #363636;
  border-radius: 3px;
  padding: 3% 3% 10% 3%;
}

#taskListView > ul > li {
  padding: 3px 6px;
  margin-top: 2%;
  margin-bottom: 2%;
  border: solid 1px rgba(127, 127, 127, 0.2);
  border-radius: 3px;
}
.x {
  float: right;
}

Babel + JSX

const {observable, computed, autorun} = mobx;

/*
 * Declare an object store
 * (just a list of tasks)
 */
class Store {
	@observable tasks = [{name:'placeholder 1'}, {name:'placeholder 2'}];
}

/*
 * Display a list of tasks
 * (listens to and redraws list when it updates)
 */
class TaskListView {
  constructor(store) {
  	this.tasks = store.tasks;
    this.redrawTemplate();
    //This is where the magic happens: OBSERVE!
    this.tasks.observe(()=>{
      this.redrawTemplate();
    });
  }
  
  addEventListeners() {
  	//this.removeEventListeners();
    let ul = document.querySelector('#taskListView > ul');
    ul.addEventListener('click', (e) => {
    	console.log('remove click', e.target.getAttribute('data-task'));
      let data = e.target.getAttribute('data-task');
    	this.removeTask(JSON.parse(data));
    });
  }
  
  removeEventListeners() {
  	let ul = document.querySelector('#taskListView > ul');
  	ul.removeEventListener();
  }
	//This is just a boring html redraw
	redrawTemplate () {
  	let containerDiv = document.getElementById('taskListView');
    //clear container
    if (containerDiv.getElementsByTagName('ul').length) {
    	containerDiv.removeChild(containerDiv.getElementsByTagName('ul')[0]);
    }
    let parentDiv = document.createElement('ul');
    containerDiv.appendChild(parentDiv);
    this.tasks.map((task)=>{
      let elm = document.createElement('li');
      elm.innerHTML = 'Name: ' + task.name + '<button class="x">X</button>';
      parentDiv.appendChild(elm);
      let closeButton = parentDiv.querySelector('button');
      closeButton.setAttribute('data-task', JSON.stringify(task));
    });
    
    this.addEventListeners();
    
  }
  
  removeTask (obj) {
    console.log('removeTask', obj);
    this.tasks.find((val, key)=>{
	    console.log('testing ', val.name, obj.name);
    	if (obj.name === val.name) {
      	this.tasks.splice(key, 1);
      	return true;
      }
      return false;
    });
    this.redrawTemplate();
  }
}

/*
...