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.

Categories

Resources