Two Way Data Binding in JavaScript

Two Way Data Binding in JavaScript
Code Snippet:Two way data binding
Author: Joshua Simmons
Published: January 12, 2024
Last Updated: January 22, 2024
Downloads: 348
License: MIT
Edit Code online: View on CodePen
Read More

This JavaScript code snippet demonstrates two-way data binding with real-time updates. It dynamically syncs data between the input box and a counter. The Observable class facilitates seamless communication between models and views, ensuring instant feedback. Watch the input box and counter values effortlessly stay in sync.

You can integrate this snippet in web forms for instant feedback. Moreover, you can easily modify the code according to your project’s requirements.

How to Create a Functionality for Two-Way Data Binding in JavaScript

1. Create a structured HTML layout with an input box, a button for triggering changes, and elements for displaying data.

<div class="center">
<h1>Fancy Two Way Data 
  <span id="input-watcher">Binding</span>
  </h1>
<p>Time Elapsed <span id="watcher">0</span></p>
<input id="input-box" style="width: 100px">
    <button id="collapse-button">
  Change
  </button>
</div>

2. Style the basic interface using the following CSS styles: (Optional)

body {
  font-family: "Space Mono", monospace;
}

.center {
  text-align: center;
}

#input-box {
  transition-property: width;
  transition-duration: 1s;
}

button {
  background-color: teal;
  padding: 7px;
  border-style: none;
  border-radius: 3px;
  color: white;
}

button:focus {
  outline: 0;
}

3. In the JavaScript section, the code begins by defining an Observable class for data tracking. Create instances for your data, like the bound counter and input binding.

Set up observers to track changes. For instance, the counterWatcher observes the bound counter, while the inputCollapseWatcher manages changes in the input box’s visibility and width.

Apply this code to web forms or interactive elements where instant data feedback is crucial. It’s particularly useful for dynamic interfaces, offering a responsive and user-friendly experience.

document.addEventListener("DOMContentLoaded", function (event) {
  //Observable class is something that has a value and can be watched by Observers and dom elements for changes
  let Observable = function (startValue) {
    let value = startValue || undefined;
    let observersModels = [];
    let observersViews = [];
    let notifyViews = () => {
      observersViews.forEach(d => {
        d.innerHTML = value;
      });
    };
    let notifyModels = () => {
      observersModels.forEach(d => {
        d.notify(value);
      });
    };
    let notify = () => {
      notifyModels();
      notifyViews();
    };
    let updateValue = d => {
      value = d;
      notify(value);
    };
    let getValue = () => value;
    let addObserveView = view => {
      observersViews.push(view);
    };
    let addObserveModel =
    observer => {
      if (observer.preNotify === true)
      observer.notify(value);
      observersModels.push(observer);
    };

    return {
      //updates value and notifies that the property changed
      updateValue,
      getValue,
      //add a DOM node that is synced with the value
      addObserveView,
      //add an Observer that with call it's callback when the value changes.
      addObserveModel };

  };

  let Observer = function (notifyCallback, preNotify) {
    let notify = notifyCallback;
    return {
      notify,
      preNotify };

  };

  //value that is going to keep track of a counter variable
  let boundCounter = new Observable(0);

  //an observer that listens and prints the new value when it recieves it
  let counterWatcher = new Observer(value => console.log(`viewWatcher1 noticed change to ${value}`));

  //have the counterWatcher added as an Observer to the bound counter
  boundCounter.addObserveModel(counterWatcher);
  //make the #watcher dom element listen for changes to the value of bound counter
  boundCounter.addObserveView(document.querySelector("#watcher"));

  //a loop that increases the value of the counter by one every second
  //notice how no DOM elements are modified in this code.
  let i = 0;
  setInterval(() => {
    boundCounter.updateValue(i += 1);
  }, 1000);

  //a new and different Observable
  let inputBind = new Observable();
  //the DOM element for the input box
  let inputNode = document.querySelector("#input-box");

  //add event listener to the #input-box element that updates the inputBind Obserable whenever you release a key.
  inputNode.addEventListener('keyup', e => {
    inputBind.updateValue(inputNode.value);
  });

  //add the #input-watcher element as an observer on the inputBind Observable
  inputBind.addObserveView(document.querySelector('#input-watcher'));

  let collapseObservable = new Observable(true);
  let collapseNode = document.querySelector('#collapse-button');

  collapseNode.addEventListener('click', e => {
    collapseObservable.updateValue(!collapseObservable.getValue());
  });

  let inputCollapseWatcher = new Observer(value => {
    if (value === true) {
      inputNode.style.width = 0;
      setTimeout(() => {
        inputNode.style.visibility = "hidden";
      }, 1000);
      inputNode.readOnly = true;
    } else {
      inputNode.style.visibility = "visible";
      inputNode.style.width = '100px';
      inputNode.readOnly = false;
    }

  }, true);

  collapseObservable.addObserveModel(inputCollapseWatcher);
});

That’s all! hopefully, you have successfully created Two Way Data Binding Javascript. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...

Please Rel0ad/PressF5 this page if you can't click the download/preview link

X