├── .eslintrc
├── .gitignore
├── .testem.json
├── README.md
├── dist
├── jquery.component.js
└── jquery.component.min.js
├── doc
└── API.md
├── example
├── basic.html
├── binding.html
├── children.html
└── events.html
├── package.json
├── src
├── index.js
├── jquery.bindData.js
├── jquery.component.js
└── jquery.events.js
└── test
├── browser
└── index.html
├── jquery.bindData.js
├── jquery.component.js
└── jquery.events.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | },
5 | "rules": {
6 | "comma-dangle": 1,
7 | "no-cond-assign": 2,
8 | "no-console": 1,
9 | "no-constant-condition": 2,
10 | "no-control-regex": 2,
11 | "no-debugger": 2,
12 | "no-dupe-keys": 2,
13 | "no-empty": 2,
14 | "no-empty-character-class": 2,
15 | "no-ex-assign": 2,
16 | "no-extra-boolean-cast": 2,
17 | "no-extra-parens": 0,
18 | "no-extra-semi": 2,
19 | "no-func-assign": 1,
20 | "no-inner-declarations": 2,
21 | "no-invalid-regexp": 2,
22 | "no-irregular-whitespace": 2,
23 | "no-negated-in-lhs": 2,
24 | "no-obj-calls": 2,
25 | "no-regex-spaces": 2,
26 | "no-reserved-keys": 0,
27 | "no-sparse-arrays": 2,
28 | "no-unreachable": 2,
29 | "use-isnan": 2,
30 | "valid-typeof": 2,
31 | "block-scoped-var": 0,
32 | "complexity": [
33 | 1,
34 | 10
35 | ],
36 | "consistent-return": 0,
37 | "curly": 0,
38 | "default-case": 0,
39 | "dot-notation": 2,
40 | "eqeqeq": [
41 | 2,
42 | "smart"
43 | ],
44 | "guard-for-in": 0,
45 | "no-alert": 1,
46 | "no-caller": 2,
47 | "no-div-regex": 2,
48 | "no-else-return": 2,
49 | "no-eq-null": 0,
50 | "no-eval": 1,
51 | "no-extend-native": 1,
52 | "no-extra-bind": 2,
53 | "no-fallthrough": 0,
54 | "no-floating-decimal": 1,
55 | "no-implied-eval": 2,
56 | "no-iterator": 2,
57 | "no-labels": 2,
58 | "no-lone-blocks": 2,
59 | "no-loop-func": 2,
60 | "no-multi-spaces": 2,
61 | "no-multi-str": 2,
62 | "no-native-reassign": 2,
63 | "no-new": 2,
64 | "no-new-func": 2,
65 | "no-new-wrappers": 2,
66 | "no-octal": 2,
67 | "no-octal-escape": 2,
68 | "no-process-env": 0,
69 | "no-proto": 2,
70 | "no-redeclare": 2,
71 | "no-return-assign": 2,
72 | "no-script-url": 2,
73 | "no-self-compare": 2,
74 | "no-sequences": 2,
75 | "no-unused-expressions": 2,
76 | "no-var": 0,
77 | "no-void": 2,
78 | "no-warning-comments": 2,
79 | "no-with": 2,
80 | "no-wrap-func": 0,
81 | "radix": 2,
82 | "vars-on-top": 0,
83 | "wrap-iife": 2,
84 | "yoda": 2,
85 | "global-strict": 0,
86 | "strict": 0,
87 | "no-catch-shadow": 2,
88 | "no-delete-var": 2,
89 | "no-label-var": 2,
90 | "no-shadow": 0,
91 | "no-shadow-restricted-names": 2,
92 | "no-undef": 1,
93 | "no-undef-init": 2,
94 | "no-undefined": 0,
95 | "no-unused-vars": 2,
96 | "no-use-before-define": 0,
97 | "handle-callback-err": 1,
98 | "no-mixed-requires": 0,
99 | "no-new-require": 2,
100 | "no-path-concat": 2,
101 | "no-process-exit": 2,
102 | "no-restricted-modules": 0,
103 | "no-sync": 0,
104 | "brace-style": [
105 | 1,
106 | "1tbs"
107 | ],
108 | "camelcase": 0,
109 | "comma-spacing": [
110 | 1,
111 | {
112 | "before": false,
113 | "after": true
114 | }
115 | ],
116 | "comma-style": [
117 | 1,
118 | "last"
119 | ],
120 | "consistent-this": 0,
121 | "eol-last": 1,
122 | "func-names": 0,
123 | "func-style": 0,
124 | "key-spacing": [
125 | 1,
126 | {
127 | "beforeColon": false,
128 | "afterColon": true
129 | }
130 | ],
131 | "max-nested-callbacks": 0,
132 | "new-cap": 2,
133 | "new-parens": 2,
134 | "no-array-constructor": 2,
135 | "no-inline-comments": 0,
136 | "no-lonely-if": 2,
137 | "no-mixed-spaces-and-tabs": 2,
138 | "no-multiple-empty-lines": 2,
139 | "no-nested-ternary": 0,
140 | "no-new-object": 2,
141 | "semi-spacing": 2,
142 | "no-spaced-func": 2,
143 | "no-ternary": 0,
144 | "no-trailing-spaces": 2,
145 | "no-underscore-dangle": 0,
146 | "one-var": 0,
147 | "operator-assignment": [
148 | 2,
149 | "always"
150 | ],
151 | "padded-blocks": 0,
152 | "quote-props": [
153 | 1,
154 | "as-needed"
155 | ],
156 | "quotes": [
157 | 2,
158 | "single"
159 | ],
160 | "semi": 2,
161 | "sort-vars": 0,
162 | "keyword-spacing": 1,
163 | "space-before-blocks": [
164 | 1,
165 | "always"
166 | ],
167 | "space-in-parens": [
168 | 1,
169 | "never"
170 | ],
171 | "space-infix-ops": 1,
172 | "space-unary-ops": [
173 | 1,
174 | {
175 | "words": true,
176 | "nonwords": false
177 | }
178 | ],
179 | "spaced-line-comment": 0,
180 | "wrap-regex": 0
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | npm-debug.log
3 | test/browser/tests-bundle.js
4 |
--------------------------------------------------------------------------------
/.testem.json:
--------------------------------------------------------------------------------
1 | {
2 | "framework": "qunit",
3 | "test_page": "test/browser/index.html",
4 | "launch_in_dev": [
5 | "Chrome"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jQuery.component
2 |
3 | Create a component with jQuery. Inspired by Backbone View model.
4 |
5 | 
6 | 
7 | [](https://opensource.org/licenses/MIT)
8 | [](https://www.npmjs.com/package/jquery)
9 | [](https://www.npmjs.com/package/lodash)
10 |
11 | ## Requirement
12 | You must include in your html jQuery and lodash.
13 |
14 | ## How to install
15 | ```terminal
16 | npm install --save jquery.component
17 | ```
18 | Include in your .html this library after jQuery and lodash files.
19 |
20 | ## How it works
21 | ### Basically
22 | jquery.component uses template method of lodash so you can integrate a template in your .html. For example:
23 | ```html
24 |
30 | ```
31 | Then in your js file, call your template and declare events in component method:
32 | ```javascript
33 | var titleComponent = $.component({
34 | template: $('#title-template').html(),
35 | events: {
36 | 'click h1': function() {
37 | $(this).parent().find('p').append('Hello everyone !');
38 | }
39 | }
40 | });
41 | ```
42 | After you can use your component with some data by using the render method:
43 | ```javascript
44 | $('body').append(titleComponent.render({
45 | title: 'Hello World'
46 | }));
47 | ```
48 | ### Children
49 | If you want to include another component or element in your component. You can use `data-children` attribute in the parent container:
50 | ```html
51 |
57 |
58 |
61 |
62 |
72 | ```
73 | `children` attribute accept an array of components or elements. If you pass a function, it will be evaluate with the model.
74 |
75 | By the way, if you declare an object into children attribute, use `data-child` with the key name:
76 | ```html
77 |
84 |
85 |
88 |
89 |
92 |
93 |
112 | ```
113 | ### Bind data
114 | You can also bind your data by declaring a `data-bind-id` attribute with a name and then apply a `data-bind` attribute to another element with the name target. Follow this example:
115 | ```html
116 |
122 |
123 |
130 | ```
131 | It's possible to pass a callback method in $.component:
132 | ```javascript
133 | var componentName = $.component({
134 | template: $('#name-template').html(),
135 | bindData: function (val) {
136 | return val + val;
137 | }
138 | });
139 | ```
140 | ### Lifecycle of component
141 | - `componentWillMount` method option will run before the render of component.
142 | - `componentDidMount` method option will run after the render of component.
143 | - `componentWillUpdate` each time, method option will run before the component re-renders. As argument, you can use old declared data.
144 | - `componentDidUpdate` each time, method option will run after the component re-renders. As argument, you can use old declared data.
145 |
146 | ## Contributing
147 | 1. Fork it
148 | 2. Create your feature branch (git checkout -b my-new-feature)
149 | 3. Commit your changes (git commit -am 'Added some feature')
150 | 4. Push to the branch (git push origin my-new-feature)
151 | 5. Create new Pull Request
152 |
153 | ## Licence
154 | ```
155 | MIT
156 | ```
157 |
--------------------------------------------------------------------------------
/dist/jquery.component.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) {
224 | result = [separator.shift(), separator.join(' ')];
225 | this.find(result[1]).bind(i, o[i]);
226 | } else {
227 | this.bind(i, o[i]);
228 | }
229 | }
230 | return this;
231 | };
232 | }(jQuery));
233 |
234 | },{}]},{},[1]);
235 |
--------------------------------------------------------------------------------
/dist/jquery.component.min.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o1){result=[separator.shift(),separator.join(" ")];this.find(result[1]).bind(i,o[i])}else{this.bind(i,o[i])}}return this}})(jQuery)},{}]},{},[1]);
--------------------------------------------------------------------------------
/doc/API.md:
--------------------------------------------------------------------------------
1 | ## API instance
2 | ### `clone`
3 | clone component instance. Useful for set new data.
4 |
5 | ### `model.data`
6 | Object where all associate datas of component are stored.
7 |
8 | ### `model.get(key)`
9 | Take as argument an attribute key of object `model.data` and return this value.
10 |
11 | ### `model.set(key, value)`
12 | Pass in first argument the key name to declare or overwrite in `model.data` and then pass in second argument this value.
13 | You can also pass in argument an object.
14 |
15 | ### `setBindData(callback)`
16 | Set or replace the callback method called after a change on input, selector or textarea tag.
17 |
18 | ### `setChildren(children)`
19 | Set or replace the children defined. Children argument must be in html.
20 |
21 | ### `setEvents(events)`
22 | Set or replace events methods. Take as example Backbone events. ([doc](http://backbonejs.org/#View-events))
23 |
24 | ### `setModel(model)`
25 | Set or replace object data used in your component.
26 |
27 | ### `setTemplate(newTemplate)`
28 | Set or replace the template html of component.
29 |
30 | ### `render(datas, optionsTemplate)`
31 | Render the component with the template attribute declared and datas passed in argument (optional). In second argument you can pass all options lodash template.
32 |
--------------------------------------------------------------------------------
/example/basic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic example
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/binding.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Binding data example
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/example/children.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Children example
6 |
7 |
8 |
15 |
16 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/events.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Events example
6 |
7 |
8 |
9 |
18 |
19 |
20 |
21 |
22 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery.component",
3 | "version": "1.3.5",
4 | "description": "Create a component with jQuery. Inspired by Backbone View model.",
5 | "main": "dist/jquery.component.js",
6 | "scripts": {
7 | "browserify": "browserify src/index.js > dist/jquery.component.js",
8 | "uglify": "uglifyjs dist/jquery.component.js -o dist/jquery.component.min.js",
9 | "dist": "npm run browserify && npm run uglify",
10 | "pretest-browser": "browserify test/jquery.component.js > test/browser/tests-bundle.js",
11 | "posttest-browser": "rm test/browser/tests-bundle.js",
12 | "test-browser": "testem"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/olivmonnier/jquery-component.git"
17 | },
18 | "keywords": [
19 | "component",
20 | "dom",
21 | "jquery",
22 | "template"
23 | ],
24 | "author": "oliv75",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/olivmonnier/jquery-component/issues"
28 | },
29 | "homepage": "https://github.com/olivmonnier/jquery-component#readme",
30 | "devDependencies": {
31 | "blanket": "1.1.7",
32 | "browserify": "^12.0.1",
33 | "jquery": "^2.1.4",
34 | "lodash": "^3.10.1",
35 | "qunitjs": "^1.20.0",
36 | "testem": "^0.9.11",
37 | "uglify-js": "^2.6.1"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | require('./jquery.events.js');
2 | require('./jquery.bindData.js');
3 | require('./jquery.component.js');
4 |
--------------------------------------------------------------------------------
/src/jquery.bindData.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $.fn.bindData = function(callback) {
3 | var self = this;
4 | $(self).find('[data-bind-id]').each(function() {
5 | var pubSub = $({});
6 | var id = $(this).data('bind-id');
7 | var eventName = id + ':change';
8 |
9 | $(this).on('change input', function() {
10 | var $input = $(this);
11 | pubSub.trigger(eventName, [$input.val()]);
12 | });
13 |
14 | pubSub.on(eventName, function(evt, val) {
15 | if (callback) var newVal = callback(val);
16 |
17 | $(self).find('[data-bind = ' + id + ']').each(function() {
18 | var $bound = $(this);
19 |
20 | if ($bound.is('input, textarea, select')) {
21 | $bound.val(newVal);
22 | } else {
23 | $bound.html(newVal);
24 | }
25 | });
26 | });
27 | });
28 | return this;
29 | };
30 | }(jQuery));
31 |
--------------------------------------------------------------------------------
/src/jquery.component.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $.component = function(options) {
3 | var opts = options || {};
4 |
5 | var Component = function() {
6 | var self = this;
7 | this.$el = '';
8 | this.mounted = false;
9 | this.children = opts.children || '';
10 | this.events = opts.events || {};
11 | this.model = {
12 | oldData: null,
13 | data: opts.model || {},
14 | get: function(attr) {
15 | return this.data[attr];
16 | },
17 | set: function(key, val) {
18 | var attrs;
19 | var modelData = Object.create({});
20 |
21 | if (key == null) return this;
22 |
23 | if (typeof key === 'object') {
24 | attrs = key;
25 | } else {
26 | (attrs = {})[key] = val;
27 | }
28 |
29 | for (var k in this.data) {
30 | Object.defineProperty(modelData, k, {
31 | value: this.data[k],
32 | writable: true,
33 | enumerable: true,
34 | configurable: true
35 | });
36 | }
37 | for (var attr in attrs) {
38 | Object.defineProperty(modelData, attr, {
39 | value: attrs[attr],
40 | writable: true,
41 | enumerable: true,
42 | configurable: true
43 | });
44 | }
45 |
46 | if (self.$el) {
47 | self.$el.replaceWith(self.render(modelData));
48 | } else {
49 | this.data = modelData;
50 | }
51 | }
52 | };
53 | this.optionsTemplate = opts.optionsTemplate || {};
54 | this.template = opts.template || '';
55 | };
56 |
57 | Component.prototype.bindData = opts.bindData || null;
58 |
59 | Component.prototype.clone = function() {
60 | return $.extend(true, {}, this);
61 | }
62 |
63 | Component.prototype.componentDidMount = opts.componentDidMount || null;
64 |
65 | Component.prototype.componentDidUpdate = opts.componentDidUpdate || null;
66 |
67 | Component.prototype.componentWillMount = opts.componentWillMount || null;
68 |
69 | Component.prototype.componentWillUpdate = opts.componentWillUpdate || null;
70 |
71 | Component.prototype.render = function(data, optionsTemplate) {
72 | this.model.oldData = this.model.data;
73 | if (data) this.model.data = data;
74 | if (optionsTemplate) this.optionsTemplate = optionsTemplate;
75 |
76 | if (!this.mounted && this.componentWillMount) {
77 | this.componentWillMount();
78 | }
79 | if (this.mounted && this.componentWillUpdate) {
80 | this.componentWillUpdate(this.model.oldData);
81 | }
82 |
83 | var $el = $(_.template(this.template, this.optionsTemplate)(this.model));
84 |
85 | if (typeof this.children == 'function') this.children = this.children();
86 |
87 | if (typeof this.children == 'object' && this.children.length == undefined) {
88 | for (var child in this.children) {
89 | $el.find('[data-child="' + child + '"]').html(this.children[child]);
90 | }
91 | } else {
92 | if (!Array.isArray(this.children)) this.children = [this.children];
93 |
94 | this.children.forEach(function(child) {
95 | $el.find('[data-children]').append(child);
96 | });
97 | }
98 | $el.events(this.events).bindData(this.bindData);
99 | this.$el = $el;
100 |
101 | if (!this.mounted && this.componentDidMount) {
102 | this.componentDidMount();
103 | }
104 | if (this.mounted && this.componentDidUpdate) {
105 | this.componentDidUpdate(this.model.oldData);
106 | }
107 |
108 | this.mounted = true;
109 |
110 | return this.$el;
111 | };
112 |
113 | Component.prototype.setBindData = function(callback) {
114 | this.bindData = callback;
115 |
116 | return this;
117 | };
118 |
119 | Component.prototype.setChildren = function(children) {
120 | this.children = children;
121 |
122 | if (this.$el) {
123 | this.$el.find('[data-children]').empty();
124 |
125 | if (typeof this.children == 'function') this.children = this.children();
126 |
127 | if (typeof this.children == 'object' && this.children.length == undefined) {
128 | for (var child in this.children) {
129 | $el.find('[data-child="' + child + '"]').html(this.children[child]);
130 | }
131 | } else {
132 | if (!Array.isArray(this.children)) this.children = [this.children];
133 |
134 | this.children.forEach(function(child) {
135 | $el.find('[data-children]').append(child);
136 | });
137 | }
138 | }
139 |
140 | return this;
141 | };
142 |
143 | Component.prototype.setEvents = function(events) {
144 | this.events = events;
145 |
146 | if (this.$el) {
147 | this.$el.replaceWith(this.render());
148 | }
149 |
150 | return this;
151 | };
152 |
153 | Component.prototype.setModel = function(model) {
154 |
155 | if (this.$el) {
156 | this.$el.replaceWith(this.render(model));
157 | } else {
158 | this.model.data = model;
159 | }
160 |
161 | return this;
162 | };
163 |
164 | Component.prototype.setTemplate = function(newTemplate) {
165 | this.template = newTemplate;
166 |
167 | if (this.$el) {
168 | this.$el.replaceWith(this.render());
169 | }
170 |
171 | return this;
172 | };
173 |
174 | return new Component();
175 | };
176 | }(jQuery));
177 |
--------------------------------------------------------------------------------
/src/jquery.events.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $.fn.events = function(o) {
3 | for (var i in o) {
4 | var separator = i.split(' ');
5 | var result = [];
6 |
7 | if (separator.length > 1) {
8 | result = [separator.shift(), separator.join(' ')];
9 | this.find(result[1]).bind(i, o[i]);
10 | } else {
11 | this.bind(i, o[i]);
12 | }
13 | }
14 | return this;
15 | };
16 | }(jQuery));
17 |
--------------------------------------------------------------------------------
/test/browser/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Test jQuery.component plugin
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/test/jquery.bindData.js:
--------------------------------------------------------------------------------
1 | QUnit.test('$.fn.bindData', function(assert) {
2 | assert.equal(typeof $.fn.bindData, 'function', 'Is function ?');
3 | });
4 |
--------------------------------------------------------------------------------
/test/jquery.component.js:
--------------------------------------------------------------------------------
1 | require('./jquery.bindData');
2 | require('./jquery.events');
3 |
4 | QUnit.test('$.component', function(assert) {
5 | var component = $.component();
6 | assert.equal(typeof $.component, 'function', 'Is function ?');
7 | assert.equal(typeof component, 'object', 'No parameters');
8 | });
9 |
10 | QUnit.test('$.component API bindData', function(assert) {
11 | var component = $.component();
12 | assert.equal(component.bindData, null, 'Is null');
13 | });
14 |
15 | QUnit.test('$.component API children', function(assert) {
16 | var component = $.component();
17 | assert.equal(component.children, '', 'Is an empty string');
18 |
19 | var component2 = $.component({
20 | template: '',
21 | children: function() {
22 | return document.createElement('span');
23 | }
24 | });
25 | component2.render();
26 | assert.equal(typeof component2.children, 'object', 'Is become an object after render running');
27 |
28 | var child = $.component({
29 | template: 'Foo'
30 | });
31 | var component3 = $.component({
32 | template: '',
33 | children: child.render()
34 | });
35 | component3.render();
36 | assert.equal(component3.$el.children().length, 1, 'Is populating by children after render running');
37 |
38 | var component4 = $.component({
39 | template: '',
40 | children: {
41 | foo: child.render()
42 | }
43 | });
44 | component4.render();
45 | assert.equal(component4.$el.find('[data-child="foo"]').children().length, 1, 'Is populating by children object key');
46 | });
47 |
48 | QUnit.test('$.component API clone', function(assert) {
49 | var component1 = $.component();
50 | assert.equal(typeof component1.clone, 'function', 'Is function');
51 |
52 | var component2 = component1.clone();
53 | assert.equal(typeof component2, 'object', 'Is an object');
54 | assert.equal(typeof component2.render, 'function', 'Is a deep clone');
55 |
56 | component1.render({foo: 'bar'});
57 | component2.render({foo: 'baz'});
58 | assert.equal(component1.model.data.foo, 'bar', 'Is data declare on render launch for component1');
59 | assert.equal(component2.model.data.foo, 'baz', 'Is data declare on render launch for component2');
60 | });
61 |
62 | QUnit.test('$.component API componentDidMount', function(assert) {
63 | var component1 = $.component();
64 | assert.equal(component1.componentDidMount, null, 'Is null');
65 |
66 | var count = 0;
67 | var component2 = $.component({
68 | componentDidMount: function() {
69 | count++;
70 | }
71 | });
72 | for (var i = 0; i < 2; i++) {
73 | component2.render();
74 | }
75 | assert.equal(count, 1, 'Expect run in first time on render');
76 | });
77 |
78 | QUnit.test('$.component API componentDidUpdate', function(assert) {
79 | var component1 = $.component();
80 | assert.equal(component1.componentDidUpdate, null, 'Is null');
81 |
82 | var count = 0;
83 | var component2 = $.component({
84 | componentDidUpdate: function() {
85 | count++;
86 | }
87 | });
88 | for (var i = 0; i < 3; i++) {
89 | component2.render();
90 |
91 | if (i === 0) {
92 | assert.equal(count, 0, 'Expect not run in first time on render');
93 | }
94 | }
95 | assert.equal(count, 2, 'Expect run each time render is called');
96 | });
97 |
98 | QUnit.test('$.component API componentWillMount', function(assert) {
99 | var component1 = $.component();
100 | assert.equal(component1.componentWillMount, null, 'Is null');
101 |
102 | var count = 0;
103 | var component2 = $.component({
104 | componentWillMount: function() {
105 | count++;
106 | }
107 | });
108 | for (var i = 0; i < 2; i++) {
109 | component2.render();
110 | }
111 | assert.equal(count, 1, 'Expect run in first time on render');
112 | });
113 |
114 | QUnit.test('$.component API componentWillUpdate', function(assert) {
115 | var component1 = $.component();
116 | assert.equal(component1.componentWillUpdate, null, 'Is null');
117 |
118 | var count = 0;
119 | var component2 = $.component({
120 | componentWillUpdate: function() {
121 | count++;
122 | }
123 | });
124 | for (var i = 0; i < 3; i++) {
125 | component2.render();
126 | if (i === 0) {
127 | assert.equal(count, 0, 'Expect not run in first time on render');
128 | }
129 | }
130 | assert.equal(count, 2, 'Expect run each time render is called');
131 | });
132 |
133 | QUnit.test('$.component API model', function(assert) {
134 | var component = $.component();
135 | assert.equal(typeof component.model, 'object', 'Is object');
136 | });
137 |
138 | QUnit.test('$.component API model.data', function(assert) {
139 | var component = $.component();
140 | assert.equal(typeof component.model.data, 'object', 'Is object');
141 | });
142 |
143 | QUnit.test('$.component API model.get', function(assert) {
144 | var component1 = $.component();
145 | assert.equal(typeof component1.model.get, 'function', 'Is function');
146 |
147 | var component2 = $.component({
148 | model: {
149 | msg: 'Hello World'
150 | }
151 | });
152 | assert.equal(component2.model.get('msg'), 'Hello World', 'Expect return value declared');
153 | });
154 |
155 | QUnit.test('$.component API model.set', function(assert) {
156 | var component1 = $.component();
157 | assert.equal(typeof component1.model.set, 'function', 'Is function');
158 |
159 | var component2 = $.component({
160 | model: {
161 | msg: 'Hello World'
162 | }
163 | });
164 | component2.model.set({msg: 'Hello Everyone'});
165 | assert.equal(component2.model.data.msg, 'Hello Everyone', 'Expect set value in model.data');
166 | });
167 |
168 | QUnit.test('$.component API render', function(assert) {
169 | var component1 = $.component();
170 | assert.equal(typeof component1.render, 'function', 'Is function');
171 | assert.equal(component1.mounted, false, 'Is not declared as mounted before render running');
172 |
173 | component1.render({foo: 'bar'});
174 | assert.equal(component1.mounted, true, 'Is declared as mounted after render running');
175 | assert.equal(component1.model.data.foo, 'bar', 'Is updating the model');
176 |
177 | var template = 'Hello World
';
178 | var component2 = $.component({ template: template });
179 | assert.deepEqual(component2.render(), $(template), 'Expect return element defined in template');
180 | });
181 |
182 | QUnit.test('$.component API template', function(assert) {
183 | var component1 = $.component();
184 | assert.equal(typeof component1.template, 'string', 'Is string');
185 |
186 | var component2 = $.component({
187 | template: $('body').html()
188 | });
189 | assert.equal(typeof component2.template, 'string', 'Expect return a string with a selector');
190 | });
191 |
192 | QUnit.test('$.component API setBindData', function(assert) {
193 | var component1 = $.component();
194 | assert.equal(typeof component1.setBindData, 'function', 'Is function');
195 |
196 | var component2 = $.component();
197 | var bindData = function(val) {
198 | return val + val;
199 | };
200 | component2.setBindData(bindData);
201 | assert.deepEqual(component2.bindData, bindData, 'Expect set attribute bindData in component');
202 | });
203 |
204 | QUnit.test('$.component API setChildren', function(assert) {
205 | var component1 = $.component();
206 | assert.equal(typeof component1.setChildren, 'function', 'Is function');
207 |
208 | var component2 = $.component();
209 | var children = 'Hello World !
';
210 | component2.setChildren(children);
211 | assert.equal(component2.children, children, 'Expect set attribute children in component');
212 | });
213 |
214 | QUnit.test('$.component API setEvents', function(assert) {
215 | var component1 = $.component();
216 | assert.equal(typeof component1.setEvents, 'function', 'Is function');
217 |
218 | var component2 = $.component();
219 | var events = {
220 | 'click body': function() {
221 | console.log('Clicked !');
222 | }
223 | };
224 | component2.setEvents(events);
225 | assert.deepEqual(component2.events, events, 'Expect set attribute events in component');
226 | });
227 |
228 | QUnit.test('$.component API setModel', function(assert) {
229 | var component1 = $.component();
230 | assert.equal(typeof component1.setModel, 'function', 'Is function');
231 |
232 | var component2 = $.component({
233 | model: {
234 | msg: 'Hello World'
235 | }
236 | });
237 | component2.setModel({
238 | msg: 'Hello Everyone'
239 | });
240 | assert.equal(component2.model.data.msg, 'Hello Everyone', 'Expect set value in model.data');
241 | });
242 |
243 | QUnit.test('$.component API setTemplate', function(assert) {
244 | var component1 = $.component();
245 | assert.equal(typeof component1.setTemplate, 'function', 'Is function');
246 |
247 | var component2 = $.component();
248 | var template = 'Hello World !
';
249 | component2.setTemplate(template);
250 | assert.equal(component2.template, template, 'Expect set attribute template in component');
251 | });
252 |
--------------------------------------------------------------------------------
/test/jquery.events.js:
--------------------------------------------------------------------------------
1 | QUnit.test('$.fn.events', function(assert) {
2 | assert.equal(typeof $.fn.events, 'function', 'Is function ?');
3 | });
4 |
--------------------------------------------------------------------------------