/jquery-watcher

jQuery plugin to write Mustache.js templates in elements and have them update automatically with reactive data.

Primary LanguageJavaScript

jQuery Watcher Coverage Status

Write Mustache.js templates in elements and have them update automatically with reactive data.

<button>Clicked: {{ count }}</button>

<script>
$('button').watcher({ count: 0 }).click(function () {
  $(this).watcher().count++
})

$('button').click().text()
// Clicked: 1
</script>

Getting Started

Install as a module

npm:

npm i jquery-watcher

yarn:

yarn add jquery-watcher

Initialize the plugin once in your project:

// src/plugins.js

import 'jquery-watcher'

// or

require('jquery-watcher')

CDN

<!-- jQuery -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<!-- Mustache.js -->
<script src="https://cdn.jsdelivr.net/npm/mustache@4.0.1/mustache.min.js"></script>
<!-- jQuery Watcher -->
<script src="https://cdn.jsdelivr.net/npm/jquery-watcher@1.3.0/dist/jquery-watcher.min.js"></script>

API

.watcher(data: Object) => jQuery

Pass a data object that you want to be reactive. Returns jQuery.
This will immediately render your template.

<div>Hello {{ value }}</div>

<script>
$('div').watcher({ value: 'World' }).text()
// Hello World

$('div').watcher({ value: 'Adam' }).text()
// Hello Adam
</script>

All of your nested objects will also be reactive.

<div>{{ nested.bird }}</div>

<script>
const { nested } = $('div').watcher({ nested: { bird: '' } }).watcher()

nested.bird = 'Robin'

$('div').text()
// Robin
</script>

Arrays too!

<div>
  {{ #starks }}
  <p>{{.}}</p>
  {{ /starks }}
</div>

<script>
const { starks } = $('div').watcher({ starks: ['Ned', 'Sansa', 'Bran', 'Jon'] }).watcher()

starks.pop()

$('div').html()
/*
<p>Ned</p>
<p>Sansa</p>
<p>Bran</p>
*/
</script>

.watcher() => Object

If no argument is passed, it will return the reactive data object.
If you manipulate the properties on the reactive object, it will automatically re-render your template.

<div>Hello {{ text }}</div>

<script>
const data = $('div').watcher({ text: 'World' }).watcher()

data.text = 'Adam'

$('div').text()
// Hello Adam
</script>

.watcher() => [Object, ...]

If there is more than one element, it will return an array of reactive data objects.

<div>{{ hero }}</div>
<div>{{ hero }}</div>

<script>
// [{ hero: 'Superman' }, { hero: 'Superman' }]
const [div1, div2] = $('div').watcher({ hero: 'Superman' }).watcher()

div2.hero = 'Batman'

$('div:nth-child(1)').text()
// Superman

$('div:nth-child(2)').text()
// Batman
</script>

Actions

.watcher('set_template', template: String) => jQuery

Sets a new template on the element. Second argument is your string template. Returns jQuery.
This will immediately render your new template if there's data.

<div>{{ things.0 }}</div>

<script>
const { things } = $('div').watcher({ things: ['Thing 1'] }).watcher()
$('div').text()
// Thing 1

things.push('Thing 2')
$('div').watcher('set_template', '{{ things.0 }} & {{ things.1 }}').text()
// Thing 1 & Thing 2
</script>

.watcher('render') => jQuery

Renders your template. Useful if you set your template via .html(). Returns jQuery.

<div></div>

<script>
$('div')
  .watcher({ hello: 'world' })
  .html('{{ hello }}')
  .watcher('render')
  .text()
// world
</script>

TODOs

  • CDN
  • Reactive arrays
  • Allow template modification
  • Config options