I'm working on a component that should be able to:
Search by input - Using the input field a function will be called after the onBlur event got triggered. After the onBlur event the startSearch() method will run.
Filter by a selected genre - From an other component the user can select a genre from a list with genres. After the onClick event the startFilter() method will run.
GOOD NEWS: I got the 2 functions above working.
BAD NEWS: The above 2 functions don't work correct. Please see the code underneath. The 2 calls underneath work, but only if I comment one of the 2 out. I tried to tweak the startSearch() method in various ways, but I just keep walking to a big fat wall.
//////Searching works
//////this.filter(this.state.searchInput);
//Filtering works
this.startFilter(this.state.searchInput);
QUESTION How can I get the filter/search method working?. Unfortunately simply putting them in an if/else is not the solution (see comments in the code).
import { Component } from 'preact';
import listData from '../../assets/data.json';
import { Link } from 'preact-router/match';
import style from './style';
export default class List extends Component {
state = {
selectedStreamUrl: '',
searchInput: '',
showDeleteButton: false,
searchByGenre: false,
list: []
};
startFilter(input, filterByGenre) {
this.setState({
searchByGenre: true,
searchInput: input,
showDeleteButton: true
});
alert('startFilter ');
console.log(this.state.searchByGenre);
/////////---------------------------------
document.getElementById('searchField').disabled = false;
document.getElementById('searchField').value = input;
document.getElementById('searchField').focus();
// document.getElementById('searchField').blur()
document.getElementById('searchField').disabled = true;
console.log(input);
this.filter(input);
}
//search
startSearch(input) {
alert('startSearch ');
console.log(this.state.searchByGenre);
//komt uit render()
if (!this.state.searchByGenre) {
//check for input
this.setState({
searchInput: input.target.value,
showDeleteButton: true
});
//Searching works
//this.filter(this.state.searchInput);
//Filtering works
this.startFilter(this.state.searchInput);
// DOESNT WORK:
// if (this.state.searchInput != "") {
// this.filter(this.state.searchInput);
// } else {
// this.startFilter(this.state.searchInput);
// }
}
}
setAllLists(allLists) {
console.log('setAllLists');
console.log(this.state.searchByGenre);
this.setState({ list: allLists });
//document.body.style.backgroundColor = "red";
}
filter(input) {
let corresondingGenre = [];
let filteredLists = listData.filter(item1 => {
var test;
if (this.state.searchByGenre) {
alert('--this.state.searchByGenre');
//filterByGenre
//& item1.properties.genre == input
for (var i = 0; i < item1.properties.genre.length; i++) {
if (item1.properties.genre[i].includes(input)) {
corresondingGenre.push(item1);
test = item1.properties.genre[i].indexOf(input) !== -1;
return test;
}
this.setState({ list: corresondingGenre });
}
} else {
//searchByTitle
alert('--default');
test = item1.title.indexOf(input.charAt(0).toUpperCase()) !== -1;
}
return test;
});
console.log('filterdLists:');
console.log(filteredLists);
console.log('corresondingGenre:');
console.log(corresondingGenre);
//alert(JSON.stringify(filteredLists))
this.setState({ list: filteredLists });
}
removeInput() {
console.log('removeInput ');
console.log(this.state.searchByGenre);
this.setState({
searchInput: '',
showDeleteButton: false,
searchByGenre: false
});
document.getElementById('searchField').disabled = false;
this.filter(this.state.searchInput);
}
render() {
//alle 's komen in deze array, zodat ze gefilterd kunnen worden OBV title.
if (
this.state.list === undefined ||
(this.state.list.length == 0 && this.state.searchInput == '')
) {
//init list
console.log('render ');
console.log(this.state.searchByGenre);
this.filter(this.state.searchInput);
}
return (
<div class={style.list_container}>
<input
class={style.searchBar}
type="text"
id="searchField"
placeholder={this.state.searchInput}
onBlur={this.startSearch.bind(this)}
/>
{this.state.searchByGenre ? <h1>ja</h1> : <h1>nee</h1>}
{this.state.showDeleteButton ? (
<button class={style.deleteButton} onClick={() => this.removeInput()}>
Remove
</button>
) : null}
{this.state.list.map((item, index) => {
return (
<div>
<p>{item.title}</p>
</div>
);
})}
</div>
);
}
}
The question you are asking is not clear. But try to be explicit with your component to help debug the issue. For example, use a constructor and declare your component state in there. Also do your .bind for the event in there to be concise.
The following example captures the state variable to be true when the onBlur event is fired, which is the same as its initial state value:
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
searchByGenre: true
};
this.startSearch = this.startSearch.bind(this);
}
startSearch() {
// This value is true
console.log(this.state.searchByGenre)
}
render() {
return (
<input
type="text"
id="searchField"
placeholder="Search"
value={this.state.searchInput}
onBlur={this.startSearch}
/>
)
}