Vue.js How to clear the selected option in a dropdown? - javascript
I added a button inside my dropdown that needs to clear the selected city.
I added an event but it isn't clearing the selected option.
Could you please suggest me what am I doing wrong ? Thank you very much.
This is the button in my dropdown
methods: {
...mapActions({
fetchCitiesByName: "fetchCitiesByName",
fetchCityDetails: "fetchCityDetails",
}),
async onClientComboSelect({value, label})
{
this.cityId = value;
this.city = label;
this.option.city = label;
this.additionalSearchField = {cityId: this.option.cityId, label: this.option.city};
await this.fetchCityInfo({id: this.option.cityId, label: this.option.city});
},
noCitySelected()
{
this.option.cityId = null;
this.$emit('input', this.option.cityId);
this.$emit('on-button-action', item);
},
<!-- Select City -->
<div
class="select-form-field"
>
<label
for="city"
class="inline-3-columns"
>
<span class="title__field">City*</span>
<combo-select
id="city"
v-model="option.cityId"
api-location="fetchCitiesByName"
api-details-location="fetchCityDetails"
search-parameter="cityName"
:additional-search-fields="additionalSearchField"
:transformer="cityTransformer"
:button="{event: noCitySelected, text: 'No City', icon: 'minus'}"
:config="{
...comboConfig,
searchLabel: 'Search Cities',
}"
:button-event="noCitySelected"
class="input input__typeahead"
#on-select-item="onCityComboSelect"
/>
<input
v-model="option.cityId"
type="hidden"
name="cityId"
>
</label>
</div>
<!-- End -->
here is the dropdown combo-select that I need I need to use. Is it possible to clear
<script>
const COMBO_STATES = Object.freeze({
OPEN: "OPEN",
CLOSED: "CLOSED"
});
const LOADING_STATES = Object.freeze({
LOADING: "LOADING",
BLOCKED: "BLOCKED",
DEFAULT: "DEFAULT"
});
export default {
directives: {
clickOutside: vClickOutside.directive,
focus: {
inserted: (el) =>
{
el.focus();
}
}
},
components:
{
InfiniteScroll
},
model: {
prop: 'selectedId',
},
props:
{
apiLocation: {
type: String,
required: true,
default: ""
},
apiDetailsLocation: {
type: String,
required: false,
default: ""
},
transformer: {
type: Function,
required: true,
default: () => ([])
},
selectedId: {
type: Number|null,
required: false,
default: null
},
selectedItems: {
type: Array,
required: false,
default: () => ([])
},
searchParameter: {
type: String,
required: false,
default: "name"
},
// temporary as the form css is too much hassle to adjust
details: {
type: String|null,
required: false,
default: null
},
additionalSearchFields: {
type: Object,
required: false,
default: () => ({})
},
getter: {
type: String,
required: false,
default: ""
},
button: {
type: Object,
required: false,
default: null
},
config: {
type: Object,
required: true,
default: () => ({})
},
canSendDifferentValue: {
type: Boolean,
required: false,
default: true
}
},
data()
{
return {
searchable: "",
openState: COMBO_STATES.CLOSED,
itemsInitializationNotEmpty: false,
selectedItem: CSItem(),
items: [],
iterations: 0,
isLoading: false,
page: 0,
pagingLoadingState: LOADING_STATES.DEFAULT,
defaultConfig: {
itemsPerPage: 20,
numberOfItemsShown: 4,
searchLabel: "Search for more...",
showDefaultLabelOnSelect: false,
clearSelectedItems: false,
isEditable: true,
isImmediate: true
}
};
},
computed:
{
hasSubitemSlot()
{
return !!this.$slots.subitem || !!this.$scopedSlots.subitem;
},
isComboSelectEditable()
{
return this.innerConfig.isEditable;
},
isOpen()
{
return this.openState === COMBO_STATES.OPEN;
},
comboItems()
{
let items = this.items;
if(this.innerConfig.clearSelectedItems)
items = this.items.filter(({id}) => !this.selectedItems.includes(id));
return CSItemList(items, this.transformer);
},
comboSelectItem()
{
const defaultLabel = this.innerConfig.isEditable ? "Select" : "";
if(this.innerConfig.showDefaultLabelOnSelect) return defaultLabel;
if(this.selectedItem.value)
{
const {label = defaultLabel} = this.comboItems.find(({value}) => value === this.selectedItem.value) || {};
return label;
}
return this.selectedItem.label ? this.selectedItem.label : defaultLabel;
},
innerConfig()
{
return Object.assign({}, this.defaultConfig, this.config);
},
hasNoItems()
{
return this.filterItems(this.items).length === 0;
},
skip()
{
return this.innerConfig.itemsPerPage * this.page;
},
isPagingLoading()
{
return this.pagingLoadingState === LOADING_STATES.LOADING;
},
isPagingLoadingBlocked()
{
return this.pagingLoadingState === LOADING_STATES.BLOCKED;
}
},
watch:
{
additionalSearchFields:
{
deep: true,
handler(newValue, oldValue)
{
if(newValue && !isEqual(newValue, oldValue))
this.getItems(false);
}
},
selectedId: function(newValue, oldValue)
{
if(newValue === oldValue) return;
this.findSelectedItem();
},
items: function(newValue, oldValue)
{
const allItems = this.filterItems(newValue);
if (allItems.length === 0 && oldValue.length !== 0) return;
if (allItems.length === 0 && oldValue.length === 0 && this.itemsInitializationNotEmpty) return;
if(allItems.length === 0)
this.$emit("on-no-items");
this.itemsInitializationNotEmpty = true;
}
},
async mounted()
{
try
{
if(!this.innerConfig.isImmediate) return;
const initialSearchParams = this.searchable.length > 0 ? {[this.searchParameter]: this.searchable} : {};
this.items = await this.$store.dispatch(this.apiLocation, Object.assign({
top: this.innerConfig.itemsPerPage,
load: false,
skip: this.page,
...initialSearchParams
}, this.additionalSearchFields
));
this.findSelectedItem();
this.searchValue$ = "";
this.requestSubscription = requestSourceService
.getInstance()
.search
.subscribe(search =>
{
const {source, value} = search;
if(this.searchValue$ === value)
Reflect.apply(source.cancel, null, [
"Cancel previous request"
]);
this.searchValue$ = value;
});
}
catch(error)
{
this.errorHandler();
}
},
destroyed()
{
if(this.requestSubscription)
this.requestSubscription.unsubscribe();
},
methods:
{
errorHandler()
{
this.isLoading = false;
this.items = [];
},
search: debounce(async function()
{
if(this.searchable.length > 0 && this.searchable.length < 2) return;
this.isLoading = true;
await this.getItems(false);
}, 300),
async getItems(isCancelable = true)
{
try
{
this.page = 0;
this.items = await this.$store.dispatch(this.apiLocation, Object.assign({
top: this.innerConfig.itemsPerPage,
load: false,
skip: this.skip,
[this.searchParameter]: this.searchable ? this.searchable : null,
cancelable: isCancelable,
isThrowable: true,
}, this.additionalSearchFields));
this.isLoading = false;
const allItems = this.filterItems(this.items);
if(allItems.length === 0)
this.$emit("on-no-items");
this.pagingLoadingState = LOADING_STATES.DEFAULT;
this.findSelectedItem();
}
catch(error)
{
this.errorHandler(error);
}
},
async findSelectedItem()
{
if(!this.selectedId) return;
const item = this.comboItems.find(item => item.value === this.selectedId);
if(item)
{
const selectedItem = CSItem({
value: this.selectedId,
label: item ? item.label : null,
...item
});
this.selectedItem = selectedItem;
this.iterations = 0;
}
else
{
{
if(!this.apiDetailsLocation) return;
if(this.iterations === 1) return;
const itemDetails = await this.$store.dispatch(this.apiDetailsLocation, {
id: this.selectedId,
isThrowable: true
});
this.items.push(itemDetails);
this.iterations = 1;
await this.findSelectedItem();
}
catch (error)
{
console.error(error);
}
}
},
selectItem(item)
{
this.selectedItem = item;
// check if it should be sent
if(this.canSendDifferentValue)
this.$emit('input', item.value);
this.$emit('on-select-item', item);
this.close();
},
async onScrollEnd()
{
if(this.isPagingLoading || this.isPagingLoadingBlocked || (this.searchable.length > 0 && this.searchable.length < 2)) return;
try
{
this.pagingLoadingState = LOADING_STATES.LOADING;
this.page++;
const items = await this.$store.dispatch(this.apiLocation, Object.assign({
top: this.innerConfig.itemsPerPage,
load: false,
skip: this.skip,
[this.searchParameter]: this.searchable ? this.searchable : null,
isThrowable: true,
}, this.additionalSearchFields));
if(items.length === 0)
{
this.pagingLoadingState = LOADING_STATES.BLOCKED;
return;
}
this.items = this.items.concat(items);
const allItems = this.filterItems(this.items);
if(allItems.length === 0)
{
this.$emit("on-no-items");
}
this.pagingLoadingState = LOADING_STATES.DEFAULT;
}
catch(error)
{
console.error(error);
this.errorHandler(error);
this.pagingLoadingState = LOADING_STATES.DEFAULT;
}
},
filterItems(items)
{
return this.innerConfig.itemsFilter ? this.innerConfig.itemsFilter(items) : items;
},
dispatch(action)
{
this.$emit("on-button-action", action);
},
toggleComboOpenState()
{
if(!this.innerConfig.isEditable) return;
return this.openState = this.isOpen ? COMBO_STATES.CLOSED : COMBO_STATES.OPEN;
},
close()
{
this.openState = COMBO_STATES.CLOSED;
}
}
};
</script>
<template>
<div>
<div
v-click-outside="close"
:class="['combo-select', { 'combo-select__disabled': !isComboSelectEditable }]"
#click="toggleComboOpenState"
>
<span class="combo-select__selecteditem">
<span
v-if="comboSelectItem === 'Select'"
id="selected-item"
>{{ comboSelectItem }}</span>
<span
v-else
id="selected-item"
v-tippy="{ placement : 'bottom', content: comboSelectItem, }"
>{{ comboSelectItem }}</span>
</span>
<font-awesome-icon
icon="caret-down"
class="dropdown--arrow f-22"
/>
<transition
name="slidedown"
appear
>
<div
v-if="isOpen"
class="sub-menu"
>
<section class="sub-search input input__typeahead field">
<div class="input-group">
<input
v-model="searchable"
v-focus
type="text"
:placeholder="innerConfig.searchLabel"
#click.stop=""
#input="search"
>
<div class="input-group-append">
<font-awesome-icon
v-if="!isLoading"
icon="search"
class="typeahead-icon"
/>
<font-awesome-icon
v-if="isLoading"
icon="spinner"
class="fa-spin relative f-25 cl-body"
/>
</div>
</div>
</section>
<infinite-scroll
v-if="!hasSubitemSlot"
:button="button"
:is-loading="isPagingLoading"
#scroll-end="onScrollEnd"
>
<template #list>
<h2
v-for="(item, index) in comboItems"
:key="`${item.label}-${index}`"
v-tippy="{
placement : 'bottom',
content: item.label,
}"
:class="['sub-menu__item', {'selected': selectedItem.value === item.value}]"
#click.stop="selectItem(item)"
>
{{ item.label }}
</h2>
<h2
v-if="hasNoItems"
class="sub-menu__item pointer-events-none"
>
No items
</h2>
</template>
</infinite-scroll>
<infinite-scroll
v-if="hasSubitemSlot"
:button="button"
:is-loading="isPagingLoading"
#scroll-end="onScrollEnd"
>
<template #list>
<div
v-for="(item, index) in comboItems"
:key="`${item.label}-${index}`"
>
<slot
name="subitem"
:index="index"
:item="item"
:isSelected="selectedItem.value === item.value"
:close="close"
:action="selectItem"
/>
<h2
v-if="hasNoItems"
class="sub-menu__item pointer-events-none"
>
No items
</h2>
</div>
</template>
</infinite-scroll>
<section
v-if="button"
class="sub-button"
>
<button
class="btn btn--creation btn--creation--grey btn--creation--square w-100 h-100 br-r-0"
#click="dispatch(button.action)"
>
<font-awesome-icon :icon="button.icon" />
<span>{{ button.text }}</span>
</button>
</section>
<!-- this should be shown only on infinite loading -->
</div>
</transition>
</div>
<span
v-if="details"
class="flex w-mc f-11 cl-6f-grey p-l-10 p-t-3"
>({{ details }})</span>
</div>
</template>
You should show your UI component library name, because combo-select would have its own usage.
Maybe you can install vue-devtools to inspect data or other bugs in your development environment.
Related
vue-autosuggest output object-object on twice click
by the way this question very similar on Vue algolia autosuggest on select showing [Object object] but i still did not solve here is my debug or code <b-form-group label="Name Agen" label-for="vi-agen-name" > <span v-text="form.agen.name_agen" /> <vue-autosuggest id="vi-agen-name" v-model="form.agen.name_agen" :suggestions="[{ data: form.agen.agens }]" :limit="7" :input-props="{ id: 'autosuggest__input', class: 'form-control', placeholder: 'Name Agen', }" #selected="onSelectedFrom" #input="searchForm($event, 'agen/', 'agen', 'name_agen')" > <template slot-scope="{suggestion}"> <span class="my-suggestion-item">{{ suggestion.item.name_agen }}</span> </template> </vue-autosuggest> </b-form-group> my problem: i have on typing yogi on form input select item that show on suggesstion : [ { data : [ { name_agen : 'Yogi' ..... <span v-text="form.agen.name_agen" /> // output : Yogi form input // output : yogi but when i tried to type again on form input yogiabc thats not show any suggestion so i remove by backspace so the input now is yogi then i tried select again the unexpected on twice select : <span v-text="form.agen.name_agen" /> // output : Yogi // why this result is string form input // output : object-object // but on form input is an object-object ? function code: async onSelectedFrom(option) { const model = this.form.currentModel const fieldSuggest = this.form.currentFieldSuggest const currentLoadData = this.form[`${model}`][`${model}s`] const currentField = this.form[`${model}`][`${fieldSuggest}`] this.form[`${model}`] = { isNew: false, [`${model}s`]: currentLoadData, ...option.item, } console.log('selected', this.form[`${model}`], 'Name Agen:', currentField) }, searchForm(keyword, uri, model, currentSuggest) { this.form.currentModel = model this.form.currentFieldSuggest = currentSuggest if (keyword) { clearTimeout(this.timeoutDebounce) this.timeoutDebounce = setTimeout(() => { useJwt.http.get(`${uri}`, { params: { keyword, single_search: true } }) .then(response => { // test debug if (response.data.total_items === 0) { // no data this.form[`${model}`].isNew = true this.form[`${model}`].user.full_name = null this.form.isAgenAndTrans = false this.form[`${model}`][`${model}s`] = [] console.log('no data show', this.form[`${model}`]) } else { // this.form[`${model}`].isNew = false this.form.isAgenAndTrans = false this.form[`${model}`][`${model}s`] = response.data[`${model}s`] } }).catch(e => { this.form[`${model}`].isNew = true this.form[`${model}`].user.full_name = null this.form.isAgenAndTrans = false this.form[`${model}`][`${model}s`] = [] }) }, 300) } }, then these the data data() { return { payload: [], form: { currentModel: '', currentFieldSuggest: '', isAgenAndTrans: false, agen: { isNew: true, id: 0, name_agen: '', dm_personal_id: 0, user: { full_name: '', }, agens: [], }, } } }
default value of autocomplete with vuetify
so i make an signup and address form for every user and i want every time the user is connected and navigate to the profile page, he will edit his details. now i have async autocomplete from api that get for me all the items in object format, so i tried to give the v-model an default value but it didn't change, i guess there is supposed to be connection between the items to the v-model, so i tried to fake the async search and get the items but still couldn't see the default value. i don't care if the value wont be in the data i just want to see it visual <script> export default { props: { cmd: { type: String }, itemText: { type: String }, itemValue: { type: String }, label: { type: String }, city: { type: Number }, street: { type: Number }, type: { type: String }, defaultValue: { type: String || Number } }, data() { return { loading: false, items: [], search: null, select: null }; }, watch: { search(val) { val && val !== this.select && this.querySelections(val); }, select(val) { if (val !== this.defaultValue) { this.$emit("selected", { value: val[this.itemValue], text: val[this.itemText] }); } } }, async mounted() { const defaultSelected = {}; defaultSelected[`${this.itemText}`] = this.defaultValue ? this.defaultValue.value : this.defaultValue; defaultSelected[`${this.itemValue}`] = this.defaultValue ? this.defaultValue.id : this.defaultValue; await this.querySelections(defaultSelected[`${this.itemText}`]); console.log(this.items); // this.select = defaultSelected[`${this.itemText}`]; }, methods: { async querySelections(v) { this.loading = true; // Simulated ajax query const data = (await this.$services.SearchService.searchAddress(v, this.cmd, this.city, this.street)).data; console.log(data); if (this.type === "city") { this.items = data.Data[`CitiesRes`]; } if (this.type === "street") { this.items = data.Data[`StreetsRes`]; } if (this.type === "streetNumber") { this.items = data.Data["NumbersRes"]; } this.loading = false; }, asyncinsertDefualtData() {} } }; </script> <template> <v-autocomplete v-model="select" :loading="loading" :items="items" :search-input.sync="search" :item-text="itemText" :item-value="itemValue" :value="defaultValue" return-object cache-items flat hide-no-data hide-details solo :label="label" ></v-autocomplete> </template>
Updating Array from AsyncStorage
I have an array of objects called audioBaby. When the app launches I check asyncStorage and if any key has value active, I want to update the lock keys in the array. What I have done is not updating all objects in array but only the last object. How can I initially update the array from asyncStorage and render the screen? const [audioBaby, setAudioBaby] = useState([ { lock: "deactive", url: "item0.mp3", }, { lock: "deactive", url: "item1.mp3", }, { lock: "deactive", url: "item2.mp3", }, ]); useEffect(() => { try { AsyncStorage.multiGet([ "babyAudio0Status", //value: active "babyAudio1Status", //value: active "babyAudio2Status", //value: active ]).then((response) => { let updatedList = audioBaby; if (response[0][1] != "null" && response[0][1] == "active") { updatedList = audioBaby.map((item) => { if (item.url == "item0.mp3") { return { ...item, lock: "active" }; } return item; }); } if (response[1][1] != "null" && response[1][1] == "active") { updatedList = audioBaby.map((item) => { if (item.url == "item1.mp3") { return { ...item, lock: "active" }; } return item; }); } if (response[2][1] != "null" && response[2][1] == "active") { updatedList = audioBaby.map((item) => { if (item.url == "item2.mp3") { return { ...item, lock: "active" }; } return item; }); } setAudioBaby(updatedList) }); } catch (error) { console.log("error::", error); } }, []); Final array should be like this: [ { lock: "active", url: "item0.mp3", }, { lock: "active", url: "item1.mp3", }, { lock: "active", url: "item2.mp3", }, ]
I moved all ifs to inside of map function and everything is fine. let updatedList = audioBaby.map((item) => { if (item.url === 'item0.mp3' && response[0][1] === 'active') { return { ...item, lock: 'active' } } if (item.url === 'item1.mp3' && response[1][1] === 'active') { return { ...item, lock: 'active' } } if (item.url === 'item2.mp3' && response[2][1] === 'active') { return { ...item, lock: 'active' } } return item })
Return single property from object array
When I try to return a specific property from my array, the terminal say: TypeError: Cannot read property 'url' of undefined. I want to search a specific element that valid this button.id === this.state.currentId control. So, when it's true I want to return element.buttonColor and, in the other method I want that its return 'element.url'. Why the first method: getCurrentBackgroundColor work and the second: getCurrentImage don't work? this.state = { currentId: null, buttons: [ { id: 0, url: "./url1.jpg", buttonColor: "#b2d8ca" }, { id: 1, url: "./url2.jpg", buttonColor: "#fef6bb" } ], }; getCurrentBackgroundColor = () => { const currentButton = this.state.buttons.find((button) => { return button.id === this.state.currentId; }); return currentButton === undefined ? "" : currentButton.buttonColor; }; getCurrentImage = () => { const currentButton = this.state.buttons.find((button) => { return button.id === this.state.currentId; }); return currentButton === undefined ? "" : currentButton.url; }; render() { return ( <div className="App"> <LeftRight backColor={this.getCurrentBackgroundColor()} image={this.getCurrentImage()} /> </div> } //In the LEFTRIGHT class <div id="left" style={{ backgroundColor: this.props.backColor }} key={this.props.backColor} > <img src={this.props.image}/> </div>
I noticed your current id is not set, you can change 'null' in the return sentence. this.state = { currentId: 0, buttons: [ { id: 0, url: "./url1.jpg", buttonColor: "#b2d8ca" }, { id: 1, url: "./url2.jpg", buttonColor: "#fef6bb" } ], }; getCurrentBackgroundColor = () => { const currentButton = this.state.buttons.find((button) => { return button.id === this.state.currentId; }); return currentButton === undefined ? "" : currentButton.buttonColor; }; getCurrentImage = () => { const currentButton = this.state.buttons.find((button) => { return button.id === this.state.currentId; }); return currentButton === undefined ? "" : currentButton.url; }; console.log("Background: ", getCurrentBackgroundColor()) console.log("Current Image: ", getCurrentImage())
this.state = { currentId: 1, buttons: [{ id: 0, url: "./url1.jpg", buttonColor: "#b2d8ca" }, { id: 1, url: "./url2.jpg", buttonColor: "#fef6bb" } ], }; getCurrentBackgroundColor = () => { this.state.buttons.map((button) => { if (this.state.currentId === button.id) return console.log(button.buttonColor) }); }; getCurrentBackgroundColor()
vuejs Data property undefined
I am having trouble where a property is returning undefined inside the vuejs instance, but returns the correct value in the HTML. data: { ... userFilter: 'all', ... }, The alert is returning this.userFilter as undefined filters: { all: function(tasks) { alert(this.userFilter); // This is undefined if(this.userFilter == 'all'){ return tasks; }else{ return tasks.filter(function(task){ return task.user_id == this.userFilter; }); } }, } Dropdown to select user to filter by <select class="form-control" v-if="visibility == 'all'" v-model="userFilter"> <option selected value="all">Showing all users tasks</option> <option v-for="user in users" value="#{{user.id}}"> #{{user.first_name}} #{{user.last_name}} </option> </select> The below correctly displays the value of userFilter #{{ userFilter }} Entire code: var tasks = new Vue({ el: '#tasks', data: { tasks: [], users: [], newTask: { description: '', due_at: '', user_id: '', completed: false }, editingTask: false, showAlert: false, loading: true, visibility: 'active', validation: [], showUser: null, authUser: {} }, ready: function() { this.getAuthUser(); this.getTasks(); this.getUsers(); }, computed: { filteredTasks: function () { return this.$options.filters[this.visibility](this.tasks); }, remaining: function() { return this.tasks.filter(function(task){ return !task.completed && task.user_id == this.authUser.id; }).length; } }, filters: { all: function(tasks) { return tasks; }, active: function(tasks) { return tasks.filter(function(task){ return !task.completed; }); }, completed: function(tasks) { return tasks.filter(function(task){ return task.completed; }); }, groupByDate: function(tasks) { var result = {}; for (var i = 0; i < tasks.length; i++) { var task = tasks[i]; // Convert due_at date to be used as array key var due_at = moment(task.due_at,'YYYY-MM-DD').format('DD-MM-YYYY'); if (result[due_at]) { result[due_at].push(task); } else { result[due_at] = [task]; } } return result; }, newDate: function(date) { return moment(date, 'DD-MM-YYYY').format('LL'); }, usersFilter: function(tasks, user_id) { if(this.visibility == 'all' && user_id){ return tasks.filter(function(task){ return task.user_id == user_id; }); }else{ return tasks; } } }, methods: { getTasks: function () { this.loading = true; this.$http.get('api/tasks/'+ this.visibility).success(function(tasks) { this.$set('tasks', tasks); this.loading = false; }).error(function(error) { console.log(error); }); }, getUsers: function() { this.$http.get('api/users/all',function(users){ this.$set('users',users); }); }, getAuthUser: function() { this.$http.get('api/users/current-user').success(function(authUser) { this.$set('authUser',authUser); }); }, toggleVisibility: function(filter) { this.visibility = filter; this.getTasks(); }, open: function(e) { e.preventDefault(); $('#add-task-modal').slideDown(); }, close: function(e) { e.preventDefault(); $('#add-task-modal').slideUp(); }, toggleAlert: function(message) { this.showAlert = true; $('.alert').text(message); $('.alert').fadeIn().delay(1000).fadeOut(); this.showAlert = false; }, addTask: function(e) { e.preventDefault(); if ( ! this.newTask) return; var task = this.newTask; this.$http.post('api/tasks', task) .success(function(data){ task.id = data.task_id; task.due_at = moment(task.due_at,'DD-MM-YYYY').format('YYYY-MM-DD'); if(this.visibility == 'all'){ this.tasks.push(task); }else if(this.authUser.id == task.user_id){ this.tasks.push(task); } $('.datepicker').datepicker('clearDates'); this.validation = []; this.newTask = { description: '', due_at: '', user_id: '', completed: '' }; this.$options.methods.toggleAlert('Task was added.'); }) .error(function(validation){ this.$set('validation', validation); }); }, toggleTaskCompletion: function(task) { task.completed = ! task.completed; this.$http.post('api/tasks/complete-task/'+ task.id, task); }, editTask: function(task) { if(task.completed) return; this.editingTask = task; }, cancelEdit: function (todo) { this.editingTask = false; }, updateTask: function(task) { task.description = task.description.trim(); this.$http.patch('api/tasks/'+ task.id, task); this.$options.methods.toggleAlert('Task was updated.'); return this.editingTask = false; }, deleteTask: function(due_at,task) { if(confirm('Are you sure you want to remove this task?')){ this.tasks.$remove(task); this.$http.delete('api/tasks/'+ task.id, task); this.$options.methods.toggleAlert('Task was removed.'); } } }, directives: { 'task-focus': function (value) { if (!value) { return; } var el = this.el; Vue.nextTick(function () { el.focus(); }); } } })
Try to use tasks.$data.visibility.