How do you prevent search results from showing when the search term is empty in Algolia? - algolia

I followed their tutorial, but it always shows pages of search results, even when the page is first loaded and the contents of the search box is empty. I tried adding queryHook and only search when the term is not blank, but it still shows search results when you load the page. In fact, the queryHook is not even called upon first load. It's only called when you type in the search box. How do you hide the search results unless the user starts typing?
https://community.algolia.com/instantsearch.js/v2/widgets/searchBox.html#usage
This works, but I don't think it's the right way because it still does a search on an empty text box. Also when you reset the search terms by clicking the X on the right, then it doesn't hide the results (because it doesn't call queryHook).
<main id="results" class="collapse">
<div id="hits"></div>
<div id="pagination"></div>
</main>
# CoffeeScript
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-input',
queryHook: (term, searchFunction) ->
console.log "term = #{term}"
if term
$('#results').show()
else
$('#results').hide()
searchFunction(term)

You can use the Helper.js library which is already part of InstantSearch. In your case, check for the query length when you instantiate your search:
var search = instantsearch({
// other search parameters
searchFunction: function(helper) {
if (helper.state.query.length === 0) {
return; // do not trigger search
}
helper.search(); // trigger search
}
});

Related

Keep two react-bootstrap-typeahead inputs in sync

So I have an application with a dashboard and a main page that has a header. Both of them have a react-bootstrap-typeahead input to perform the same action - a search to open something on a map.
What I would like to achieve is:
when the user search something on the dashboard, the main page opens with the search result and on the header, the search input there shows what was searched on the other component.
on the other hand, when the user search something on the search input on the main page header, and then goes back to the dashboard, the dashboard search input should be prefilled with the value previously searched on the main page.
What I have tried so far:
So when the user picks a search item result, that string is saved on the application state using redux. I also clear it manually when the user clicks on the clear search button. The RBT component is defined to use this variable, as in:
<AsyncTypeahead defaultInputValue={props.currentSearchValue} ... />
This seams to work on the first time, i.e. when the user has not interacted with the other input yet. For example, with the application on a fresh state (just loaded) if on the dashboard I pick a search item, when going to the main page because that search input has not been touched yet. Then, when I pick a search item on the main page and go back to the dashboard, I wouldn't see it because setting defaultInputValue is not enough, as that input is not in its default state anymore.
Any tips? I have been running in circles so far. Tried the key/setKey workaround as described in another answer, but that wasn't enough to cover the case described on the previous paragraph. I also tried comparing the input value to the recorded value, but naturally when starting to typing with the input field the values would be different and therefore I cannot trigger a component reload based on that.
Thanks in advance.
Unless I'm missing something about your use case, the selected prop should do what you need. You can save the selected item(s) in your redux store and populate the typeahead with the value on the given page.
// Get the initial value from the store. This should be an array.
const typeaheadSelections = useSelector(...);
<Typeahead
...
onChange={(selected) => {
// Update the value in the store when the selection changes.
dispatch({
type: 'set-typeahead',
value: selected,
});
}}
selected={typeaheadSelections}
/>

Keep selected options in Vuetify multiple autocomplete with options from the database

I'm trying to use Vuetify's Autocomplete component to select a list of users from the database, searching by name. I want to allow selecting multiple users, with each user appearing as another chip in the autocomplete's input field.
It works fine for the first user selected, but then if I start to type the name of another user, when the search results are updated in the autocomplete component, if the first selected user was not included in the new search results, that user disappears from selected chips.
Here's an example of what happens:
Is there a way to maintain the selected options even if they are no longer included in the search results from the database?
So I found what I feel is an acceptable solution, though I'd love to know if there's a better one.
Basically instead of just overwriting the user search results with what I get from the database via api, I first append the selected results to the new search results. Something like this:
axios.get('/api/users/' + this.search)
.then(res => {
this.user.parents.forEach((id) => res.data.push(this.getSearchResultById(id)));
this.parentOptions = res.data;
});
getSearchResultById(id) {
return this.parentOptions.find((parent) => parent.id === id);
},
Use the props cache-items in your case. It keep the selected items in autocomplete viewable

ionic 5 - How to use ionic search bar to search on server only when user presses enter / confirms the search

I am using ionic 5 to build an app and I would like to have a search bar to search and show results from a server.
When looking on the documentation (https://ionicframework.com/docs/api/searchbar), it seems that this element is designed with local filtering in mind.
The event ionInput behaves very similarly to the ionChange, and fires when the input is changed.
I would like to search on the server and present the results only when the user confirms the search (i.e. by pressing enter).
I could not find how to do that.
Best Regards,
Guilherme.
I found out a solution for this, wrapping the search bar element in a form element and reacting to the onSubmit event of the form:
export default class MyComponent extends React.Component<{}> {
handleSubmit(e: FormEvent) {
e.preventDefault();
console.log("submitted")
}
render() {
return (
<form onSubmit={e => this.handleSubmit(e)}>
<IonSearchbar/>
</form>
);
}
}

"Clicking" on a not visible element

So my current situation is that I am trying to click on a marker based in a Google Maps window on a webpage. I have successfully located the markers in two manners: element.all(by.css('.angular-google-map-marker')) and element.all(by.repeater('m in map.markers')).
I have proven that I am obtaining the correct elements by changing the location on the Google Map and using count() to retrieve the number of markers present which returns the correct number in every case.
However, when I try to do for example element.all(by.css('.angular-google-map-marker')).first().click(), I receive the following error:
Failed: element not visible
HTML section
<div ng-transclude="" style="display: none">
<span class="angular-google-map-marker" ng-transclude="" ng-repeat="m in map.markers" options="m.options" coords="m.coords" idkey="m.id" click="onMarkerClick"></span>
<span class="angular-google-maps-window" ng-transclude="" coords="activeMarker.coords" options="windowMapOptions" show="windowMapOptions.show" closeclick="closeInfoWindow" templateurl="'gMapInfoWindow.html'" templateparameter="activeMarker"></span>
</div>
Normally elements that trigger some event due to clicking have an attribute like ng-click= foo(), however the markers above only use click= foo(). In addition if you look the line with the div tag, it says display: none, which might explain the visibility error.
My Question: Is there a way to activate the effect of an attribute like click= foo() without clicking on the element directly?
Aside from trying to make an element visible and then clicking, you can attempt clicking "via JavaScript" (there are some differences though - WebDriver click() vs JavaScript click()):
var marker = $('.angular-google-map-marker');
browser.executeScript("arguments[0].click();", marker.getWebElement());
First of all be sure that you can interact with the element when it is visible, you can do this from within the DevTools of your browser, make it visible by adding a display:block. Then check that if you change the value of the selectbox, the value can also be used with Angular Binding.
If so, you can easily make the element visible with Protractor by injecting a piece of Javascript in the page with the following command:
browser.executeScript('document.querySelector("div").style.display = "block"');
This results in a promise, so be aware of that!

Value of textbox when using Google Closure AutoCompleteBasic is incomplete

I use Google Closure's AutoCompleteBasic for some text boxes I have on the form. When the user fills in the text box after typing a key or two and then using arrow keys to pick one of the suggestions of the autocomplete, the value of the textbox just seems to be whatever keys the user typed in though the form renders the full text of the autocomplete word in the textbox. I use document.getElementById(id_of_textbox).value to get the value
Is this expected behavior of autocomplete and textbox interaction?
How can I get the full complete string instead of just the first few keystrokes? Or is there some other way to read the value?
I haven't looked into using AutoCompleteBasic, but here's some code that might help:
example.setupSearchListener = function(){
var searchbox = goog.dom.getElement('your-textbox');
var delay = new goog.async.Delay(function(){example.handleSearch();}, 500);
goog.events.listen(searchbox, goog.events.EventType.KEYUP, function(){
delay.start();
});
};
This will wait until the user stops typing, and then call example.handleSearch() to do whatever.