You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.1 KiB
172 lines
5.1 KiB
<potato-field-tags>
|
|
<div class="field-tags">
|
|
|
|
<select name="{ state.options.name }[]" multiple style="display: none;">
|
|
<option each={ tag in state.tags } value={ tag }></option>
|
|
</select>
|
|
|
|
<label class="field-label">
|
|
<div class="field-input-group">
|
|
<input class="field-text" type="text" onkeypress={ handleKeyup } />
|
|
<button class="button button--add m-bottom-0 button--hover-icon-contrast" type="button" onclick={ () => { handleAdd() }}>
|
|
<svg class="icon"><use xlink:href="symbol-defs.svg#icon-add" /></svg>
|
|
</button>
|
|
</div>
|
|
</label>
|
|
|
|
<ul class="field-tags__list m-top-4 m-bottom-0" if={ state.tags.length > 0 }>
|
|
<li class="badge field-tags__item field-tags__item--active" each={ tag in state.tags }>
|
|
<span class="field-tags__label">{ tag }</span>
|
|
<button class="button m-bottom-0 button--hover-icon-contrast" type="button" onclick={ () => { handleRemove(tag) } }>
|
|
<svg class="icon"><use xlink:href="symbol-defs.svg#icon-remove" /></svg>
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div if={ state.errors && state.errors.length > 0 } class="field-error">
|
|
<ul>
|
|
<li each={ error in state.errors }>
|
|
{ error }
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
</div>
|
|
<script>
|
|
|
|
import * as riot from 'riot'
|
|
import tagsStore from './../../stores/tags.js'
|
|
|
|
/**
|
|
* component field adding / remove tags for a form
|
|
*
|
|
* @author Björn Hase
|
|
* @license hhttps://www.gnu.org/licenses/gpl-3.0.en.html GPL-3
|
|
* @link https://gitea.node001.net/HerrHase/potato-launcher.git
|
|
*
|
|
*/
|
|
|
|
export default
|
|
{
|
|
state:
|
|
{
|
|
options: {
|
|
name: 'tags',
|
|
},
|
|
tags: [ ],
|
|
errors: [ ]
|
|
},
|
|
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
onBeforeMount()
|
|
{
|
|
if (this.props.options) {
|
|
this.state.options = Object.assign(this.state.options, this.props.options)
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
onMounted() {
|
|
tagsStore.on('update', (data) => {
|
|
|
|
// if no data is send, reset array
|
|
if (!data) {
|
|
data = []
|
|
}
|
|
|
|
this.state.tags = data
|
|
this.update()
|
|
})
|
|
},
|
|
|
|
/**
|
|
* check if "return" has pressed,
|
|
* if trigger click event for button
|
|
*
|
|
* @param Object event
|
|
*
|
|
*/
|
|
handleKeyup(event)
|
|
{
|
|
if (event.keyCode === 13) {
|
|
event.preventDefault()
|
|
|
|
// trigger to add tag
|
|
this.$('.button--add').click()
|
|
}
|
|
},
|
|
|
|
/**
|
|
* remove tag
|
|
*
|
|
*
|
|
* @param String tag
|
|
*
|
|
*/
|
|
handleRemove(tag)
|
|
{
|
|
for (let i = 0; i < this.state.tags.length; i++) {
|
|
if (this.state.tags[i] === tag) {
|
|
this.state.tags.splice(i, 1)
|
|
this.update()
|
|
break
|
|
}
|
|
}
|
|
|
|
this.$('input').focus()
|
|
},
|
|
|
|
/**
|
|
* adding tag, check if string already exists
|
|
*
|
|
*
|
|
* @param Object event
|
|
*
|
|
*/
|
|
handleAdd(event)
|
|
{
|
|
let inArray = false
|
|
|
|
// delete whitespace
|
|
let value = this.$('input').value.trim()
|
|
|
|
this.state.errors = []
|
|
|
|
// check if value already in data
|
|
for (let i = 0; i < this.state.tags.length; i++) {
|
|
if (value === this.state.tags[i]) {
|
|
inArray = true
|
|
|
|
this.state.errors.push('Already added')
|
|
this.update()
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
// if value is not already in data and longer than zero chars
|
|
if (inArray === false && value.length > 0) {
|
|
this.state.tags.push(value)
|
|
this.update()
|
|
|
|
// select new option
|
|
this.$('select option[value="' + value + '"]').selected = true
|
|
this.$('input').value = ''
|
|
} else if (value.length === 0) {
|
|
this.state.errors.push('Required!')
|
|
this.update()
|
|
}
|
|
|
|
// adding focus to input
|
|
this.$('input').focus();
|
|
}
|
|
}
|
|
|
|
</script>
|
|
</potato-field-tags> |