ComponentSearch with submit button - reactjs

I need help in making the component search fire up only when a submit button is clicked or hit enter key. not as the user types.
I have set up my state and
used onValueChange method to get the value entered
made the button
state={
searchText: ""
}
......
...
onValueChange= {(e) => this.setState({searchText:e.target.value})}
<button type="button >
Search
</button>
I want my button to get that value and make the query run when hit submit or press enter.
thanks for help

You can read the docs on controlled behavior in ReactiveSearch over here. I have also implemented a small example for the above situation you check the demo here.

Just you have to do is ,
set the state (eg. showResult) as true on onClick event of the search button,
And then just add condition to the result list or result card.
Like this:
{showResult ?
(<ReactiveList
componentId="results"
dataField={selected}
size={15}
sortBy={sort}
loader={<ProductLoader />}
react={{
and: andQuery
}}
onAllData={(results, loadMoreData) => this.getProduct(results)}
/>)
: ""}

Related

How to Link A certain Keyboard Key to a function in React JS

I have made an App that is simple you can check it out here but the problem is now that when a user is logged in and creating a post there is a button that adds a post now I want "Enter" key to perform the same task the code to my button is
<Button variant="contained" color="secondary" onClick = {updateList}>Add item</Button>
now I want to bind the same updateList function to Enter key please guide me on how can I do that???
The button is from Material-ui
also currently as I click enter key it reloads the page I also want to stop that from happening
Also, can anyone tell me that is it possible to take multikey stroke input like ctrl + Z ?
If you want to bind function to some key you can do it by event listeners called onKeyDown or onKeyPress:
handleKeyPress = (event) => {
if(event.key === 'Enter'){
console.log('enter press here! ')
}
}
function App(){
return(
<div>
<input type="text" id="one" onKeyPress={this.handleKeyPress} />
</div>
);
}
Because you pager is reloading im guessing your using the HTML form tag. To prevent it the page from reloading your need to prevent the default event behavior after submitting.
<form onSubmit={(event) => {event.preventDefault() /* this stops reloading the page */ }} ></form>
To be able to submit on enter, you should add a button in side the form tag and add type "submit" to it.
<form onSubmit={(event) => {event.preventDefault() /* this stops reloading the page */ }} >
<button type={"submit"}/>
</form>
That should do it.

Update array of items with help of modal input in React

I didn't find any suitable answer for this question. Here is what I am looking for.
I have lists of menus items coming from the state array variable (https://i.imgur.com/FzD0sol.png).
I have an add button which opens a modal. Modal includes an input field. (https://i.imgur.com/6DCZhoj.png)
The final result would be when some click adds button of modal, its field values updated in menus state array. which further updates the menus list on UI.
I able to made all these UI. But I didn't have any idea how can I pass my data from modal input to menus list. Here is codesandebox link of the same problem (https://kx6yr.csb.app/).
There is a way to solve your problem :
You have to give a callback props to your Modal component. As it, The modal will be able to add an item.
There is the codesandBox : https://codesandbox.io/s/friendly-boyd-ptxem
So this is one way to do it, in your modals add this onAdd prop:
<AddModal
heading="Add Food"
modalId="addFood"
inputName="addFood"
onAdd={(textEntered) => { alert(textEntered); }}
ref={this.foodModal}
/>
<AddModal
heading="Add Drink"
modalId="addDrink"
inputName="addDrink"
onAdd={(textEntered) => { alert(textEntered); }}
ref={this.drinkModal}
/>
And within the modal component, call this handler passing the input value:
<button
type="button"
onClick={this.props.onAdd.bind(this, this.state.item)}
className="golden-button-op"
style={{ margin: "0px" }}
>
Add
</button>
Hope it helps!

React widgets combobox; how to clear input or prevent selection

I'm using the combobox from React Widgets as a search UI component.
I've put in a custom render item so that when you click a search result in the dropdown, you navigate to the relevant page.
However when you select a result, the name of the selected item goes into the text input, which isn't what a user will expect when they select a search result. I think they'd expect the search term to remain, or perhaps the input to be cleared.
I like the Combobox component and haven't found another UI widget that would do what I want, so I'd like to find a solution.
Is there some way to override the selection behaviour so that clicking a list item doesn't select it? I've tried setting the 'onSelect' property but this doesn't suppress the default selection behaviour, it just adds extra functionality.
Alternatively is there a way to manually set the selection to null? The docs don't seem to show anything. I tried getting the input node's value manually to '' with reactDOM, but the value didn't change. I would guess that the component controls it.
I've wrapped the Combobox in a functional component:
function Search(props) {
...
const onSelect = (value) => {
const node = ReactDOM.findDOMNode(Search._combobox);
const input = node.getElementsByTagName('input')[0];
input.value = '';
}
return (
<Combobox
ref={(c) => Search._combobox = c}
onSelect={onSelect}
textField="name"
valueField="_id"
/>
);
}
If I set the value prop of the Combobox then it is impossible to type into it.
Any suggestions? Thank you.
The solution I found is to create my own search controls using an input and a button, and hide the native input and button with display: none. "componentDidUpdate" detects when new search results arrive and opens the dropdown to show them.
There is a manually-added 'show more...' entry at the end of search results. Clicking this increases the search limit for that group. That's the main reason I wanted to avoid showing the clicked result in the text input. The custom input is not affected by the user's selection, it always shows the search term.
My search component now looks something like this:
<div className="search">
<div className="search-controls">
<Input
onChange={this.onChangeInput}
type="text"
/>
<Button
onClick={this.toggleOpen}
title="toggle results"
>
<FontAwesomeIcon icon={['fas', 'search']} style={{ 'color': iconColors.default }} size="1x" />
</Button>
</div>
<Combobox
busy={isSearching}
data={searchResults}
onChange={() => {}}
open={open}
onSelect={this.onSelect}
textField="name"
valueField="_id"
/>
</div>

Dynamic Popover in ReactJS

I'm fairly new to React and I'm using the Ant Design framework (https://ant.design/).
I have a table list of items that I'm looking to have a button on each so that when it is pressed additional information about that row becomes available (which is a secondary API call specific to that row).
I'm trying to use a popover but I'm noticing that the popover wants the text before being rendered which is a problem since I don't have that information until the second API call. The best idea I've come up so far is to have the button press trigger the api call and then the state is updated but that creates a funky experience (as it is update after the popover is already opened - after starting with the previous rows information). It isn't a huge amount of time but it still isn't an ideal experience.
This is what I have so far:
<Popover content={this.contentSec([record['section']])} title=
{record['section']} trigger="click">
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
</Popover>
this.sectionAttributes triggers my fetch request. and this.contentSec does the formatting on the existing popup (see below).
contentSec(props) {
const listItems = this.state.attributes.map((item) =>
<li>{item}</li>
);
return <div><ul>{listItems}</ul></div>
}
Any ideas of a better way to handle this so that there isn't that buggy delay when clicking the button for the popover?
Thanks.
As the content is populated after the second api call, You can send two props content which can be empty string or any default value and loading variable as true on click. Once you have the data after the API call you can send the updated props ie content with actual text and loading as false and finally handle your logic and state update in componentwillrecieveprops() in the popover component.
You can use the loading prop to switch from a loader initially to the actual content.
Write a condition to check if the response from this.sectionAttributes(record['section'] is true, if it is true then
<Popover content={this.contentSec([record['section']])} title=
{record['section']} trigger="click">
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
</Popover>
else simply use
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
For the first time user clicks on button, the component rerenders and state gets updated, so when it rerenders you can see popover as the if condition satisfy.

How to display a new component on click of next button in React

I have a form Component, i am doing validation of that form on click of the Next button, once the validation will be successful i want to render a different component.
inside the state i am keeping the "showComponent" as false and on the click of that button i am making it true.
_onButtonClick (event){
event.preventDefault();
this.setState({
...this.state,
showComponent: !this.state.showComponent
})
console.log("button clicked",this.state);
}
Button Logic :
<div>
<button onClick={(event) => this._onButtonClick(event)}>Button</button>
{this.state.showComponent ?<AddModules /> : null}
</div>
I am able to render that new page but its rendering on the same page, which i don't want.
I think the<Route /> component that react-router-dom gives you is exactly what you need.
Take a look at the example in the react-router docs. Notice how they set up their <Route />. They also have an example in the docs on how to prevent someone from going into another page.
I also made a quick demo in CodeSandbox that more closely resembles what you are looking for.

Resources