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

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.

Related

How to format a list of string into columns of react bootstrap table 2 such that data doesn't flows out of actual columns

I am trying to render some data in tabular form using react-bootstrap-table but the data of one column is overlapping with the data of other columns. i wanted to keep my layout fixed and thus have added the css layout:fixed which is actually a requirement as well. But the final result is:
Actually for this column i'm getting an array of string from backend. e.g. ["DEPT","OLD","CUSTOM_FUNCTION",...] which is getting converted into a single string internally by react and i'm not sure how to further format it.
I also searched in react table docs at : https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-celledit.html#rich-editors but didn't find anything.
My ultimate goal is to visualize the data in a much better way like drop down or each element of array in new line within the same column expandable on some mouse click.
The above image can be considered as sample requirement where only the first element of list will be displayed on load and after clicking on arrow button it will show all the list items below one another in the same column as shown below.
I am not able to figure out which column prop will help me or whether it's even possible or not. The goal is exactly the same but a simple new line separated data will also do.
Column Definition Code:
{
dataField: 'data',
text: 'DATA',
editable: false,
filter: textFilter(),
headerStyle: () =>
{
return { width: '100px', textAlign: 'center'};
}
}
Table Creation Code:
<BootstrapTable
keyField='serialNo'
data={ this.state.data }
columns={ this.state.columns }
filter={ filterFactory() }
pagination={ paginationFactory({sizePerPage: 4}) }
cellEdit={ cellEditFactory({ mode: 'click'}) }
striped
hover
/>
Kindly help or suggest something appropriate.
Thanks
Check this sandbox.
https://codesandbox.io/s/competent-rain-2enlp
const columns = [{
dataField: 'id',
text: 'Product ID',
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'labels',
text: 'Labels',
formatter: (cell) => {
return <>{cell.map(label => <li>{label}</li>)}</>
},
}];
You need to define your own formatter in order to include "complex" html inside your table cell.

error on removing an object in list in vue

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.

How to loop through a list of components in VueJS

I may have gone about this completely the wrong way from the beginning so all advise is welcomed.
I am trying to create a basic page with inputs on the right and hints for the inputs on the left and when you focus on the inputs the appropriate hint is highlighted on the left.
There is a JSFiddle here: https://jsfiddle.net/eywraw8t/210693/
This will not work as I do not know how to find the appropriate hint to highlight (and set isHighlighted to false on all the other hints).
I managed to get a working example by adding a highlighted prop on the field object and not using a hint component. However in reality the fields data will come from the database so it won't have a highlighted parameter so a hint component seemed more sensible.
To put my question in simple terms: How can I find the relevant hint component when focused on an input?
JS Fiddle showing functionality without a component: https://jsfiddle.net/as2vxy79/
Broken JS Fiddle trying to use a component: https://jsfiddle.net/eywraw8t/210693/
Here is the JS outside JS Fiddle:
Vue.component('hint', {
template: `
<div class="hint" :class="{'highlight-hint': isHighlighted }">
<slot></slot>
</div>
`,
data() {
return {
isHighlighted: false
}
}
});
new Vue({
el: "#app",
data: {
fields: [
{
'id': 'name',
'hint': 'Put the name here'
},
{
'id': 'description',
'hint': 'Put the description here'
},
{
'id': 'more',
'hint': 'Put more here'
}
]
},
methods: {
onFocus(focusedField) {
// Somehow loop through the hints
// I am aware there is no "hints" property this is an example
this.hints.forEach(function(field) {
field.isHighlighted = (focusedField == field.id)
})
}
}
})
Short answer: you don't need a direct reference to the components displaying the hint because you can solve this problem using reactivity.
Only thing you need to do is add a data field which stores the field id you want to highlight and then conditionally add a class to the hint you want to highlight based on the selected id (or render the components conditionally).
new Vue({
el: "#app",
data: {
highlightedFieldId: '',
fields: [
{
'id': 'name',
'hint': 'Put the name here' },
{
'id': 'description',
'hint': 'Put the description here' },
{
'id': 'more',
'hint': 'Put more here' }
]
},
methods: {
onFocus(focusedFieldId) {
this.highlightedFieldId = focusedFieldId;
}
}
})
Here's an update to your Fiddle.
NOTES:
If you really need direct references you can use the ref directive (this also works in a list of components generated by v-for).
You should probably think about using tooltips for the hints. E.g. using Element UI's Tooltip.
UPDATE:
So, here's a solution using the ref directive to obtain a reference to the highlighted hint component. You can see that I used the field id in :ref but you still get an array from this.$refs[focusedFieldId] since there is a surrounding v-for. Other than that, it's pretty simple.
I also updated the hint component to accept the is-highlighted prop so it can change its class on its own (you previously used a data property for this which does not result in a component update).

Default Column are not displayed in Material Design Data Table (iamisti/mdDataTable)

I am trying to populate the <mdt-column> inside of <mdt-header-row> dynamically with an array from controller. This piece of code doesn't seem to work properly:
hide-column-by-default="c.selector_hidden"
When loading the table default columns are not displayed. Some columns are set as default and are excluded from the "column-selector", so even after selecting all columns in the selector these columns are not displayed.
When i set ...columnSelector: false}... in table-card it shows me my columns, but the functions to select column is gone!?
How can i fix this?
This is the mdt-header-row:
<mdt-header-row>
<mdt-column
hide-column-by-default="c.selector_hidden"
exclude-from-column-selector="c.selector_exclude"
column-sort="c.sort"
sortable-rows-default="c.sort_default"
column-key="{{c.key}}"
align-rule="{{c.align}}"
column-definition="{{c.definition}}"
ng-repeat="c in tableHeader"><span>{{c.name}}</span></mdt-column>
</mdt-header-row>
The Data is comming from this Array in controller:
$scope.tableHeader = [
{
name: 'Dessert (100g serving)',
definition: '',
align: 'left',
sort: true,
sort_default:false,
hidden: false,
selector_exclude:false,
selector_hidden:false
},...
I also created a fork for it:
https://codepen.io/anon/pen/JJQyKN?editors=1111
This piece of code doesn't seem to work properly:
hide-column-by-default="c.selector_hidden"
That's because you don't have a selector_hidden property in any of the objects in your tableHeader array. It should look something like this:
$scope.tableHeader = [
{
name: 'Dessert (100g serving)',
definition: '',
align: 'left',
sort: true,
sort_default:false,
hidden: false,
selector_exclude:false,
selector_hidden:true
},...
Actually the issue is whit this directive it self. I had to modify the md-data-table.js file and change "isVisible" references column to true. I as well changed the isHidden property to "isVisable" because that is what is referenced by the md-data-table-templates.js file. I modified the code further to match our requirements and therefor cannot provide specific patches. However, unfortunately this project seems to be abandoned by the developer.

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?

Categories

Resources