Skip to content

Commit 9507c36

Browse files
committedDec 26, 2020
[FEAT] #709 - Programmatically adding tags in mix-mode
1 parent ecefa02 commit 9507c36

File tree

2 files changed

+64
-19
lines changed

2 files changed

+64
-19
lines changed
 

‎src/parts/events.js

+1-10
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ export default {
8686
eventData = {relatedTarget:e.relatedTarget},
8787
isTargetSelectOption = this.state.actions.selectOption && (ddEnabled || !_s.dropdown.closeOnSelect),
8888
isTargetAddNewBtn = this.state.actions.addNew && ddEnabled,
89-
selection = window.getSelection(),
9089
shouldAddTags;
9190

9291
if( type == 'blur' ){
@@ -117,15 +116,7 @@ export default {
117116
this.dropdown.hide.call(this)
118117
// reset state which needs reseting
119118
this.state.dropdown.visible = undefined
120-
121-
// save last selection place to be able to inject anything from outside to that specific place
122-
this.state.selection = {
123-
anchorOffset : selection.anchorOffset,
124-
anchorNode: selection.anchorNode
125-
}
126-
127-
if (selection.getRangeAt && selection.rangeCount)
128-
this.state.selection.range = selection.getRangeAt(0)
119+
this.setStateSelection()
129120
}
130121

131122
return

‎src/tagify.js

+63-9
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,20 @@ Tagify.prototype = {
156156
return s;
157157
},
158158

159+
setStateSelection(){
160+
var selection = window.getSelection()
161+
162+
// save last selection place to be able to inject anything from outside to that specific place
163+
var sel = {
164+
anchorOffset: selection.anchorOffset,
165+
anchorNode : selection.anchorNode,
166+
range : selection.getRangeAt && selection.rangeCount && selection.getRangeAt(0)
167+
}
168+
169+
this.state.selection = sel
170+
return sel
171+
},
172+
159173
/**
160174
* Get the caret position relative to the viewport
161175
* https://stackoverflow.com/q/58985076/104380
@@ -364,7 +378,6 @@ Tagify.prototype = {
364378
? document.createTextNode(newNode)
365379
: newNode
366380

367-
tagElm.appendChild(newNode)
368381
tagElm.parentNode.insertBefore(newNode, tagElm.nextSibling)
369382
return newNode
370383
},
@@ -533,7 +546,7 @@ Tagify.prototype = {
533546
/**
534547
* injects nodes/text at caret position, which is saved on the "state" when "blur" event gets triggered
535548
* @param {Node} injectedNode [the node to inject at the caret position]
536-
* @param {Object} selection [optional selection Object. must have "anchorNode" & "anchorOffset"]
549+
* @param {Object} selection [optional range Object. must have "anchorNode" & "anchorOffset"]
537550
*/
538551
injectAtCaret( injectedNode, range ){
539552
range = range || this.state.selection.range
@@ -1175,19 +1188,60 @@ Tagify.prototype = {
11751188

11761189
/**
11771190
* Adds a mix-content tag
1178-
* @param {String/Array} tagsItems [A string (single or multiple values with a delimiter), or an Array of Objects or just Array of Strings]
1191+
* @param {String/Array} tagData A string (single or multiple values with a delimiter), or an Array of Objects or just Array of Strings
1192+
*/
1193+
addMixTags( tagsData ){
1194+
if( tagsData[0].prefix || this.state.tag ){
1195+
this.prefixedTextToTag(tagsData[0])
1196+
return
1197+
}
1198+
1199+
if( typeof tagsData == 'string' )
1200+
tagsData = [{ value:tagsData }]
1201+
1202+
1203+
var selection = !!this.state.selection, // must be cast, not to use the reference which is changing
1204+
frag = document.createDocumentFragment()
1205+
1206+
tagsData.forEach(tagData => {
1207+
var tagElm = this.createTagElem(tagData)
1208+
frag.appendChild(tagElm)
1209+
this.insertAfterTag(tagElm)
1210+
})
1211+
1212+
// if "selection" exists, assumes intention of inecting the new tag at the last
1213+
// saved location of the caret inside "this.DOM.input"
1214+
if( selection ){
1215+
this.injectAtCaret(frag)
1216+
}
1217+
// else, create a range and inject the new tag as the last child of "this.DOM.input"
1218+
else{
1219+
this.DOM.input.focus()
1220+
selection = this.setStateSelection()
1221+
selection.range.setStart(this.DOM.input, selection.range.endOffset)
1222+
selection.range.setEnd(this.DOM.input, selection.range.endOffset)
1223+
this.DOM.input.appendChild(frag)
1224+
1225+
this.updateValueByDOMTags() // updates internal "this.value"
1226+
this.update() // updates original input/textarea
1227+
}
1228+
},
1229+
1230+
/**
1231+
* Adds a tag which was activly typed by the user
1232+
* @param {String/Array} tagsItem [A string (single or multiple values with a delimiter), or an Array of Objects or just Array of Strings]
11791233
*/
1180-
addMixTags( tagsItems ){
1234+
prefixedTextToTag( tagsItem ){
11811235
var _s = this.settings,
11821236
tagElm,
11831237
createdFromDelimiters = this.state.tag.delimiters
11841238

1185-
_s.transformTag.call(this, tagsItems[0])
1239+
_s.transformTag.call(this, tagsItem)
11861240

1187-
tagsItems[0].prefix = tagsItems[0].prefix || this.state.tag ? this.state.tag.prefix : (_s.pattern.source||_s.pattern)[0];
1241+
tagsItem.prefix = tagsItem.prefix || this.state.tag ? this.state.tag.prefix : (_s.pattern.source||_s.pattern)[0];
11881242

11891243
// TODO: should check if the tag is valid
1190-
tagElm = this.createTagElem(tagsItems[0])
1244+
tagElm = this.createTagElem(tagsItem)
11911245

11921246
// tries to replace a taged textNode with a tagElm, and if not able,
11931247
// insert the new tag to the END if "addTags" was called from outside
@@ -1197,7 +1251,7 @@ Tagify.prototype = {
11971251

11981252
setTimeout(()=> tagElm.classList.add(this.settings.classNames.tagNoAnimation), 300)
11991253

1200-
this.value.push(tagsItems[0])
1254+
this.value.push(tagsItem)
12011255
this.update()
12021256

12031257
// fixes a firefox bug where if the last child of the input is a tag and not a text, the input cannot get focus (by Tab key)
@@ -1207,7 +1261,7 @@ Tagify.prototype = {
12071261
}, this.isFirefox ? 100 : 0)
12081262

12091263
this.state.tag = null
1210-
this.trigger('add', extend({}, {tag:tagElm}, {data:tagsItems[0]}))
1264+
this.trigger('add', extend({}, {tag:tagElm}, {data:tagsItem}))
12111265

12121266
return tagElm
12131267
},

0 commit comments

Comments
 (0)
Please sign in to comment.