From 7034282bed10c8222a67e6ec05e1855ce5bed7d9 Mon Sep 17 00:00:00 2001 From: Aurel Date: Mon, 5 Dec 2016 22:40:08 +0100 Subject: [PATCH 1/2] Support reactive items. Separate options from items. --- README.md | 34 ++++++++++++++++++++++------------ index.js | 42 ++++++++++++++++-------------------------- index.umd.js | 42 ++++++++++++++++-------------------------- package.json | 2 +- src/index.js | 45 +++++++++++++++++---------------------------- 5 files changed, 72 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 8b616f9..b9f8194 100644 --- a/README.md +++ b/README.md @@ -23,25 +23,35 @@ $ npm install vue-tribute --save import Vue from "vue"; import VueTribute from "vue-tribute"; -Vue.use(VueTribute, options); +Vue.use(VueTribute, globalOptions); ``` -> The `options` parameter is optional. +> The `globalOptions` parameter is optional. ...and inside your template, bind a dynamic `values` parameter to some data: -`` - -The `values` array should be an array of objects that contain a key and value like so: - ``` -[ - {key: "Phil Heartman", value: "pheartman"}, - {key: "Gordon Ramsey", value: "gramsey"} -] + ``` -You can modify this structure using the built-in [Tribute options](https://github.com/zurb/tribute#a-collection). +The value of `v-tribute` should be an array of objects that contain a `key` to search and a `value` to be inserted. We recommend using a Vue computed property to format your data like so: + +``` +computed: { + tributeUsers: function() { + return [ + {key: "Phil Heartman", value: "pheartman"}, + {key: "Gordon Ramsey", value: "gramsey"} + ] + }, +}, +``` + +The `tributeoptions` attribute is optional. It is merged with `globalOptions` and takes precendence. + +See the available options [here](https://github.com/zurb/tribute#a-collection). ## Events @@ -49,4 +59,4 @@ Tribute broadcasts two events — a `tribute-replaced` event, and a `tribute-no- ## License -MIT © [Collin Henderson](https://github.com/syropian) +MIT © [Collin Henderson](https://github.com/syropian), [Aurélien Nicolas](https://github.com/deckardai) diff --git a/index.js b/index.js index 2e1c993..451bc4c 100644 --- a/index.js +++ b/index.js @@ -8,44 +8,34 @@ if (!Tribute) { throw new Error("[vue-tribute] cannot locate tributejs"); } -exports.install = function (Vue, options) { +exports.install = function (Vue, globalOptions) { Vue.directive("tribute", { - params: ["values"], + params: ["tributeoptions"], + tribute: null, - paramWatchers: { - values: function values(val, oldVal) { - this.setValues(val); - } - }, + + /** Create a Tribute instance for this element */ bind: function bind() { var _this = this; - // If it has a "values" property, it's actually a collection - if (this.params.values.hasOwnProperty("values")) { - this.tribute = new Tribute({ - collection: this.params.values - }); - } else { - this.tribute = new Tribute(Object.assign({ - values: this.params.values - }, options)); - } + this.tribute = new Tribute(Object.assign({ + values: [] + }, globalOptions, this.params.tributeoptions)); this.tribute.attach(this.el); + this.el.addEventListener("tribute-replaced", function (e) { - _this.vm.$emit("tribute-replaced"); + _this.vm.$emit("tribute-replaced", e); }); this.el.addEventListener("tribute-no-match", function (e) { - _this.vm.$emit("tribute-no-match"); + _this.vm.$emit("tribute-no-match", e); }); }, - setValues: function setValues(values) { - // If it has a "values" property, it's actually a collection - if (values.hasOwnProperty("values")) { - this.tribute.collection = values; - } else { - this.tribute.collection[0].values = values; - } + + + /** Set the initial or updated items */ + update: function update(values) { + this.tribute.append(0, values, /* replace= */true); } }); }; \ No newline at end of file diff --git a/index.umd.js b/index.umd.js index 022b023..ade3c5e 100644 --- a/index.umd.js +++ b/index.umd.js @@ -10,44 +10,34 @@ throw new Error("[vue-tribute] cannot locate tributejs"); } - exports.install = function (Vue, options) { + exports.install = function (Vue, globalOptions) { Vue.directive("tribute", { - params: ["values"], + params: ["tributeoptions"], + tribute: null, - paramWatchers: { - values: function values(val, oldVal) { - this.setValues(val); - } - }, + + /** Create a Tribute instance for this element */ bind: function bind() { var _this = this; - // If it has a "values" property, it's actually a collection - if (this.params.values.hasOwnProperty("values")) { - this.tribute = new Tribute({ - collection: this.params.values - }); - } else { - this.tribute = new Tribute(Object.assign({ - values: this.params.values - }, options)); - } + this.tribute = new Tribute(Object.assign({ + values: [] + }, globalOptions, this.params.tributeoptions)); this.tribute.attach(this.el); + this.el.addEventListener("tribute-replaced", function (e) { - _this.vm.$emit("tribute-replaced"); + _this.vm.$emit("tribute-replaced", e); }); this.el.addEventListener("tribute-no-match", function (e) { - _this.vm.$emit("tribute-no-match"); + _this.vm.$emit("tribute-no-match", e); }); }, - setValues: function setValues(values) { - // If it has a "values" property, it's actually a collection - if (values.hasOwnProperty("values")) { - this.tribute.collection = values; - } else { - this.tribute.collection[0].values = values; - } + + + /** Set the initial or updated items */ + update: function update(values) { + this.tribute.append(0, values, /* replace= */true); } }); }; diff --git a/package.json b/package.json index c7de95b..685c344 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-tribute", - "version": "0.1.3", + "version": "0.2.0", "description": "A Vue.js wrapper for Zurb's Tribute library for native @mentions", "license": "MIT", "repository": "syropian/vue-tribute", diff --git a/src/index.js b/src/index.js index c8b1448..35c3a50 100644 --- a/src/index.js +++ b/src/index.js @@ -4,42 +4,31 @@ if (!Tribute) { throw new Error("[vue-tribute] cannot locate tributejs") } -exports.install = function (Vue, options) { +exports.install = function (Vue, globalOptions) { Vue.directive("tribute", { - params: ["values"], + params: ["tributeoptions"], + tribute: null, - paramWatchers: { - values (val, oldVal) { - this.setValues(val) - } - }, - bind () { - // If it has a "values" property, it's actually a collection - if (this.params.values.hasOwnProperty("values")) { - this.tribute = new Tribute({ - collection: this.params.values - }) - } else { - this.tribute = new Tribute(Object.assign({ - values: this.params.values - }, options)) - } + + /** Create a Tribute instance for this element */ + bind() { + this.tribute = new Tribute(Object.assign({ + values: [], + }, globalOptions, this.params.tributeoptions)) this.tribute.attach(this.el) + this.el.addEventListener("tribute-replaced", e => { - this.vm.$emit("tribute-replaced") + this.vm.$emit("tribute-replaced", e) }) this.el.addEventListener("tribute-no-match", e => { - this.vm.$emit("tribute-no-match") + this.vm.$emit("tribute-no-match", e) }) }, - setValues (values) { - // If it has a "values" property, it's actually a collection - if (values.hasOwnProperty("values")) { - this.tribute.collection = values - } else { - this.tribute.collection[0].values = values - } - } + + /** Set the initial or updated items */ + update(values) { + this.tribute.append(0, values, /* replace= */ true) + }, }) } From 62aa6aa6cdf4d3ecb4a1b1816149878f25f77d59 Mon Sep 17 00:00:00 2001 From: au Date: Wed, 7 Dec 2016 19:59:46 +0100 Subject: [PATCH 2/2] Test for separate items and options --- test/VueTribute.spec.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/test/VueTribute.spec.js b/test/VueTribute.spec.js index 83d0801..4e4f6ad 100644 --- a/test/VueTribute.spec.js +++ b/test/VueTribute.spec.js @@ -7,7 +7,10 @@ beforeEach(() => { vm = new Vue({ el: document.body, replace: false, - template: "", + template: ``, data(){ return { items: [ @@ -27,8 +30,14 @@ describe("vue-tribute", () => { expect(typeof vm.$options.directives["tribute"]).toEqual("object") }) - it("triggers the param watcher when the underlying model changes", (done) => { - spyOn(vm.$options.directives["tribute"].paramWatchers, "values").and.callThrough() + it("supports tribute options", () => { + expect(vm._directives[0].tribute.collection[0].trigger).toEqual("#") + }) + + it("updates the items when the underlying model changes", (done) => { + + const directive = vm._directives[0] + expect(directive.tribute.collection[0].values).toEqual(vm.items) const newItems = [ {key: "Kerem Suer", value: "kerem"}, @@ -36,9 +45,9 @@ describe("vue-tribute", () => { ] vm.$set("items", newItems) - setTimeout(() => { - expect(vm.$options.directives["tribute"].paramWatchers.values).toHaveBeenCalled() + Vue.nextTick(() => { + expect(directive.tribute.collection[0].values).toEqual(newItems) done() - }, 0) + }) }) })