Vue-InstantSearch with Algolia & Laravel: Hide result on empty query - laravel

I'd like to figure out how to hide the index/result on an empty search query.
In my blade I have the code (slightly modified from the official documentation):
<ais-instant-search index-name="myIndex" :search-client="searchClient">
<ais-search-box placeholder="Search here"></ais-search-box>
<ais-state-results>
<template slot-scope="{ state: { query } }">
<ais-hits v-if="query.length > 0">
<div slot="item" slot-scope="{ item }">
<h2>#{{ item.Title}}</h2>
<p>#{{ item.Text}}</p>
</div>
</ais-hits>
</template>
</ais-state-results>
</ais-instant-search>
If I enter a search query this works fine, but on empty query this displays the following unwanted notification on my page (instead of the before unwanted index):
Use this component to have a different layout based on a certain state.
Fill in the slot, and get access to the following things on the slot-scope:
results: [
"_rawResults",
"hits",
"nbHits",
[..]
How can I hide this notification?

Ah, I just found a solution I think.
This notification text is displayed if there's no DOM element inside <ais-hits>. And in case of no query there isn't, since "v-if" removes that. So If instead of "v-if" I use "v-show" it works as I need it, since the DOM element still exists, but isn't displayed (display:hidden).
<ais-instant-search index-name="myIndex" :search-client="searchClient">
<ais-search-box placeholder="Search here"></ais-search-box>
<ais-state-results>
<template slot-scope="{ state: { query } }">
<ais-hits v-show="query.length > 0">
<div slot="item" slot-scope="{ item }">
<h2>#{{ item.Title}}</h2>
<p>#{{ item.Text}}</p>
</div>
</ais-hits>
</template>
</ais-state-results>

Related

Cypress: How to click on a array-list element if matching text found

I want to add an item in cart with a matching text like 'cashews'. I tried below code but .click() function is giving error as "bind and event handler to the click javascript event"
cy.get('.products').find('.product').each(($e1, index, $list) => {
const textveg = $e1.find('h4.product-name').text() {
if (textveg.includes('Cashews')) {
$e1.find('.button').click();
}
}
})
can someone suggest what can be the possible reason that .click() method is not identified by cypress. I am using cypress version 7
How you do this depends on the structure of the HTML.
It looks like you may have this sort of hierarchy
<div class="products">
<div class="product">
<h4 class="product-name">Almonds</h4>
<button>Add to cart</button>
</div>
<div class="product">
<h4 class="product-name">Cashews</h4>
<button>Add to cart</button>
</div>
</div>
Take the product section containing the text you want, and within that find the products <button>.
Your test might be
cy.contains('.product', 'Cashews') // pick the <div class="product"> with required text
.find('button') // inside the product, find it's button
.click()
You can use .filter() to find your element and click it:
cy.get('h4.product-name').filter(':contains("Cashews")').click()

Cypress selecting item in list with .eq(0) also checks conditions in other items

How do I select one item of a list and apply the conditions to only that item?
I have this html:
<ion-list v-if="mangelzuordnungs.length > 0">
<ion-item>
<h2>Item A</h2>
<button
data-cy="photo-add-button"
shape="round"
>
<span data-cy="photo-add-button-text"> Hinzufügen </span>
</button>
</ion-item>
<ion-item>
<h2>Item B</h2>
</ion-item>
</ion-list>
And this test:
it('Ensures when Mangelzustand does contains photos, the "Hinzufügen" Button Text does not exist', () => {
cy.get("ion-item")
.eq(1)
.get("[data-cy=photo-add-button")
.get("[data-cy=photo-add-button-text")
.should("not.contain", "Hinzufügen");
});
I would expect that the test succeeds because it fails arguing that photo-add-button-text exists and highlights the element of the first list item.
What am I missing?
If you use .get() after .eq(1) you are searching from cy.root(), which is the the whole DOM.
Try .find() instead.
cy.get("ion-item")
.eq(1)
.find("[data-cy=photo-add-button")
.find("[data-cy=photo-add-button-text")
.should("not.contain", "Hinzufügen");
Your second item in the list doesn't contain [data-cy="photo-add-button-text] and [data-cy=photo-add-button-text], hence when you are trying to use get(), the test is failing. Instead you can directly assert:
cy.get("ion-item").eq(1).should("not.contain", "Hinzufügen")

Identify last item in alpine.js for loop

I have a for loop in my alpine.js code
<template x-for="(value, index, collection) in forecastQ4Values" :key="index">
<div class="..."><span x-text="value"></span></div>
</template>
How can I add a class only to the last item in the for loop?
Basically I want to hide the last element until some variable changes.
For instance like this, but only on the last item.
<template x-for="(value, index, collection) in forecastQ4Values" :key="index">
<div :class="{ 'invisible': !productDActive }" class="..."><span x-text="value"></span></div>
</template>
Thanks
If you have access to index my first thought would be to check where you are in the loop. Like so:
<template x-for="(value, index, collection) in forecastQ4Values" :key="index">
<div :class="{ 'invisible': (forecastQ4Values.size == index+1) }" class="..."><span x-text="value"></span></div>
</template>

How can I get the cell selected in a Vuetify Datatable?

I know that I can get the row selected using the event "click:row" in my Datatable component, but I need to get the specific cell that I had clicked
You can use slots for that. Add it inside of your table component like given below:
<template v-slot:item.name="{ item }">
<div #click="rowClicked(item)">
<v-icon
class="mr-2"
color="#54a1e0"
large
>{{ "mdi-folder" }}
</v-icon>
{{ item.name }}
</div>
</template>
Here, you call a "rowClicked" method and you pass the clicked item when there is a click on "name" field that you also customise within the template.

Polymer paper-dropdown menu does not overlay iron-list

My issue is similar to the one here: paper-menu-button's dropdown (paper-menu) not overlaying other iron-list items, but no adequate solution is proposed there.
The problem is that I have a <paper-dropdown-menu>, which opens up correctly inside the <iron-list> item it is in, but goes underneath the following <iron-list> items:
I have a simple <paper-dropdown-menu> like this:
<paper-dropdown-menu-light class="custom" label="Languages" no-label-float>
<paper-listbox class="dropdown-content" selected="1">
<paper-item>Spanish</paper-item>
<paper-item>English</paper-item>
<paper-item>French</paper-item>
<paper-item>Sinhala</paper-item>
</paper-listbox>
</paper-dropdown-menu-light>
which is inserted into another element with an <iron-list> (which loads a JSON file with <iron-ajax>):
<iron-list id="list" items="[[bookList.books]]" as="item">
<template>
<div>
<div class$="[[getClassForItem(item, selected)]]" tabindex$="[[tabIndex]]" style="z-index: 1;">
<div class="avatar">[[item.id]]</div>
<div class="pad">
<div class="primary">[[item.titleen]]</div>
<div class="shortText">[[item.slug]]</div>
<div class="longText">[[item.blurb]]</div>
<div class="languagedrop">
<language-drop></language-drop>
</div>
</div>
</div>
</div>
</template>
</iron-list>
I tried setting the z-index for each <iron-list> item to 1, but that did not work. I tried working with <iron-overlay>, but I did not manage to get that done. I'm very new to Polymer, so if anybody has a solution or workaround that would be great.
That's because iron-list is using transform: translate3d for each list item.
The workaround that I have found is working is to add z-indexto the current list item (<div class="item"></div>) on which you have the dropdown expanded, or to all items from top to bottom in descending order, programatically.

Resources