npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

stimulus-data-bindings

v1.3.2

Published

One-way data binding controller for stimulus.js

Downloads

435

Readme

Stimulus Data Bindings

Stimulus controller to provide one-way data bindings from form input. Automatically sets bindings on connection to the DOM, and can perform updates on any event via a data-action attribute.

Installation

$ yarn add stimulus-data-bindings

Usage

Register the controller with Stimulus:

// application.js
import { Application } from "@hotwired/stimulus";
import { DataBindingController } from "stimulus-data-bindings";

const application = Application.start();
application.register("data-binding", DataBindingController);

Initialize the controller on a container element, then add bindings:

<div data-controller="data-binding">
  <form>
    <input
      type="text"
      data-action="change->data-binding#update"
      data-binding-target="output"
      data-binding-property="textContent"
      data-binding-value="$source.value"
      data-binding-debug="true"
    />
  </form>
  <div class="output">
    <div data-binding-ref="output" />
  </div>
</div>

All input elements to be bound require at least a data-action calling the update method, a data-binding-target specifying the target element, and either a data-binding-property to set a property on the target, or a data-binding-attribute to set an attribute.

Optionally data-binding-condition can be passed, to only set the property/attribute if the condition evaluates to true. Also data-binding-value can be passed, to set the value of the target property/attribute.

multiple properties and attributes can be used separated by a space, as well as multiple targets.

Most data attributes (property, attribute, value, and condition) can be set on the target. When set on both the target and the source, target will override the source.

Options

data-binding-debug

e.g: data-binding-debug="true"

Set this to true to have helpful debug information logged to the console. We strongly recommend having this switched on when setting up your bindings, then set to false or remove when you're happy its working.

data-binding-target

e.g: data-binding-target="my-target"

The target element(s) to alter. any element that has a data-binding-ref of this value will match. Multiple elements can match.

data-binding-property

e.g: data-binding-property="textContent"

The property(s) of the target element to set.

data-binding-attribute

e.g: data-binding-attribute="disabled hidden"

The attribute(s) of the target element to set.

data-binding-class

e.g: data-binding-class="text-red-500 line-through"

The classes to be added/removed from the target element.

data-binding-value

e.g: data-binding-value="$source.value"

The value to set the target attribute/property to. Note that this field evaluates an expression, this expression has access to $source which is the element this is defined on.

If you would like to pass in a string, you would have to do this: data-binding-value="'my string'".

If this value is not set, the attribute will be set/removed without a value.

data-binding-condition

e.g: data-binding-condition="$source.value === 'hello world'"

The condition to check whether or not to set the target attribute/property/class. This evaluates an expression which has access to the value of the source element as $source and the target element as $target.

data-binding-initial (Defaults to true)

e.g: data-binding-initial="true" e.g: data-binding-initial="false"

If this is true data-binding#update will be called on load to set an initial value. Set to false to prevent this behaviour.

data-binding-event

e.g: data-binding-event="change input"

You can set one or more events to be triggered when the data-binding-property is changed. This is sometimes required because programmatically assigned values do not trigger events on an element, whereas physically updating the value in the UI does.

  • Note events will not be triggered on changes to data-binding-attribute. Only property changes will trigger an event.

Examples

Mirror and alter the contents of an input field

<input
  type="text"
  data-action="change->data-binding#update"
  data-binding-target="foo"
  data-binding-property="textContent"
  data-binding-value="`edited-${$source.value}`"
/>

<div data-binding-ref="foo"><!-- this will be edited-xxx --></div>

Set a data attribute of an element if a number box has a value greater than 5

<input
  type="number"
  data-action="change->data-binding#update"
  data-binding-target="foo"
  data-binding-condition="$source.value > 5"
  data-binding-attribute="data-large"
/>

<!-- this will have data-large set only if the input has a number greater than 5 in it -->
<div data-binding-ref="foo"></div>

Toggle a class on a div based on if a checkbox is checked

<input
  type="checkbox"
  data-action="change->data-binding#update"
  data-binding-target="foo"
  data-binding-condition="$source.checked"
  data-binding-class="badger bodger"
/>

<!-- this will have the classes "badger" and "bodger" when the checkbox is checked, and not if it is unchecked.  -->
<div data-binding-ref="foo"></div>

Disable and hide a field if a checkbox is not checked

<input
  type="checkbox"
  data-action="change->data-binding#update"
  data-binding-target="foo"
  data-binding-condition="!$source.checked"
  data-binding-attribute="disabled hidden"
/>

<!-- this will be visable and enabled only if the checkbox is ticked -->
<div data-binding-ref="foo"></div>

Hide one field, and disable another, based on whether a checkbox is checked

<input
  type="checkbox"
  data-action="change->data-binding#update"
  data-binding-target="foo"
/>

<div
  data-binding-ref="foo"
  data-binding-condition="!$source.checked"
  data-binding-attribute="disabled"
>I will be disabled when checked</div>
<div
  data-binding-ref="foo"
  data-binding-condition="$source.checked"
  data-binding-attribute="hidden"
>I will be hidden when unchecked</div>

Only show a single field from a list based on the value of a select

<select
  data-action="change->data-binding#update"
  data-binding-condition="$source.value !== $target.dataset.id"
  data-binding-target="bar"
  data-binding-attribute="hidden"
>
  <option value="1" selected>ID: 1</option>
  <option value="2">ID: 2</option>
</select>

<div>
  <div data-binding-ref="bar" data-id="1"><!-- currently shown --></div>
  <div data-binding-ref="bar" data-id="2"><!-- currently hidden --></div>
</div>

Show/Hide elements based on a radio input

<label>B</label>
<input
  type="radio" value="A" checked
  data-action="change->data-binding#update"
  data-binding-target="radio"
  data-binding-attribute="hidden"
  data-binding-initial="false" />

<label>A</label>
<input
  type="radio" value="B"
  data-action="change->data-binding#update"
  data-binding-target="radio"
  data-binding-attribute="hidden"
  data-binding-initial="false" />

<div data-binding-ref="radio" data-binding-condition="$source.value !== 'A'">Showing A</div>
<div data-binding-ref="radio" data-binding-condition="$source.value !== 'B'" hidden>Showing B</div>

Set the value of an input when a button is clicked

<button
  data-action="click->data-binding#update"
  data-binding-target="amount"
  data-binding-property="value"
  data-binding-initial="false"
  data-binding-value="$source.dataset.fullAmount"
  data-full-amount="12.99"
>Full amount</button>

<input type="number" data-binding-ref="amount" />

Trigger an event when a property is set

<button
  data-action="click->data-binding#update"
  data-binding-target="amount"
  data-binding-property="value"
  data-binding-initial="false"
  data-binding-value="$source.dataset.fullAmount"
  data-full-amount="12.99"
  data-binding-event="change input"
>Full amount</button>

<input type="number" data-binding-ref="amount" />

Contributing

Fork the project.

Install dependencies

$ yarn install

Start the test watcher

$ yarn test:watch

Running one-off test runs can be done with:

$ yarn test

Write some tests, and add your feature. Send a PR.