Hello guys I was hoping to find help here since I'm very new to coding in reactjs and electron.
Im trying to put a searchbar between the tabs and content like on chrome I use Antd
The code of the Tabs, I don't know where I need to add my searchbar to get it under the tabs and over the content as shown in the picture:
Help much appreciated :)
import { Tabs, Input, Space } from 'antd';
import React from 'react';
import 'antd/dist/antd.css';
import '../../index.css';
import App from '../../App';
import { AudioOutlined } from '#ant-design/icons';
const { Search } = Input;
const suffix = (
<AudioOutlined
style={{
fontSize: 16,
color: '#1890ff',
}}
/>
);
const onSearch = value => console.log(value);
const { TabPane } = Tabs;
const initialPanes = [
{ title: 'Tab 1', content: 'Content of Tab 1', key: '1' },
// { title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
// {
// title: 'Tab 3',
// content: 'Content of Tab 3',
// key: '3',
// closable: false,
// },
];
class Demo extends React.Component {
newTabIndex = 0;
state = {
activeKey: initialPanes[0].key,
panes: initialPanes,
};
onChange = activeKey => {
this.setState({ activeKey });
};
onEdit = (targetKey, action) => {
this[action](targetKey);
};
add = () => {
const { panes } = this.state;
const activeKey = `newTab${this.newTabIndex++}`;
const newPanes = [...panes];
newPanes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey });
this.setState({
panes: newPanes,
activeKey,
});
};
remove = targetKey => {
const { panes, activeKey } = this.state;
let newActiveKey = activeKey;
let lastIndex;
panes.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const newPanes = panes.filter(pane => pane.key !== targetKey);
if (newPanes.length && newActiveKey === targetKey) {
if (lastIndex >= 0) {
newActiveKey = newPanes[lastIndex].key;
} else {
newActiveKey = newPanes[0].key;
}
}
this.setState({
panes: newPanes,
activeKey: newActiveKey,
});
};
render() {
const { panes, activeKey } = this.state;
return (
<Tabs
type="editable-card"
onChange={this.onChange}
activeKey={activeKey}
onEdit={this.onEdit}
>
{panes.map(pane => (
<TabPane tab={pane.title} key={pane.key} closable={pane.closable}>
{pane.content}
</TabPane>
))}
</Tabs>
);
}
}
export { Demo };
Related
I'm trying to make a slideshow dynamic block, actually, it alredy works, but, throws this error and I don't know why.
Uncaught SyntaxError: expected expression, got '<' slideshow-category-picker.js:33:14
This error appears twice at customizer and once at the public site, at the public site it doesn't cause performance issues, but, at the customizer it doesn't let me start any other script.
I hope somebody can help me.
/*slideshow-category-picker.js*/
const {
withSelect
} = wp.data;
const {
SelectControl
} = wp.components;
/* Guardar categorias en un arreglo */
const CategorySelect = (props) => {
const {
terms,
selectTerm
} = props;
const catSelections = [];
catSelections.push({
value: '',
label: 'Todas las categorÃas'
} );
terms &&(
terms.forEach(item => {
catSelections.push({
label: item.name,
value: item.id
} );
}));
return(
<SelectControl
className = "slideshow-categoryselect"
label = "CategorÃas"
options = {
catSelections
}
onChange = {
(itemId) => selectTerm(itemId)
}
/>
);
}
export default withSelect((select, props) => {
return {
terms: select('core').getEntityRecords('taxonomy', 'category', {
per_page: -1
})
}
})(CategorySelect);
/*index.js*/
const {
__
} = wp.i18n;
const {
registerBlockType
} = wp.blocks;
const {
Placeholder,
PanelBody,
RangeControl
} = wp.components;
const {
withSelect
} = wp.data;
const {
InspectorControls
} = wp.blockEditor;
import CategorySelect from './slideshow-category-picker';
const BlockEdit = (props) => {
const {
attributes,
setAttributes
} = props;
const selectTerm = (termId) => {
setAttributes({
termId: termId
});
}
return ( <div className = {props.className }>
<InspectorControls>
<PanelBody
title = { __('Slider Settings', 'slideshow') }
initialOpen = {true}
>
<RangeControl
label = { __('Cantidad de Diapositivas', 'slideshow') }
value = { attributes.numSlides }
onChange = {
(val) => setAttributes({
numSlides: val
})
}
min = { 1 }
max = { 10}
/>
<CategorySelect
selectedTermId = {
attributes.termId
}
selectTerm = {
selectTerm
}
/>
</PanelBody>
</InspectorControls>
<Placeholder label = { __('SlidesShow Posts', 'slideshow')}>
</Placeholder>
</div>
);
}
//Logo para el bloque
import {
ReactComponent as Logo
} from '../slideshow-icon.svg';
registerBlockType('slideshow/slides', {
title: __('Slideshow Posts', 'slideshow'),
icon: {
src: Logo
},
category: 'slideshow',
attributes: {
termId: {
type: 'number',
default: 0
},
numSlides: {
type: 'number',
default: 3
},
},
edit: BlockEdit,
save: () => {
return null;
}
});
I want to automatically open Tab 1. Making Tab 1 as default Tab that opens as soon as we run the code. I have used Ant Design library for creating this tab section. There is something called defaultActiveTab in Ant-tabs that would work as initial active tab on running.
Even though I have mentioned Tab 1 as defaultActiveTab, it isn't working.
I want Tab 1 to be default and all the other tabs should pop only after clicking the Add button. I have attached the link below
const { Tabs, Button } = antd
const { TabPane } = Tabs
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
focusingPaneKey: '',
openingPaneKeys: [],
}
}
openPane = (paneKey) => {
this.setState(({ ...state }) => {
if (!state.openingPaneKeys.includes(paneKey)) {
state.openingPaneKeys = [...state.openingPaneKeys, paneKey]
}
state.focusingPaneKey = paneKey
return state
})
}
closePane = (paneKey) => {
this.setState(({ ...state }) => {
if (paneKey === state.focusingPaneKey) {
const paneKeyIndex = state.openingPaneKeys.indexOf(paneKey)
state.focusingPaneKey = state.openingPaneKeys[paneKeyIndex - 1]
}
state.openingPaneKeys = state.openingPaneKeys.filter((openingPaneKey) => openingPaneKey !== paneKey)
return state
})
}
handleTabsEdit = (key, action) => {
if (action === 'remove') {
this.closePane(key)
}
}
render() {
const { panes } = this.props
const keysOfPane = Object.keys(panes)
return (
<div className="tab-section">
<div style={{ marginBottom: 16 }}>
{keysOfPane.map((key) => (
<Button key={key} onClick={() => this.openPane(key)}>
ADD Tab-{key}
</Button>
))}
</div>
<Tabs
hideAdd
onChange={this.openPane}
activeKey={this.state.focusingPaneKey}
type="editable-card"
onEdit={this.handleTabsEdit}
defaultActiveKey="1"
>
{this.state.openingPaneKeys
.map((key) => panes[key])
.map((pane) => (
<TabPane tab={pane.title} key={pane.key}>
{pane.content}
</TabPane>
))}
</Tabs>
</div>
)
}
}
const panes = {
1: { key: '1', title: 'Tab 1', content: 'Content of Tab Pane 1' },
2: { key: '2', title: 'Tab 2', content: 'Content of Tab Pane 2' },
3: { key: '3', title: 'Tab 3', content: 'Content of Tab Pane 3' },
}
https://jsfiddle.net/6719phr3/1/
I have a component that uses React.useState to keep a property named available
and what I want to do is to change its value to true with a conditional statement, so that my component gets rendered based on that condition, but I can't set up a conditional statement inside React.useState. I tried changing it in my other component with a conditional statement:
const [isUserLogged] = React.useState(true);
const arrowDir = props['data-expanded']
? 'k-i-arrow-chevron-down'
: 'k-i-arrow-chevron-right';
if (isUserLogged === true) {
props.available === true;
}
But that didn't work too. How can I achieve this with a conditional statement? Here is my entire code:
import * as React from 'react';
import { withRouter } from 'react-router-dom';
import {
Drawer,
DrawerContent,
DrawerItem,
} from '#progress/kendo-react-layout';
import { Button } from '#progress/kendo-react-buttons';
const CustomItem = (props) => {
const { visible, ...others } = props;
const [isUserLogged] = React.useState(true);
const arrowDir = props['data-expanded']
? 'k-i-arrow-chevron-down'
: 'k-i-arrow-chevron-right';
if (isUserLogged === true) {
props.available === true;
}
return (
<React.Fragment>
{props.available === false ? null : (
<DrawerItem {...others}>
<span className={'k-icon ' + props.icon} />
<span className={'k-item-text'}>{props.text}</span>
{props['data-expanded'] !== undefined && (
<span
className={'k-icon ' + arrowDir}
style={{
position: 'absolute',
right: 10,
}}
/>
)}
</DrawerItem>
)}
</React.Fragment>
);
};
const DrawerContainer = (props) => {
const [drawerExpanded, setDrawerExpanded] = React.useState(true);
const [isUserLogged] = React.useState(true);
const [items, setItems] = React.useState([
{
text: 'Education',
icon: 'k-i-pencil',
id: 1,
selected: true,
route: '/',
},
{
separator: true,
},
{
text: 'Food',
icon: 'k-i-heart',
id: 2,
['data-expanded']: true,
route: '/food',
},
{
text: 'Japanese Food',
icon: 'k-i-minus',
id: 4,
parentId: 2,
route: '/food/japanese',
},
{
text: 'Secret Food',
icon: 'k-i-minus',
id: 5,
parentId: 2,
route: '/food/italian',
available: false,
},
{
separator: true,
},
{
text: 'Travel',
icon: 'k-i-globe-outline',
['data-expanded']: true,
id: 3,
route: '/travel',
},
{
text: 'Europe',
icon: 'k-i-minus',
id: 6,
parentId: 3,
route: '/travel/europe',
},
{
text: 'North America',
icon: 'k-i-minus',
id: 7,
parentId: 3,
route: '/travel/america',
},
]);
const handleClick = () => {
setDrawerExpanded(!drawerExpanded);
};
const onSelect = (ev) => {
const currentItem = ev.itemTarget.props;
const isParent = currentItem['data-expanded'] !== undefined;
const nextExpanded = !currentItem['data-expanded'];
const newData = items.map((item) => {
const {
selected,
['data-expanded']: currentExpanded,
id,
...others
} = item;
const isCurrentItem = currentItem.id === id;
return {
selected: isCurrentItem,
['data-expanded']:
isCurrentItem && isParent ? nextExpanded : currentExpanded,
id,
...others,
};
});
props.history.push(ev.itemTarget.props.route);
setItems(newData);
};
const data = items.map((item) => {
const { parentId, ...others } = item;
if (parentId !== undefined) {
const parent = items.find((parent) => parent.id === parentId);
return { ...others, visible: parent['data-expanded'] };
}
return item;
});
return (
<div>
<div className="custom-toolbar">
<Button icon="menu" look="flat" onClick={handleClick} />
<span className="title">Categories</span>
</div>
<Drawer
expanded={drawerExpanded}
mode="push"
width={180}
items={data}
item={CustomItem}
onSelect={onSelect}
>
<DrawerContent>{props.children}</DrawerContent>
</Drawer>
</div>
);
};
export default withRouter(DrawerContainer);
if props.available is present when your component is rendering you can write a conditional expression while declaring the isLoggedIn inside useState.
In case it is available later we can always use useEffect hook to update the isLoggedIn
const Component = (props) => {
// if props.available is already present to you
const [isLoggedIn, setIsLoggedIn] = React.useState(props.isAvailable ? true : false);
// if props.isAvailable is not present when your component renders you can use
// useEffect
React.useEffect(() => {
setIsLoggedIn(props.isAvailable);
}, [props.isAvailable])
// use IsLoggedIN here
return (
<div>
{
isLoggedIn ?
<div> Logged in </div>
: <div>llogged out</div>
}
</div>
)
}
I have 2 problems, firstly On clicking add button, 2 same tabs are being opened. Secondly on closing the tab all the tabs are being closed and shows this error that I have attached in the image. I have problem with closing the tab. I want to close a particular tab that I close instead of closing all tabs. please look into this problem.
import React from 'react';
import { Tabs, Button } from 'antd';
import 'antd/dist/antd.css';
const { TabPane } = Tabs;
class App extends React.Component {
constructor(props) {
super(props);
this.newTabIndex = 0;
const panes = [
];
this.state = {
activeKey: 0,
panes,
};
this.onChange = this.onChange.bind(this);
this.onEdit = this.onEdit.bind(this);
this.add = this.add.bind(this);
this.remove = this.remove.bind(this);
}
onChange(activeKey) {
this.setState({ activeKey });
console.log(activeKey);
};
onEdit(targetKey, action){
this[action](targetKey);
};
add = targetKey => {
console.log('targetKey', targetKey)
let { activeKey } = this.state;
//if (targetKey !== activeKey){
this.setState(prevState => {
const newState = {...prevState};
newState.panes.push({title:'Tab '+ targetKey, content:'Content of tab pane '+ targetKey,key: activeKey+1});
return newState;
});
//}
};
remove = targetKey => {
let { activeKey } = this.state;
let lastIndex;
this.setState(prevState => {
const newState = {...prevState};
newState.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const panes = newState.filter(pane => pane.key !== targetKey);
if (panes.length && activeKey === targetKey) {
if (lastIndex >= 0) {
activeKey = panes[lastIndex].key;
} else {
activeKey = panes[0].key;
}
}
return ({panes, activeKey});
});
};
render() {
return (
<div className="tab-section">
<div style={{ marginBottom: 16 }}>
{
['1', '2', '3'].map(item =>
<Button key={item} onClick={() => this.add(item)}>ADD Tab-{item}</Button>
)
}
</div>
<Tabs
hideAdd
onChange={this.onChange}
activeKey={this.state.activeKey}
type="editable-card"
onEdit={this.onEdit}
>
{this.state.panes.map(pane => (
<TabPane tab={pane.title} key={pane.key}>
{pane.content}
</TabPane>
))}
</Tabs>
</div>
);
}
}
export default App;
Snaps of the outputs:
https://i.stack.imgur.com/m55Bx.png
Initially panes were defined this way, which shows the tabs even before button click. But my actual requirement is tabs should pop-up on button click. So I have removed the panes made it empty.
{ title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
{ title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
{ title: 'Tab 3', content: 'Content of Tab Pane 3', key: '3' },
Note- "antd": "^4.16.13" "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", are the packages used.
I refactored the code (https://jsfiddle.net/6719phr3/1/):
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
focusingPaneKey: '',
openingPaneKeys: [],
}
}
openPane = (paneKey) => {
this.setState(({ ...state }) => {
if (!state.openingPaneKeys.includes(paneKey)) {
state.openingPaneKeys = [...state.openingPaneKeys, paneKey]
}
state.focusingPaneKey = paneKey
return state
})
}
closePane = (paneKey) => {
this.setState(({ ...state }) => {
if (paneKey === state.focusingPaneKey) {
const paneKeyIndex = state.openingPaneKeys.indexOf(paneKey)
state.focusingPaneKey = state.openingPaneKeys[paneKeyIndex - 1]
}
state.openingPaneKeys = state.openingPaneKeys.filter((openingPaneKey) => openingPaneKey !== paneKey)
return state
})
}
handleTabsEdit = (key, action) => {
if (action === 'remove') {
this.closePane(key)
}
}
render() {
const { panes } = this.props
const keysOfPane = Object.keys(panes)
return (
<div className="tab-section">
<div style={{ marginBottom: 16 }}>
{keysOfPane.map((key) => (
<Button key={key} onClick={() => this.openPane(key)}>
ADD Tab-{key}
</Button>
))}
</div>
<Tabs
hideAdd
onChange={this.openPane}
activeKey={this.state.focusingPaneKey}
type="editable-card"
onEdit={this.handleTabsEdit}
>
{this.state.openingPaneKeys
.map((key) => panes[key])
.map((pane) => (
<TabPane tab={pane.title} key={pane.key}>
{pane.content}
</TabPane>
))}
</Tabs>
</div>
)
}
}
You can pass panes data by props.
I'm new React developer(mainly with hooks but did not find good example with hooks), here i have antd table with search functionality, my question is when user writes something in search then user gets different result, how to cancel that search by clicking 'Reset' button ?
my code:
https://codesandbox.io/s/antd-table-filter-search-forked-mqhcn?file=/src/EventsSection/EventsSection.js
You can add an id to your input into TitleSearch.js:
<Search
id='IDYOUWANT'
placeholder="Enter Title"
onSearch={onSearch}
onChange={onChange}
style={{ width: 200 }}
/>
And add event into EventsSection.js
ResetInput = () => {
const input = document.getElementById('IDYOUWANT');
input.value = '';
this.handleSearch('');
}
....
<button
onClick={this.ResetInput}
>Reset</button>
Change IDYOUWANT with your id
run this code
Created a new function for reset value and trigger it from reset button.
function:
resetValue = () =>{
this.setState({
eventsData: eventsData
});
}
And trigger from button
<button onClick={this.resetValue}>Reset</button>
all code::
import React, { Component } from "react";
import styles from "./style.module.css";
import { EventsTable } from "../EventsTable";
import { StatusFilter } from "../StatusFilter";
import { TitleSearch } from "../TitleSearch";
const eventsData = [
{
key: 1,
title: "Bulletproof EP1",
fileType: "Atmos",
process: "match media",
performedBy: "Denise Etridge",
operationNote: "-",
updatedAt: "26/09/2018 17:21",
status: "complete"
},
{
key: 2,
title: "Dexter EP2",
fileType: "Video",
process: "Compliance",
performedBy: "Dane Gill",
operationNote: "passed",
updatedAt: "21/09/2018 12:21",
status: "inProgress"
}
];
class EventsSection extends Component {
constructor(props) {
super(props);
this.state = {
eventsData
};
}
handleFilter = (key) => {
const selected = parseInt(key);
if (selected === 3) {
return this.setState({
eventsData
});
}
const statusMap = {
1: "complete",
2: "inProgress"
};
const selectedStatus = statusMap[selected];
const filteredEvents = eventsData.filter(
({ status }) => status === selectedStatus
);
this.setState({
eventsData: filteredEvents
});
};
handleSearch = (searchText) => {
const filteredEvents = eventsData.filter(({ title }) => {
title = title.toLowerCase();
return title.includes(searchText);
});
this.setState({
eventsData: filteredEvents
});
};
handleChange = (e) => {
const searchText = e.target.value;
const filteredEvents = eventsData.filter(({ title }) => {
title = title.toLowerCase();
return title.includes(searchText);
});
this.setState({
eventsData: filteredEvents
});
};
resetValue = () =>{
this.setState({
eventsData: eventsData
});
}
render() {
return (
<section className={styles.container}>
<header className={styles.header}>
<h1 className={styles.title}>Events</h1>
<button onClick={this.resetValue}>Reset</button>
<TitleSearch
onSearch={this.handleSearch}
onChange={this.handleChange}
className={styles.action}
/>
</header>
<EventsTable eventsData={this.state.eventsData} />
</section>
);
}
}
export { EventsSection };
Here is what i did in order to solve it:
i added onClick on the button
<button onClick={this.resetSearch}>Reset</button>
Then in the function i put handleSearch to '', by doing this it reset the table:
resetSearch = () =>{
this.handleSearch('')
}