11

Two-way data binding refers to the ability to bind changes to an object’s properties to changes in the UI, and vice-versa.

Can we achieve 2-way data-binding with JavaScript?

Especially 2 Way Data Binding without Frameworks.

2
  • Probably, using getters and setters. Commented Aug 3, 2017 at 16:37
  • yes! for example angular use two way binding between your UI and a controller Commented Aug 3, 2017 at 16:37

6 Answers 6

33

When an input is changed update the value, add a setter to the value which sets the inputs content. E.g this element:

<input id="age">

And some js:

var person = (function(el){
 return {
   set age(v){
    el.value = v;
   },
   get age(){
     return el.value;
   }
 };
})(document.getElementById("age"));

So you can do:

 person.age = 15;

And the input will change. Changing the input changes person.age

Sign up to request clarification or add additional context in comments.

5 Comments

Did you mean setAge(v) and getAge()?
@GabrielWest no i didnt.
@JonasWilms How do I check that input changes person.age? I tried adding a log statement inside set age() { } but it did not work.
@overlord it does not. Accessing person.age retrieves the updated value from the input.
Can you please explain in Detail how does it work ?
6

Simple and working approach to two-way binding, only using vanilla JS.

<!-- index.html -->
<form action="#" onsubmit="vm.onSubmit(event, this)">
    <input onchange="vm.username=this.value" type="text" id="Username">
    <input type="submit" id="Submit">
</form>
<script src="vm.js"></script>

// vm.js - vanialla JS
let vm = {
    _username: "",
    get username() {
        return this._username;
    },
    set username(value) {
        this._username = value;
    },
    onSubmit: function (event, element) {
        console.log(this.username);
    }
}

JS Getters and Setters are quite nice for this - especially when you look at the browser support.

Comments

5

Yes, we can achieve the two way data binding using pure javascript.

twoWay=function(event) {
  var elem = document.getElementsByClassName(event.currentTarget.className);
  for(var key in elem){
    elem[key].value=event.currentTarget.value;
  }
}

You can check the jsfiddle.

Comments

1

Yes indeed. There are frameworks like angular Js which provides full support for two way data binding. And if you want to achieve the same in vanilla js you can bind value into view

Eg. document.getElementById('test').value="This is a Test"

And to bind view value to the controller you can trigger onchange event in html.

 <Input type="text" id="test" onchange="Func()">

1 Comment

youre mixing jquery and vanillaJS
1

Adding a little elaboration to Jonas Wilms answer, here's a sample without currying and also adds event binding for a full two way bind.

// Property binding
var person = { 
  set name(v) {
    document.getElementById('name').value = v;
  },
  get name() {
    return document.getElementById('name').value;
  },
  set age(v) {
    document.getElementById('age').value = v;
  },
  get age() {
    return document.getElementById('age').value;
  }
};

// You can now set values as such
person.name = 'Cesar';
person.age = 12;

// Event binding completes the two way
function logToConsole(event) { 
  console.log(event.target.value);
}

// You can set person.name or person.age in console as well.
<label for="name">Name: </label><input id="name" onkeyup="logToConsole(event)">
<label for="age">Age: </label><input id="age" onkeyup="logToConsole(event)">

Comments

-1

Would you mind if it would be a small component for databinding tasks that provides enough convenient databinding definition commands. I did it with databindjs. e.g.

// Lets assume that there is just simple form (target)
var simpleForm = {
   input: $('.simple .input-value'),
   output: $('.simple .output-value')
};
// And here is the simple model object (source)
var model = {
    text: 'initial value'
};

// Lets set two directional binding between [input] <-> [text]
var simpleBinding = bindTo(simpleForm, () => model, {
    'input.val': 'text',  // bind to user input
    'output.text': 'text'  // simple region that will react on user input
});
// This command will sync values from source to target (from model to view)
updateLayout(simpleBinding);
subscribeToChange(simpleBinding, () => {
    $('.simple .console').html(JSON.stringify(model));
});
// Just initialize console from default model state
$('.simple .console').html(JSON.stringify(model));

The full solution here. You can check the full implementation of the databinding core on github

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.