Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="ViewModel event bindings">
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
 <style>
   my-input {
     display: inline-block;
     
   }
   my-input div {
     height: 18px;
     width: 140px;
     background-color: white;
     border: solid 1px black;
   }
  </style>
  
<div id='out'></div>
<script id="my-input-template"
        type="text/stache">
 <div 
   ($keydown)='updateValue(%event)'
   tabindex='0'>{{value}}</div> 
</script>
  
<script id="app" type="text/stache">
<person-edit>
  <h3>Name: {{name}}</h3>
  <p> Custom: 
      <my-input {value}="name"
                (value)="updateNameOnEven(%viewModel.value)"/> 
  </p>
  <p> Native: 
      <input {$value}="name"
             ($input)="updateNameOnEven(%element.value)"/> 
  </p>
</person-edit>
</script>
  
  
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.js"></script>
<script src="//canjs.com/release/2.3.2/can.jquery.js"></script>
<script src="//canjs.com/release/2.3.2/can.stache.js"></script>
</body>
</html>
 
can.Component.extend({
  tag: "my-input",
  template: can.view("my-input-template"),
  viewModel: {
    value: "",
    updateValue: function(event){
      event.preventDefault();
      var cur = this.attr("value");
      if(event.keyCode === 8) {
        this.attr("value",cur.substr(0,cur.length-1));
      } else {
        var key = String.fromCharCode(event.keyCode);
        if(!event.shiftKey) {
          key = key.toLowerCase();
        }
        this.attr("value",cur+key)       
      }
    }
  }
})
can.Component.extend({
  tag: "person-edit",
  viewModel: {
    name: "Justin",
    updateNameOnEven: function(newName){
      if(newName.length % 2 === 0) {
        this.attr("name", newName);
      }
    }
  }
})
$("#out").html( can.view("app",{}) );
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x