Memento Example

In this example below you will see how to do a Memento Example with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by Frontender, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright Frontender ©
  • HTML
  • CSS
  • JavaScript
    <h1>Memento Example</h1>
<p>This pattern provides the ability to restore an object to its previous state. Memento is implemented with three objects: the Originator, a Caretaker and a Memento. The Originator is some object that has an internal state. This internal state can be saved in a Memento object. The Caretaker first asks the Originator for a Memento object and stores it. Then some actions are performed on the Originator. To roll back to the state before the actions, Caretaker returns the corresponding Memento object to the Originator. The Memento object itself is an opaque object (the Caretaker cannot, or should not, change it).</p>
<button id="sender1">Underline Text</button>
<button id="sender2">Strong Text</button>
<button id="sender3">Italic Text</button>
<button id="sender4">Undo</button>
<button id="reset">Reset</button>
<br><br>
<div id="result">
No result. Press a button above.
</div>
<br>
<div class="items" id="logs">
  <header>Logs:</header>
</div>
<br> 

/*Downloaded from https://www.codeseek.co/curveball/memento-example-XpeVqv */
    body {padding:10px;}
#receiver {
  border:1px solid gray;
  width:25%;
  margin-top:1em;
  padding: 5px;
}
div.items {
  overflow:auto; 
  padding:10px; 
  border:1px solid #222; 
  margin-top:10px; 
  display:inline-block;
}
div.items div, div.items header {
  border-bottom:1px solid #000;
  margin-bottom:10px;
}


/*Downloaded from https://www.codeseek.co/curveball/memento-example-XpeVqv */
    // Originator
function Text(text) {
  var txt = text;
  this.getText = function() {
  return txt;
  }
  this.underline = function() {
  txt = '<u>' + txt + '</u>';
  }
  this.strong = function(text) {
  txt = '<b>' + txt + '</b>';
  }
  this.italic = function(text) {
  txt = '<i>' + txt + '</i>';
  }  
  this.storeState = function(action) {
  return new Memento(txt, action);
  }  
  this.restoreState = function(memento) {
  if(!memento) return;
  setup.addRecord(memento, true);  
  txt = memento.getState();  
  }  
}
// Memento
function Memento(txt, action) {
  var state = txt;
  var action = action;
  this.getState = function() {
    return state;
  }
  this.getAction = function() {
    return action;
  } 
}
// CareTaker
function CareTaker() {
  this.results = [];
  this.setMemento = function(memento) {
    this.results.push(memento);
    setup.addRecord(memento);
  }
  this.getMemento = function() {
    return this.results.pop();
  }
}
// Run it all
function Setup() {
   this.logCont = document.getElementById('logs');
   this.resCont = document.getElementById('result');
}
Setup.prototype.run = function() {

  var text = prompt('Insert some text', ''); 
  var _this = this;
  var txt = new Text(text);
  var careTaker = new CareTaker();
  this.showResult(txt.getText());
  
  var btn1 = document.getElementById("sender1");
  btn1.addEventListener("click", function() {
  careTaker.setMemento(txt.storeState('Underline text'));  
  txt.underline(text);
  _this.showResult(txt.getText()); 
  });
  var btn2= document.getElementById("sender2");
  btn2.addEventListener("click", function() {
  careTaker.setMemento(txt.storeState('Strong text'));  
  txt.strong(text);
  _this.showResult(txt.getText());
});
  var btn3 = document.getElementById("sender3");
  btn3.addEventListener("click", function() {
  careTaker.setMemento(txt.storeState('Italic text'));  
  txt.italic(text);
  _this.showResult(txt.getText());
  });
  var btn4 = document.getElementById("sender4");
  btn4.addEventListener("click", function() { 
  txt.restoreState(careTaker.getMemento());
  _this.showResult(txt.getText());
  });
  
  var reset = document.getElementById("reset"); // clean table
  reset.addEventListener("click", function() {
  _this.removeResult();
  _this.removeMsg(_this.logCont);
  });
}
Setup.prototype.showResult = function(res) {
  this.resCont.innerHTML = res;
}
Setup.prototype.removeResult = function() {
  this.resCont.innerHTML = 'No result. Press a button above.';
}
Setup.prototype.addRecord = function(memento, undo) { // add record 
  var record = document.createElement('div');
  var msg = '';
  if(undo) var msg = 'Undone '; 
  record.textContent = msg + memento.getAction();
  this.logCont.appendChild(record);
}
Setup.prototype.removeMsg = function(elem) {
  var msgs = Array.prototype.slice.call(elem.children);
  msgs.forEach(function(element, index, array) {
   if(msgs[index].tagName != 'header'.toUpperCase()) {
     msgs[index].remove();
   }
  });  
}
var setup = new Setup();
setup.run(); 

Comments