Converted tag autosuggestion to vue component
This commit is contained in:
		
							parent
							
								
									b023699f1b
								
							
						
					
					
						commit
						d3e4a1a6f9
					
				| 
						 | 
					@ -496,188 +496,6 @@ module.exports = function (ngApp, events) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }]);
 | 
					    }]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Tag Autosuggestions
 | 
					 | 
				
			||||||
     * Listens to child inputs and provides autosuggestions depending on field type
 | 
					 | 
				
			||||||
     * and input. Suggestions provided by server.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    ngApp.directive('tagAutosuggestions', ['$http', function ($http) {
 | 
					 | 
				
			||||||
        return {
 | 
					 | 
				
			||||||
            restrict: 'A',
 | 
					 | 
				
			||||||
            link: function (scope, elem, attrs) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Local storage for quick caching.
 | 
					 | 
				
			||||||
                const localCache = {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Create suggestion element
 | 
					 | 
				
			||||||
                const suggestionBox = document.createElement('ul');
 | 
					 | 
				
			||||||
                suggestionBox.className = 'suggestion-box';
 | 
					 | 
				
			||||||
                suggestionBox.style.position = 'absolute';
 | 
					 | 
				
			||||||
                suggestionBox.style.display = 'none';
 | 
					 | 
				
			||||||
                const $suggestionBox = $(suggestionBox);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // General state tracking
 | 
					 | 
				
			||||||
                let isShowing = false;
 | 
					 | 
				
			||||||
                let currentInput = false;
 | 
					 | 
				
			||||||
                let active = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Listen to input events on autosuggest fields
 | 
					 | 
				
			||||||
                elem.on('input focus', '[autosuggest]', function (event) {
 | 
					 | 
				
			||||||
                    let $input = $(this);
 | 
					 | 
				
			||||||
                    let val = $input.val();
 | 
					 | 
				
			||||||
                    let url = $input.attr('autosuggest');
 | 
					 | 
				
			||||||
                    let type = $input.attr('autosuggest-type');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Add name param to request if for a value
 | 
					 | 
				
			||||||
                    if (type.toLowerCase() === 'value') {
 | 
					 | 
				
			||||||
                        let $nameInput = $input.closest('tr').find('[autosuggest-type="name"]').first();
 | 
					 | 
				
			||||||
                        let nameVal = $nameInput.val();
 | 
					 | 
				
			||||||
                        if (nameVal !== '') {
 | 
					 | 
				
			||||||
                            url += '?name=' + encodeURIComponent(nameVal);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    let suggestionPromise = getSuggestions(val.slice(0, 3), url);
 | 
					 | 
				
			||||||
                    suggestionPromise.then(suggestions => {
 | 
					 | 
				
			||||||
                        if (val.length === 0) {
 | 
					 | 
				
			||||||
                            displaySuggestions($input, suggestions.slice(0, 6));
 | 
					 | 
				
			||||||
                        } else  {
 | 
					 | 
				
			||||||
                            suggestions = suggestions.filter(item => {
 | 
					 | 
				
			||||||
                                return item.toLowerCase().indexOf(val.toLowerCase()) !== -1;
 | 
					 | 
				
			||||||
                            }).slice(0, 4);
 | 
					 | 
				
			||||||
                            displaySuggestions($input, suggestions);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Hide autosuggestions when input loses focus.
 | 
					 | 
				
			||||||
                // Slight delay to allow clicks.
 | 
					 | 
				
			||||||
                let lastFocusTime = 0;
 | 
					 | 
				
			||||||
                elem.on('blur', '[autosuggest]', function (event) {
 | 
					 | 
				
			||||||
                    let startTime = Date.now();
 | 
					 | 
				
			||||||
                    setTimeout(() => {
 | 
					 | 
				
			||||||
                        if (lastFocusTime < startTime) {
 | 
					 | 
				
			||||||
                            $suggestionBox.hide();
 | 
					 | 
				
			||||||
                            isShowing = false;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }, 200)
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                elem.on('focus', '[autosuggest]', function (event) {
 | 
					 | 
				
			||||||
                    lastFocusTime = Date.now();
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                elem.on('keydown', '[autosuggest]', function (event) {
 | 
					 | 
				
			||||||
                    if (!isShowing) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    let suggestionElems = suggestionBox.childNodes;
 | 
					 | 
				
			||||||
                    let suggestCount = suggestionElems.length;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Down arrow
 | 
					 | 
				
			||||||
                    if (event.keyCode === 40) {
 | 
					 | 
				
			||||||
                        let newActive = (active === suggestCount - 1) ? 0 : active + 1;
 | 
					 | 
				
			||||||
                        changeActiveTo(newActive, suggestionElems);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    // Up arrow
 | 
					 | 
				
			||||||
                    else if (event.keyCode === 38) {
 | 
					 | 
				
			||||||
                        let newActive = (active === 0) ? suggestCount - 1 : active - 1;
 | 
					 | 
				
			||||||
                        changeActiveTo(newActive, suggestionElems);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    // Enter or tab key
 | 
					 | 
				
			||||||
                    else if ((event.keyCode === 13 || event.keyCode === 9) && !event.shiftKey) {
 | 
					 | 
				
			||||||
                        currentInput[0].value = suggestionElems[active].textContent;
 | 
					 | 
				
			||||||
                        currentInput.focus();
 | 
					 | 
				
			||||||
                        $suggestionBox.hide();
 | 
					 | 
				
			||||||
                        isShowing = false;
 | 
					 | 
				
			||||||
                        if (event.keyCode === 13) {
 | 
					 | 
				
			||||||
                            event.preventDefault();
 | 
					 | 
				
			||||||
                            return false;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Change the active suggestion to the given index
 | 
					 | 
				
			||||||
                function changeActiveTo(index, suggestionElems) {
 | 
					 | 
				
			||||||
                    suggestionElems[active].className = '';
 | 
					 | 
				
			||||||
                    active = index;
 | 
					 | 
				
			||||||
                    suggestionElems[active].className = 'active';
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Display suggestions on a field
 | 
					 | 
				
			||||||
                let prevSuggestions = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                function displaySuggestions($input, suggestions) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Hide if no suggestions
 | 
					 | 
				
			||||||
                    if (suggestions.length === 0) {
 | 
					 | 
				
			||||||
                        $suggestionBox.hide();
 | 
					 | 
				
			||||||
                        isShowing = false;
 | 
					 | 
				
			||||||
                        prevSuggestions = suggestions;
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Otherwise show and attach to input
 | 
					 | 
				
			||||||
                    if (!isShowing) {
 | 
					 | 
				
			||||||
                        $suggestionBox.show();
 | 
					 | 
				
			||||||
                        isShowing = true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if ($input !== currentInput) {
 | 
					 | 
				
			||||||
                        $suggestionBox.detach();
 | 
					 | 
				
			||||||
                        $input.after($suggestionBox);
 | 
					 | 
				
			||||||
                        currentInput = $input;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Return if no change
 | 
					 | 
				
			||||||
                    if (prevSuggestions.join() === suggestions.join()) {
 | 
					 | 
				
			||||||
                        prevSuggestions = suggestions;
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Build suggestions
 | 
					 | 
				
			||||||
                    $suggestionBox[0].innerHTML = '';
 | 
					 | 
				
			||||||
                    for (let i = 0; i < suggestions.length; i++) {
 | 
					 | 
				
			||||||
                        let suggestion = document.createElement('li');
 | 
					 | 
				
			||||||
                        suggestion.textContent = suggestions[i];
 | 
					 | 
				
			||||||
                        suggestion.onclick = suggestionClick;
 | 
					 | 
				
			||||||
                        if (i === 0) {
 | 
					 | 
				
			||||||
                            suggestion.className = 'active';
 | 
					 | 
				
			||||||
                            active = 0;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        $suggestionBox[0].appendChild(suggestion);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    prevSuggestions = suggestions;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Suggestion click event
 | 
					 | 
				
			||||||
                function suggestionClick(event) {
 | 
					 | 
				
			||||||
                    currentInput[0].value = this.textContent;
 | 
					 | 
				
			||||||
                    currentInput.focus();
 | 
					 | 
				
			||||||
                    $suggestionBox.hide();
 | 
					 | 
				
			||||||
                    isShowing = false;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Get suggestions & cache
 | 
					 | 
				
			||||||
                function getSuggestions(input, url) {
 | 
					 | 
				
			||||||
                    let hasQuery = url.indexOf('?') !== -1;
 | 
					 | 
				
			||||||
                    let searchUrl = url + (hasQuery ? '&' : '?') + 'search=' + encodeURIComponent(input);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Get from local cache if exists
 | 
					 | 
				
			||||||
                    if (typeof localCache[searchUrl] !== 'undefined') {
 | 
					 | 
				
			||||||
                        return new Promise((resolve, reject) => {
 | 
					 | 
				
			||||||
                            resolve(localCache[searchUrl]);
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    return $http.get(searchUrl).then(response => {
 | 
					 | 
				
			||||||
                        localCache[searchUrl] = response.data;
 | 
					 | 
				
			||||||
                        return response.data;
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ngApp.directive('entityLinkSelector', [function($http) {
 | 
					    ngApp.directive('entityLinkSelector', [function($http) {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            restrict: 'A',
 | 
					            restrict: 'A',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,130 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const template = `
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <input :value="value" :autosuggest-type="type" ref="input"
 | 
				
			||||||
 | 
					            :placeholder="placeholder" :name="name"
 | 
				
			||||||
 | 
					            @input="inputUpdate($event.target.value)" @focus="inputUpdate($event.target.value)"
 | 
				
			||||||
 | 
					            @blur="inputBlur"
 | 
				
			||||||
 | 
					            @keydown="inputKeydown"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <ul class="suggestion-box" v-if="showSuggestions">
 | 
				
			||||||
 | 
					            <li v-for="(suggestion, i) in suggestions"
 | 
				
			||||||
 | 
					                @click="selectSuggestion(suggestion)"
 | 
				
			||||||
 | 
					                :class="{active: (i === active)}">{{suggestion}}</li>
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function data() {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        suggestions: [],
 | 
				
			||||||
 | 
					        showSuggestions: false,
 | 
				
			||||||
 | 
					        active: 0,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ajaxCache = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = ['url', 'type', 'value', 'placeholder', 'name'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getNameInputVal(valInput) {
 | 
				
			||||||
 | 
					    let parentRow = valInput.parentNode.parentNode;
 | 
				
			||||||
 | 
					    let nameInput = parentRow.querySelector('[autosuggest-type="name"]');
 | 
				
			||||||
 | 
					    return (nameInput === null) ? '' : nameInput.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const methods = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputUpdate(inputValue) {
 | 
				
			||||||
 | 
					        this.$emit('input', inputValue);
 | 
				
			||||||
 | 
					        let params = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (this.type === 'value') {
 | 
				
			||||||
 | 
					            let nameVal = getNameInputVal(this.$el);
 | 
				
			||||||
 | 
					            if (nameVal !== "") params.name = nameVal;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.getSuggestions(inputValue.slice(0, 3), params).then(suggestions => {
 | 
				
			||||||
 | 
					            if (inputValue.length === 0) {
 | 
				
			||||||
 | 
					                this.displaySuggestions(suggestions.slice(0, 6));
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Filter to suggestions containing searched term
 | 
				
			||||||
 | 
					            suggestions = suggestions.filter(item => {
 | 
				
			||||||
 | 
					                return item.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1;
 | 
				
			||||||
 | 
					            }).slice(0, 4);
 | 
				
			||||||
 | 
					            this.displaySuggestions(suggestions);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputBlur() {
 | 
				
			||||||
 | 
					        setTimeout(() => {
 | 
				
			||||||
 | 
					            this.$emit('blur');
 | 
				
			||||||
 | 
					            this.showSuggestions = false;
 | 
				
			||||||
 | 
					        }, 100);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputKeydown(event) {
 | 
				
			||||||
 | 
					        if (event.keyCode === 13) event.preventDefault();
 | 
				
			||||||
 | 
					        if (!this.showSuggestions) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Down arrow
 | 
				
			||||||
 | 
					        if (event.keyCode === 40) {
 | 
				
			||||||
 | 
					            this.active = (this.active === this.suggestions.length - 1) ? 0 : this.active+1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Up Arrow
 | 
				
			||||||
 | 
					        else if (event.keyCode === 38) {
 | 
				
			||||||
 | 
					            this.active = (this.active === 0) ? this.suggestions.length - 1 : this.active-1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Enter or tab keys
 | 
				
			||||||
 | 
					        else if ((event.keyCode === 13 || event.keyCode === 9) && !event.shiftKey) {
 | 
				
			||||||
 | 
					            this.selectSuggestion(this.suggestions[this.active]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Escape key
 | 
				
			||||||
 | 
					        else if (event.keyCode === 27) {
 | 
				
			||||||
 | 
					            this.showSuggestions = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    displaySuggestions(suggestions) {
 | 
				
			||||||
 | 
					        if (suggestions.length === 0) {
 | 
				
			||||||
 | 
					            this.suggestions = [];
 | 
				
			||||||
 | 
					            this.showSuggestions = false;
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.suggestions = suggestions;
 | 
				
			||||||
 | 
					        this.showSuggestions = true;
 | 
				
			||||||
 | 
					        this.active = 0;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    selectSuggestion(suggestion) {
 | 
				
			||||||
 | 
					        this.$refs.input.value = suggestion;
 | 
				
			||||||
 | 
					        this.$refs.input.focus();
 | 
				
			||||||
 | 
					        this.$emit('input', suggestion);
 | 
				
			||||||
 | 
					        this.showSuggestions = false;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get suggestions from BookStack. Store and use local cache if already searched.
 | 
				
			||||||
 | 
					     * @param {String} input
 | 
				
			||||||
 | 
					     * @param {Object} params
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    getSuggestions(input, params) {
 | 
				
			||||||
 | 
					        params.search = input;
 | 
				
			||||||
 | 
					        let cacheKey = `${this.url}:${JSON.stringify(params)}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (typeof ajaxCache[cacheKey] !== "undefined") return Promise.resolve(ajaxCache[cacheKey]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this.$http.get(this.url, {params}).then(resp => {
 | 
				
			||||||
 | 
					            ajaxCache[cacheKey] = resp.data;
 | 
				
			||||||
 | 
					            return resp.data;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const computed = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {template, data, props, methods, computed};
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,15 @@
 | 
				
			||||||
const draggable = require('vuedraggable');
 | 
					const draggable = require('vuedraggable');
 | 
				
			||||||
 | 
					const autosuggest = require('./components/autosuggest');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let data = {
 | 
					let data = {
 | 
				
			||||||
    pageId: false,
 | 
					    pageId: false,
 | 
				
			||||||
    tags: [],
 | 
					    tags: [],
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const components = {draggable};
 | 
					const components = {draggable, autosuggest};
 | 
				
			||||||
 | 
					const directives = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let computed = {
 | 
					let computed = {};
 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let methods = {
 | 
					let methods = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,5 +64,5 @@ function mounted() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    data, computed, methods, mounted, components
 | 
					    data, computed, methods, mounted, components, directives
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -265,7 +265,7 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input.outline {
 | 
					.outline > input {
 | 
				
			||||||
  border: 0;
 | 
					  border: 0;
 | 
				
			||||||
  border-bottom: 2px solid #DDD;
 | 
					  border-bottom: 2px solid #DDD;
 | 
				
			||||||
  border-radius: 0;
 | 
					  border-radius: 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,10 +18,14 @@
 | 
				
			||||||
                <transition-group name="test" tag="div">
 | 
					                <transition-group name="test" tag="div">
 | 
				
			||||||
                    <div v-for="(tag, i) in tags" :key="tag.key">
 | 
					                    <div v-for="(tag, i) in tags" :key="tag.key">
 | 
				
			||||||
                        <div width="20" class="handle" ><i class="zmdi zmdi-menu"></i></div>
 | 
					                        <div width="20" class="handle" ><i class="zmdi zmdi-menu"></i></div>
 | 
				
			||||||
                        <div><input autosuggest="{{ baseUrl('/ajax/tags/suggest/names') }}" autosuggest-type="name" class="outline" :name="getTagFieldName(i, 'name')"
 | 
					                        <div>
 | 
				
			||||||
                                   v-model="tag.name" @change="tagChange(tag)" @blur="tagBlur(tag)" placeholder="{{ trans('entities.tag') }}"></div>
 | 
					                            <autosuggest url="/ajax/tags/suggest/names" type="name" class="outline" :name="getTagFieldName(i, 'name')"
 | 
				
			||||||
                        <div><input autosuggest="{{ baseUrl('/ajax/tags/suggest/values') }}" autosuggest-type="value" class="outline" :name="getTagFieldName(i, 'value')"
 | 
					                                   v-model="tag.name" @input="tagChange(tag)" @blur="tagBlur(tag)" placeholder="{{ trans('entities.tag') }}"/>
 | 
				
			||||||
                                   v-model="tag.value" @change="tagChange(tag)" @blur="tagBlur(tag)" placeholder="{{ trans('entities.tag_value') }}"></div>
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div>
 | 
				
			||||||
 | 
					                            <autosuggest url="/ajax/tags/suggest/values" type="value" class="outline" :name="getTagFieldName(i, 'value')"
 | 
				
			||||||
 | 
					                                         v-model="tag.value" @change="tagChange(tag)" @blur="tagBlur(tag)" placeholder="{{ trans('entities.tag') }}"/>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
                        <div width="10" v-show="tags.length !== 1" class="text-center text-neg" style="padding: 0;" @click="removeTag(tag)"><i class="zmdi zmdi-close"></i></div>
 | 
					                        <div width="10" v-show="tags.length !== 1" class="text-center text-neg" style="padding: 0;" @click="removeTag(tag)"><i class="zmdi zmdi-close"></i></div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </transition-group>
 | 
					                </transition-group>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue