How to display detail page from search results in ResultCard? - reactjs

Preconditions: React application using appbaseio/reactivesearch
Problem: I am trying to open a simple detail page in the same window (e.g. as a popup window triggered via onclick handler) when I click on a search result. Search results are being displayed by the ResultCard component. Anybody had a similar issue and solved it?
I see there is the url parameter (here: "profile") in the ResultCard component, but it just redirects to the specified url in another tab window.
import {ReactiveBase, DataSearch, ResultCard} from
appbaseio/reactivesearch";
// ...some more code
<div className="container">
// connector to appbase.io
<ReactiveBase
app="myapp"
credentials="xxx"
theme={{
primaryColor: "#ffe067"
}}
>
// search bar
<DataSearch
componentId="SearchSensor"
dataField={["gebot_name", "info"]}
className="search"
/>
// display search results in a list with title and description
<ResultCard
className="right-col"
componentId="SearchResult"
size={10}
onData={data => ({
title: data.gebot_name,
description: data.description,
url: "profile"
})}
react={{
and: ["SearchSensor"]
}}
/>
</ReactiveBase>
</div>

So to what I understand from your question you want to display a Modal when clicking on result item and show all the details.
If this is the case you can use ReactiveList and render the data according to your choice. For eg:
In v2:
<ReactiveList
...
onData={ res => (
<div onClick={() => this.handleModal(res)} >{Content}</div>
)
}
/>
With this.handleModal you can handle the Modal and display the data.
In v3
<ReactiveList
...
renderItem={ res => (
<div onClick={() => this.handleModal(res)} >{Content}</div>
)
}
/>
Check documentation here:
For v3: https://opensource.appbase.io/reactive-manual/result-components/reactivelist.html
For v2: https://opensource.appbase.io/reactive-manual/v2/result-components/reactivelist.html

Related

React toggling between clickable words that pull up <Elements/>

Somewhat new to React.
I want to be able to toggle between React elements CreateUser, EditUser, and ListUser.
It would be great to have a clickable text that when selected pulls up that element and its
corresponding stuff. In the case of Create its a field with a save button.
What is the best way to have my CrudSelector class list all three texts, make them clickable and pull up the stuff inside toggling to the selected one at a time?
Welcome. Always a good idea to share code with your question.
You'll want to use some kind of state which tells your parent component which child component to show. Kind of like this in your React functional component:
const [ featureToShow, setFeatureToShow ] = useState('list')
return (
<>
{/* Show some buttons to change the state */}
<button onClick={() => setFeatureToShow('list')}>Show User List</button>
<button onClick={() => setFeatureToShow('create')}>Create User</button>
<button onClick={() => setFeatureToShow('edit')}>Edit User</button>
{/* Depending on what is in the state show that component */}
{ featureToShow === 'list' ? <ListUser /> : null }
{ featureToShow === 'create' ? <CreateUser /> : null }
{ featureToShow === 'edit' ? <EditUser /> : null }
</>
)
In reality you'll probably want to enable clicking on the user's name in ListUser to show the EditUser component.

How to check if a link has been added to a CKEditor/Textarea using ReactJs? and CKEditor

I am using CKEditor with reactjs, and I need to know when a user adding a link in the text area, and I am talking about video links for example youtube.
I want to check when a user adds a video link so i can grab it and render it in the specific page I want.
for rendering the video I am using react-youtube.
what i tried and what i got as result.
1- I have a field because i am using Formik, as follow
<Field
name="postText"
render={({ field, form }) => {
console.log("post text", field.value);
return editorLoaded ? (
<>
<CKEditor
editor={ClassicEditor}
data={field.value}
onChange={(event, editor) => {
form.setFieldValue(field.name, editor.getData());
}}
/>
</>
) : (
<> </>
);
}}
/>
2- I did a console.log
console.log("post text", field.value);
3- The result of the console.
post text <p>Hello this is a video link </p>
<figure class="media">
<oembed url="https://www.youtube.com/watch?v=EaZxUCWAjb0"></oembed>
</figure>
so now is there a way to find out the link and save the database?
i really appreciate your help:)

React - changing text based on what element is hovered

I have a rectangle div box on my page that contains various elements including a Font Awesome download icon. I want to display a specific text when the user hovers over the entire div, and then I want to change that text when the download button is hovered. I see the text change/show when the div is hovered, but don't see the text change when the download button is hovered. I added a console log in the download hover and that does show up. So I'm guessing the component is not re-rendering to display the updated text.
const [viewDownloadText, setViewDownloadText] = useState('');
...
return (
<div
className={'product d-flex'}
key={product.id}
onClick={() => openPDF(product.name)}
onMouseOver={() => setViewDownloadText('Click to view')}
onMouseOut={() => setViewDownloadText('')}
>
{viewDownloadText && (
<div className={'click-text'}>{viewDownloadText}</div>
)}
<FontAwesomeIcon
className={'SDS-download'}
icon={faFileDownload}
size={'2x'}
onMouseOver={() => {
console.log('download set!');
setViewDownloadText('Click to download');
}}
onMouseOut={() => {
setViewDownloadText('Click to view');
}}
/>
</div>
);

Rendering a component in order/after one has rendered (React)

I have an app that displays data from an API and a button for loading more.
The problem I have is that the button flashes on the screen before the data list is fetched and displayed.
I want the button to display only at the bottom of the page after the list.
What is a way I can do this?
The code :
useEffect(() => {
setLoading(true);
fetchTopRatedMovies(pageNumber).then((newData) =>
setApiData({
...newData,
results: [...apiData.results, ...newData.results]
})
);
setLoading(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pageNumber]);
return (
<div className='top-rated-page-wrapper'>
{isLoading ? (
<Loader />
) : (
<>
<MovieList results={results} />
<PageButton pageLimit={pageLimit} loadMore={loadMore} />
</>
)}
</div>
To clarify.
The button loads first and flashes before the data is rendered.
The button is then in the position where I want it at the bottom of the page.
I don't want to button to be visible until the data has been rendered.
You could use conditional render to render load more button when data > 0
{ apiData ? <PageButton pageLimit={pageLimit} loadMore={loadMore} /> : null }
I believe this article will answer your question. The author uses the same hook and speaks specifically how to manage the lifecycle event with a state variable.
https://daveceddia.com/useeffect-hook-examples/

React - Setting state to target with onClick method

I am trying to recreate a tabs component in React that someone gave me and I am getting stuck while getting the onClick method to identify the target.
These are the snippets of my code that I believe are relevant to the problem.
If I hardcode setState within the method, it sets it appropriately, so the onClick method is running, I am just unsure of how to set the tab I am clicking to be the thing I set the state to.
On my App page:
changeSelected = (event) => {
// event.preventDefault();
this.setState({
selected: event.target.value
})
console.log(event.target.value)
};
<Tabs tabs={this.state.tabs} selectedTab={this.state.selected}
selectTabHandler={() => this.changeSelected}/>
On my Tabs page:
{props.tabs.map(tab => {
return <Tab selectTabHandler={() => props.selectTabHandler()} selectedTab={props.selectedTab} tab={tab} />
})}
On my Tab page:
return (
<div
className={'tab active-tab'}
onClick={props.selectTabHandler(props.tab)}
>
{props.tab}
</div>
When I console.log(props.tab) or console.log(event.target.value) I am receiving "undefined"
There are a few issues causing this to happen. The first issue is that you wouldn't use event.target.value in the Content component because you aren't reacting to DOM click event directly from an onClick handler as you are in Tab, instead you are handling an event from child component. Also keep in mind that event.target.value would only be applicable to input or similar HTML elements that have a value property. An element such as <div> or a <span> would not have a value property.
The next issues are that you aren't passing the tab value from Tabs to Content and then from within Content to it's changeSelected() handler for selectTabHandler events.
In addition the onClick syntax in Tab, onClick={props.selectTabHandler(props.tab)} is not valid, you will not be able to execute the handler coming from props and pass the props.tab value. You could instead try something like onClick={() => props.selectTabHandler(props.tab)}.
Content - need to pass tab value coming from child to changeSelected():
render() {
return (
<div className="content-container">
<Tabs
tabs={this.state.tabs}
selectedTab={this.state.selected}
selectTabHandler={tab => this.changeSelected(tab)}
/>
<Cards cards={this.filterCards()} />
</div>
);
}
Tabs - need to pass tab coming from child to selectTabHandler():
const Tabs = props => {
return (
<div className="tabs">
<div className="topics">
<span className="title">TRENDING TOPICS:</span>
{props.tabs.map(tab => {
return (
<Tab
selectTabHandler={tab => props.selectTabHandler(tab)}
selectedTab={props.selectedTab}
tab={tab}
/>
);
})}
</div>
</div>
);
};
export default Tabs;
Also don't forget the unique key property when rendering an array/list of items:
<Tab
key={tab}
selectTabHandler={tab => props.selectTabHandler(tab)}
selectedTab={props.selectedTab}
tab={tab}
/>
Here is a forked CodeSandbox demonstrating the functionality.

Resources