error on removing an object in list in vue - javascript

I'm deploying a client app with vue.js.
In this app I have some tabs that are being rendered using v-for. this tab array is formated like this in vuex store:
tabs: [
{
id: 1,
title: 'first tab',
number: '09389826331',
accountName: 'DelirCo',
contactName: 'PourTabarestani',
startTime: '2019-02-25 15:11:30',
endTime: '2019-02-25 18:04:10',
duration: null,
subject: '',
description: ''
},
{
id: 2,
title: 'second tab',
number: '09124578986',
accountName: 'Cisco',
accountGUID: '',
contactName: 'Arcada',
contactGUID: '',
startTime: '2019-02-25 15:11:45',
endTime: '2019-02-25 15:13:55',
duration: null,
subject: '',
description: ''
}
]
I'm using getters to load the tabs in my vuex store which renders the tabs using following template:
<template>
<div id="Tabs">
<vs-tabs color="#17a2b8" v-model="selectedTab">
<vs-tab v-for="tab in tabs" :key="tab.id" :vs-
label="tab.title">
<Tab :tab="tab"></Tab>
</vs-tab>
</vs-tabs>
</div>
</template>
I'm using vuesax components for creating the tabs displays.
each object in this list is a tab in my front end which shows the related data when I click each tab.
it's doing perfectly fine when I try to show the tabs or even adding another object in the array.
the problem is when I try to remove a certain item from this array the content goes away but the tab title (the button where I can select the tab with it) remains on the page.
I'm using
state.tabs.splice(objectIndex, 1)
state.selectedTab -= 1
for removing the tab and changing the selected tab to the previous one.
but as I said the title of the tab is not being removed like the picture below:
and when I click on that tab I'm getting this error:
webpack-internal:///./node_modules/vuesax/dist/vuesax.common.js:4408 Uncaught TypeError: Cannot set property 'invert' of undefined
at VueComponent.activeChild (webpack-internal:///./node_modules/vuesax/dist/vuesax.common.js:4408)
at click (webpack-internal:///./node_modules/vuesax/dist/vuesax.common.js:4127)
at invoker (webpack-internal:///./node_modules/vue/dist/vue.esm.js:2140)
at HTMLButtonElement.fn._withTask.fn._withTask (webpack-internal:///./node_modules/vue/dist/vue.esm.js:1925)
anyone have any suggestion around this matter ?

You can just add a key to the parent element to force the rerender.
<div :key="forceRender">
<vs-tabs :value="activeTab">
<template v-for="item in items">
<vs-tab :label="item.name" #click="onTabChange(item)">
<div class="con-tab-ejemplo">
<slot name="content"></slot>
</div>
</vs-tab>
</template>
</vs-tabs>
</div>
After that add a watcher on the items:
watch: {
items (val) {
this.forceRender += 1
}
},

It seems to be an issue with the vuesax library. The <vs-tabs> component doesn't support <vs-tab> components being added/removed as child components dynamically.
Here's an excerpt from the vsTab.vue file in the repo:
mounted(){
this.id = this.$parent.children.length
this.$parent.children.push({
label: this.vsLabel,
icon: this.vsIcon,
id: this.$parent.children.length,
listeners: this.$listeners,
attrs: this.$attrs
})
}
When the <vs-tab> component is mounted, it adds itself to the parent (<vs-tabs>) as a child, but it does not remove itself from this array when it is destroyed.
You can open an issue on their GitHub page to see if they could support what you want, or you can submit a pull request.

Related

ais-refinement-list in VueInstantSearch(Algolia) doesn't renders list

I have stucked with an issue using refinement list widget of algolia.
First of all my resulting data structure is like that:
[
{
objectID: 999,
title: 'some title',
categories: [
{
id: 444,
name: 'some name',
},
{...},
]
}
]
I have that type of structure on my page:
<ais-instant-search
:search-client="searchClient"
:initial-ui-state="{
index_Name: { query: searchedValue },
}"
index-name="index_Name"
>
<ais-index index-name="index_Name">
<ais-configure
:filters="facetsFilters"
:facets="['categories.id']"
:hits-per-page.camel="items"
/>
<ais-refinement-list attribute="categories.id" />
<div> ...Some other widgets nested in divs as ais-search-box, ais-sort-by, etc </div>
</ais-index>
</ais-instant-search>
Within ais-configure I have passed to filters a facetsFilters variable which contains string with such content:
"categories.id:1 OR categories.id:5"
and it works ok, I'm getting results within selected categories,
problems starts, when i try to get refinement-list here:
<ais-refinement-list attribute="categories.id" />
I have an empty list despite that on dashboard this attribute is added as an attributesForFacetings and in ais-configure filters parameters with categories.id in it also works well.
Any suggestions is highly appreciated !
Problem was in Dashboard of Algolia.
When we clicked on 'searchable' instead of 'filter only' radiobutton for chosen attributeForFaceting - everything starts working good.

How can I let the list page remember some params?

I have a Vue project, but there is a issue to me,
In my router.js:
{
path: '/home/aftersale_physicalserver_workpanel/:use_flag/:areapartition_homeshowtext',
meta: { keepAlive: true },
icon: 'compose',
name: 'aftersale_physicalserver_workpanel',
title: 'work panel',
component: resolve => {
require(['./views/main_home/home/components/general_admin_staff_panel/physicalserver/physicalserver_workpanel.vue'], resolve);
}
},
there is the code:
...
<template>
<lml-page
ref="lml_page_ref"
v-if=" origin_data && origin_data.count"
:data_count="origin_data.count"
:current.sync="cur_page"
#change_page_for_parent="server_change_page">
</lml-page>
</template>
...
<script>
export default {
props: {
...
cur_page: 1,
},
</script>
you see the cur_page is the page number. I want the URL append the page number.
because when I enter a detail page, when I go back, there will go to page 1 by default.
My purpose
my purpose is let the list_page remember some params. such as the upper page_number, and some search params. but in Vue I don't know how.
When I from a searched params page enter a detail page, when I go back:
<span class="go-left" #click="$router.go(-1)">
<Icon type="chevron-left"></Icon>
<span>Go back</span>
</span>
there will get a list_page without the searched data.
You would need to use either local storage or a central state, what I use is vuex like this:
onPageChange: function (pageNo) {
this.$store.dispatch(this.$mts.some.SOMETHING, pageNo);
},
Then you can call your store wherever you need and get the page number.
Look for the vuex docs on how to setup state management.
Like this:
this.page = this.$store.getters.some.page

Vue did not read my child component in v-for loops

What's wrong: Vue returns an empty array on when I console.log it. However when I clicked it in Developer Tools, the data was there!
Background story: I was actually trying to make a total value of child's data wheter child has this value or not, however upon trying to just opening the component data none showed up!
P.S. The child data will automatically updated every X seconds.
The result of console.log(this.$children); shows [] (empty array) in console. But when I clicked it, it opens the whole children array. But when I tried to reveal it via this.$children[0], it shows value of undefined!
So here's my link to JSFiddle https://jsfiddle.net/irfandyjip89/zmn5yhju/
Vue.component("comp", {
props: ["location"],
template: "#comp"
})
vm = new Vue({
el: "#vm",
data: {
location: [{
nation: "America",
money: "Dollar"
}, {
nation: "China",
money: "Yuan"
}, {
nation: "Thailand",
language: "Baht"
}]
},
computed: {
totalNation() {
console.log(this.$children)
return this.location.length
}
}
})
<section id="vm">
Total of Nations : {{totalNation}}
<comp v-for="loc in location" :location="loc.nation"></comp>
Child : {{$children}}
</section>
<template id="comp">
<li>{{location}}</li>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.min.js"></script>
What should happen:
I can access children's data.
Please feel free to ask for more information.

Checkbox form array data Vue 2

I have a checkbox list which is generated using a for loop that consists of an id and a name:
Data:
yards[{id:1,name:'test'}] etc
HTML:
<ul class="checkbox-list">
<template v-for="(yard, index) in yards">
<li>
<input type="checkbox"
v-bind:id="'yardlist_'+yard.name"
v-bind:value="yard.id"
v-model="newSchedule.yards.id">
<label v-bind:for="'yardlist_'+yard.name">{{ yard.name }}</label>
</li>
<li>
<input type="text"
class="form-control"
placeholder="Yard notes..."
v-model="newSchedule.yards.notes">
</li>
</template>
</ul>
I want to save the selected checkbox with the id and notes field in an array:
newSchedule: {
due_at: '',
notes: '',
users: [],
yards: [{id:'',notes:'']
}
I have tried using the index from the yards array: newSchedule.yards[index].notes but am getting the following error "TypeError: undefined is not an object (evaluating 'newSchedule.yards[index].id')"
Any ideas how I can achieve this?
** Update **
Here is a basic fiddle of what I am wanting to achieve:
https://jsfiddle.net/j7mxe5p2/13/
I think you are trying to mix the old jQuery or javascript way of doing things with Vue framework. You should not have to set id on <input> elements to capture or set its value.
The correct way to do this is as follows:
new Vue({
el: '#app',
data: function() {
return {
yards: [
{id: 1, name: 'test', selected: true},
{id: 2,name: 'test 2', selected: false},
{id: 3,name: 'test 3', selected: false},
{id: 4,name: 'test 4', selected: true}
]
};
},
template: `
<div class="list-of-yards"> <!-- You cannot use v-for on the top-level element -->
<label for="jack" v-for="yard in yards">
<input type="checkbox" v-model="yard.selected"> {{yard.name}}
</label>
</div>
`,
});
Here is a jsFiddle of the above code: https://jsfiddle.net/z48thf9a/
Things to note:
You cannot use v-for on the template tag itself
You cannot use v-for on the top-level element just inside template. The template should contain one and only enclosing element, typically a <div>
There is no need to set id on input elements. You need to use v-model for your model-view bindings
If you still have issues, please provide a jsFiddle to debug further.
Edited after comment #1 and #2:
My above response is focused more on constructing the Vue component and rendering the list with proper binding to the checkboxes.
To get the checked items into a separate array, you can use a computed property in the same component to run through the original array this.yards and create a new array of selected items only.
Here is the jsFiddle for capturing the checked values: https://jsfiddle.net/z48thf9a/1/
You may modify the above to capture only the id part, and rename selectedYards to newSchedule or whatever your app requires.
I am not sure if I understood your question correctly, and if this solves your issue. Can you please provide more code samples?

Ember Shepherd doesn't recognize DOM changes

Description
I am using ember with ember-shepherd and have come across an annoying issue. Every time the DOM is changed during the tutorial, shepherd doesn't seem to recognize any of the changes and therefore breaks when trying to anchor to a tag that wasn't there when it originally loaded.
Does anyone know how to make shepherd reload the DOM without reloading the entire page?
Example
controller.js
import Ember from 'ember';
export default Ember.Controller.extend({
tour: Ember.inject.service(),
showDiv: false,
setupTutorial: function () {
this.set('tour.steps', [
{
id: '1',
options: {
attachTo: '#some-div top',
text: 'Read me!',
when: {
hide: () => {
this.set('showDiv', true);
}
}
}
},
{
id: '2',
options: {
attachTo: '#hidden-div top',
text: 'Shhh I am hidden.'
}
}
]);
this.get('tour').trigger('start');
}.on('init')
});
template.hbs
<div id="some-div">
More stuff.
</div>
{{#if showDiv}}
<div id="hidden-div">
Blargh
</div>
{{/if}}
The first tour step will show perfectly fine, but the second step will not locate the "hidden-div" anchor after it is inserted into the DOM.
In current version of ember-shepard addon all tour dom elements of steps should exists before start of tour .trigger('start');

Categories

Resources