I know you can make awesome stuff when you are free to format the results from super awesome instant search. But how about traditional tables..?
Would be nice to have the ability to present the result in a plain table. (or at least some documentation for it)
Been playing around with it and even though I set the
<tbody is="ais-results"> ... </tbody>
Still returns a div.
If we could just render the ais-results component as a tbody we would be all good.
Interesting use case, I'll need to try that out 👍
So indeed this is currently not do-able.
We would need to code our Results component as a render function and accepting the "tag name" as a prop. cc https://stackoverflow.com/questions/41748934/how-to-create-dynamic-tag-based-on-props-with-vue-2
Given the results component is simple, we might want to do the move.
I first want to make sure there is no other way.
Hey @blomdahldaniel , what do you think of #256?
Wow!
Haven't had the time to look it up but yeah,as far as I understood there was no other way but to solve it like you say.
Would be a great feature that would allow for even more flexibility and (for how I understand it) for a low cost.
Hey @blomdahldaniel , here is a working solution that does not require a new version of the library :
<ais-results inline-template>
<table>
<tbody>
<tr v-for="result in results" :key="result.objectID">
<td>{{ result.name }}</td>
<td>{{ result.description }}</td>
</tr>
</tbody>
</table>
</ais-results>
Let me know how that works out for you!
Here is a quick codepen that illustrates it: https://codepen.io/team/algolia/pen/qXRpzR?editors=1000
I'm also adding this to the docs in #257
waooo!! Bingo! Thanks for pointing that out! Ofc inline-template super rad man! Big thanks!
Glad that you'll add this to the docs. Like I said, this will offer even more flexibility!
Good job and thank you! :)
And thank you for spitting out the code example for me here in this issue!
Is anyone else finding that there are restrictions to using inline-template regarding accessing methods? For example, if I wanted to run a method that returned a string depending on the value of of something from my data object:
<ais-results>
<tr slot-scope="{ result }" :key="result.objectID">
<td>
<svg class="colour" :class="displayColour(result.Colour)">
<use xlink:href="#svg--bottle"></use>
</svg>
</td>
</tr>
</ais-results>
If I try to do the same as above with an in-line template, I'm unable to access the methods:
<script>
export default {
data() {
return {
}
},
methods: {
displayColour(colourName) {
let wineColour = 'bottle-colour--' + colourName.toLowerCase();
return wineColour;
}
}
}
</script>
Not using inline-template allows me to access all methods I need to access, but with the downside that I'm getting a <div> where I shouldn't, which breaks the visual of the table etc.
Is there a way to tag the <ais-results> in the same way you can with <router-link>? e.g.
<router-link tag="li" to="/foo">
Apologies if this should be a separate issue, but I figured that I might just be missing something obvious on the accessing methods whilst using the inline-template solution above.
Many thanks, TT
@techytuppers a tag on ais-results would be the wrapper tag, not that one of each result, right?
@Haroenv yes I guess I was thinking it could be the <tbody> rather than a <div>
@techytuppers I guess that makes sense in this case then. Do you think other components can also benefit from the tag prop?
@Haroenv I'm not sure, looking at the possibilities, the other components reference more than just a single element:
<ais-search-box> incorporates the search box, plus the actions buttons, so adding a tag wouldn't make much sense here as it wouldn't be clear which element you were overriding (or in fact why you would want to)
<ais-pagination> dictates both the <ul> and <li> which seems to be perfectly reasonable markup for it's purpose. If someone wants a wrapping element for styling purposes, they can add that wrapped around the component. Would it even be possible to supply two types of tags here? One for the <ul> and one for the <li> if someone really did want to change these? I'm not sure what the real value of this change would be though.
Thanks for the rapid responses :)
There’s also aid-input for the searchbox without the rest, but the other buttons are there for a11y etc
I don't think going for a "tag" is a good option as it will quickly add a lot of noise to the API.
Indeed when using inline-templates, the scope is the one of the component you are inlining the template for, that is why you can no longer access your methods. This is also why it is not recommended to use inline-templates in the official docs.
If you need to go specific on the tags + the behavior, I would go for a custom component and extend the existing one. It is very simple to do so. Is there any reason you don't want to go that route @techytuppers ?
@rayrutjes I'd be very happy to go for a custom component, and given the other behaviour I'm looking to implement (expandable child rows), it's by far the cleanest solution.
I was just attempting that based on both:
https://community.algolia.com/vue-instantsearch/components/results.html and
https://community.algolia.com/vue-instantsearch/getting-started/custom-components.html
But I'm struggling a bit to piece it all together. I'm clearly missing something! Would you have any suggestions?
My main.js includes import InstantSearch from 'vue-instantsearch'; and Vue.use(InstantSearch);
<!-- Parent.Vue -->
<template>
<div>
<ais-index app-id="XX" api-key="XX" index-name="XX">
<ais-results> <-- not sure how to "replace" this with a tbody element
<result-child slot-scope="{ result }"></result-child>
</ais-results>
</div>
</template>
<script>
import ResultChild from './Child.vue';
export default {
data() {
return {
}
},
methods: {
displayColour(colourName) {
console.log(colourName);
}
},
components: {
appResult: ResultChild,
},
}
</script>
<!-- Child.Vue -->
<template>
<tr class="main-row">
<td>{{ result.Colour }}</td>
<td>{{ result.Colour1 }}</td>
<tr>
<tr class="child-row">
<td>{{ result.OtherField }}</td>
<td>{{ result.OtherField2 }}</td>
<tr>
</template>
md5-1c066517a82bb14f7e01453dc584ce84
If I need to re mount the results, I'm unsure as to where I do that. Any tips on the above would be really appreciated, especially if I'm going in the complete wrong direction!
I would go with a custom "Results" component and not use the one shipped with the library.
You can just copy paste the existing Results.vue file, and adjust it.
That way you got full control over what's happening.
@rayrutjes Brilliant thank you so much. I've replaced all the code in Child.vue with the code from Results.vue, as well as copied across the component.js file as it was a mixin requirement. This solves all the problems. Thanks to @Haroenv too for your earlier responses.
awesome @techytuppers
Kool @techytuppers .
You don't need to copy over the component.js file, it is exported!
See here: https://community.algolia.com/vue-instantsearch/getting-started/custom-components.html#how-to-create-a-custom-component
I hope that will make it even cleaner!
Most helpful comment
Here is a quick codepen that illustrates it: https://codepen.io/team/algolia/pen/qXRpzR?editors=1000
I'm also adding this to the docs in #257