# domod

> A lightweight data-binding (or so-called mvvm) library, providing both declarative template and imperative call ways.

Latest version **1.0.0** (published 2018-02-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install domod
pnpm add domod
yarn add domod
bun add domod
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2018-02-22 |
| First published | 2017-10-08 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 434.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 11 |
| Author | hengwu |
| Maintainers | hengwu |
| Keywords | data-binding, mvvm, reactive, template |

## Links

- npm: https://www.npmjs.com/package/domod
- Repository: https://github.com/shenfe/domod
- Homepage: https://github.com/shenfe/domod#readme
- Issues: https://github.com/shenfe/domod/issues
- npm.io page: https://npm.io/package/domod

## Recent versions

- 1.0.0 (latest) — 2018-02-22
- 0.2.4 — 2017-12-08
- 0.2.3 — 2017-12-08
- 0.2.2 — 2017-12-08
- 0.2.1 — 2017-12-08
- 0.2.0 — 2017-12-08
- 0.1.9 — 2017-12-08
- 0.1.8 — 2017-12-08
- 0.1.7 — 2017-12-08
- 0.1.6 — 2017-12-08
- 0.1.5 — 2017-12-08
- 0.1.4 — 2017-12-07
- 0.1.3 — 2017-10-13
- 0.1.2 — 2017-10-09
- 0.1.1 — 2017-10-08
- … 1 more at https://npm.io/package/domod/versions

## README

<p align="center"><img width="190"src="https://raw.githubusercontent.com/shenfe/domod/master/readme_assets/logo.png"></p>

![gzipped](http://img.badgesize.io/https://raw.githubusercontent.com/shenfe/domod/master/dist/domod.min.js?compression=gzip)
<a href="https://circleci.com/gh/shenfe/domod/tree/master"><img  src="https://img.shields.io/circleci/project/shenfe/domod/master.svg"></a>
<a href="https://www.npmjs.com/package/domod"><img src="https://img.shields.io/npm/v/domod.svg"></a>
![license](https://img.shields.io/npm/l/domod.svg)

A lightweight data-binding (or so-called mvvm) library, providing both **declarative template** and **imperative call** ways.

*"domod" is named from "DOM", "Model" and their two-way relationship.*

## Philosophy

* Connection, relation, dependency. No matter it is data or dom, it is a tree. Tree and tree node relations make up graphs.
* Reactive programming.

## Simple Application

A simple application:

```js
const state = {
    count: 0,
    increase() {
        this.count++ // `this` points to `state`
    }
}

DMD.relate(state, {
    negative: {
        resultFrom() {
            return this.count < 0 // `this` points to `state`
        }
    }
})

const view = `
    <div>
        <h1 m-style="{ color: $negative ? 'red' : 'green' }">{{$count}}</h1>
        <button m-onclick="$count = $count - 1">-</button>
        <button m-onclick="$increase()">+</button>
    </div>
`

DMD('#app', view, state)
```

## API

An online [demo](http://hengwu.me/repos/domod/domod3.html).

An example of a form:

```html
<script src="path/to/domod.js" charset="utf-8"></script>

<form id="form1">
    <div>
        <label>gender:</label>
        <input m-onclick="$form.gender = 'male'" 
               type="radio" name="gender" value="male" m-checked="$form.gender === 'male'">Male
        <input m-onclick="$form.gender = 'female'" 
               type="radio" name="gender" value="female" m-checked="$form.gender === 'female'">Female
    </div>
    <div>
        <label>mobile:</label>
        <input type="text" name="mobile" m-value="$form.mobile">
        <span m-style="{ display: !!$form.mobile ? 'inline' : 'none' }">
            You input: {{$parse($form.mobile)}}.
        </span>
        <span m-class="['some-class', { red: !$mobileInputStatus }]" 
              m-style="{ display: !$mobileInputStatus ? 'inline' : 'none' }">
            {{$form.mobile}} is {{$mobileInputStatus}}!
        </span>
    </div>
    <div>
        <label>age:</label>
        <select name="age" m-value="$form.age.value">
            <option m-each="$val in $form.age.options" m-value="$val">{{$val}}</option>
        </select>
    </div>
    <div>
        <label>city:</label>
        <select name="city" m-value="$form.city.value">
            <option m-each="($val, $key) in $form.city.options" m-value="$key">
                {{$val.code}}.{{$val.name}}
            </option>
        </select>
    </div>
</form>

<script>
    var store = {
        parse: function (v) {
            return parseInt(v);
        },
        validateMobile: function () {
            return /^1[3|4|5|8][0-9]\d{8}$/.test(this.form.mobile);
        },
        form: {
            gender: 'female',
            mobile: '15210001000',
            age: {
                value: '37-54',
                options: [
                    '0-18',
                    '19-36',
                    '37-54',
                    '55-200'
                ]
            },
            city: {
                value: '1',
                options: [
                    { code: 1, name: 'beijing' },
                    { code: 2, name: 'newyork' },
                    { code: 3, name: 'tokyo' },
                    { code: 4, name: 'london' },
                    { code: 5, name: 'paris' }
                ]
            }
        }
    };

    /* Watch a property mutation */
    store.mobileInputStatus = store.validateMobile();
    DMD.relate(store, {
        'form.mobile': {
            dnstream: 'mobileInputStatus',
            resultIn: function (v) {
                var newVal = store.validateMobile();
                console.log(`mobile is ${newVal}`);
                DMD.$(store, 'mobileInputStatus', newVal);
            }
        }
    });

    DMD('#form1', store);
</script>
```

## Advance

### Imperative Calling

Providing a data object:

```js
var store = {
    value: '1'
};
```

Now assign a property `color` which would be computed from the property `value`.

There are two methods available, `kernel` and `relate`.

The `kernel` method, which is actually a constructor function, accepts two parameters besides the data object: the property and its relation object.

```js
new domod.kernel(store, 'color', {
    resultFrom: function () {
        return isNaN(parseInt(store.value)) ? 'red' : 'green';
    }
});
```

The `relate` method, which is somehow a composition of `kernel`, accepts one parameter besides the data object: an object representing a map from property names to relation objects.

```js
domod.relate(store, {
    color: {
        resultFrom: function () {
            return isNaN(parseInt(store.value)) ? 'red' : 'green';
        }
    }
});
```

### Relation Object

A relation object can be declared with these properties:

Property | Effect
:---: | :---
resultFrom | Do when the property is being got, and return the value computed.
resultIn | Do when the property is being set.
upstream | Other properties as the property's dependencies.
dnstream | Other properties as the property's effects.

## Standalone Libraries

### Kernel

See the [code](https://github.com/shenfe/domod/blob/master/src/Kernel.js) and [doc](https://github.com/shenfe/domod/blob/master/doc/Kernel.md) for more.

### ObservableArray

Also called OArray for short. See the [code](https://github.com/shenfe/domod/blob/master/src/OArray.js) and [doc](https://github.com/shenfe/domod/blob/master/doc/ObservableArray.md) for more.

## License

MIT

---
_Source: https://npm.io/package/domod · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
