From 6cd5e2d80929179ea24eb461127fbfabe016b192 Mon Sep 17 00:00:00 2001 From: Sean Coker Date: Fri, 1 Jun 2018 19:49:47 -0400 Subject: [PATCH] Add move method Will be the foundation of dnd #109 --- src/taggle.js | 44 +++++++++++++++++- test/taggle-test.js | 108 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/taggle.js b/src/taggle.js index 8d82e81..99fa6d4 100644 --- a/src/taggle.js +++ b/src/taggle.js @@ -908,6 +908,10 @@ return this.settings.preserveCase ? text : text.toLowerCase(); }; + Taggle.prototype._isIndexInRange = function(index) { + return index >= 0 && index <= this.tag.values.length - 1; + }; + Taggle.prototype.getTags = function() { return { elements: this.getTagElements(), @@ -967,7 +971,7 @@ throw new Error('Second edit argument must be a number'); } - if (index > this.tag.values.length - 1 || index < 0) { + if (!this._isIndexInRange(index)) { throw new Error('Edit index should be between 0 and ' + this.tag.values.length - 1); } @@ -985,6 +989,44 @@ return this; }; + Taggle.prototype.move = function(currentIndex, destinationIndex) { + if (typeof currentIndex !== 'number' || typeof destinationIndex !== 'number') { + throw new Error('Both arguments must be numbers'); + } + + if (!this._isIndexInRange(currentIndex)) { + throw new Error('First index should be between 0 and ' + this.tag.values.length - 1); + } + + if (!this._isIndexInRange(destinationIndex)) { + throw new Error('Second index should be between 0 and ' + this.tag.values.length - 1); + } + + if (currentIndex === destinationIndex) { + return this; + } + + var value = this.tag.values[currentIndex]; + var element = this.tag.elements[currentIndex]; + var lastElement = this.tag.elements[destinationIndex]; + var eventFn = this._closeEvents[currentIndex]; + var closeButton = this._closeButtons[currentIndex]; + + this.tag.values.splice(currentIndex, 1); + this.tag.elements.splice(currentIndex, 1); + this._closeEvents.splice(currentIndex, 1); + this._closeButtons.splice(currentIndex, 1); + + this.tag.values.splice(destinationIndex, 0, value); + this.tag.elements.splice(destinationIndex, 0, element); + this._closeEvents.splice(currentIndex, 0, eventFn); + this._closeButtons.splice(currentIndex, 0, closeButton); + + this.list.insertBefore(element, lastElement.nextSibling); + + return this; + }; + Taggle.prototype.remove = function(text, all) { var len = this.tag.values.length - 1; var found = false; diff --git a/test/taggle-test.js b/test/taggle-test.js index 1e0699d..fde26a7 100644 --- a/test/taggle-test.js +++ b/test/taggle-test.js @@ -1087,6 +1087,114 @@ describe('Taggle', function() { expect(instance.getTagValues()).to.eql([{ text: 'three', id: 1 }, { text: 'four', id: 2 }]); }); + + it('should edit leave element references intact', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'], + attachTagId: true + }); + var elements = instance.getTagElements(); + + instance.edit('three', 0).edit('four', 1); + + expect(instance.getTagElements()[0]).to.equal(elements[0]); + expect(instance.getTagElements()[1]).to.equal(elements[1]); + }); + }); + + describe('#move', function() { + it('should be chainable', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + var container = instance.move(0, 1).getContainer(); + + expect(container).to.equal(this.container); + }); + + it('should throw if first argument is not a number', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + + expect(instance.move.bind(instance, null)).to.throw(); + }); + + it('should throw if second argument is not a number', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + + expect(instance.move.bind(instance, 0, null)).to.throw(); + }); + + it('should throw if either argument is greater than tag length', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + + expect(instance.move.bind(instance, 0, 3)).to.throw(); + expect(instance.move.bind(instance, 3, 0)).to.throw(); + }); + + it('should throw if either argument is less than 0', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + + expect(instance.move.bind(instance, 0, -1)).to.throw(); + expect(instance.move.bind(instance, -1, 1)).to.throw(); + }); + + it('should move tags appropriately', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + + instance.move(0, 1); + + expect(instance.getTagValues()).to.eql(['two', 'one']); + }); + + it('should edit leave tag ids intact', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'], + attachTagId: true + }); + + instance.move(0, 1); + + expect(instance.getTagValues()).to.eql([{ text: 'two', id: 2 }, { text: 'one', id: 1 }]); + }); + + it('should edit leave element references intact', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'] + }); + var elements = instance.getTagElements(); + var fromIndex = 0; + var destinationIndex = 1; + + + instance.move(fromIndex, destinationIndex); + + expect(instance.getTagElements()[destinationIndex]).to.equal(elements[fromIndex]); + }); + + it('should edit leave element references intact with attached tag ids', function() { + var instance = new Taggle(this.container, { + tags: ['one', 'two'], + attachTagId: true + }); + var elements = instance.getTagElements(); + var fromIndex = 0; + var destinationIndex = 1; + + + instance.move(fromIndex, destinationIndex); + + expect(instance.getTagElements()[destinationIndex]).to.equal(elements[fromIndex]); + }); }); describe('#remove', function() {