Nextjs: Button onclick toggle in sidebar overlay - reactjs

I have a case regarding the onclick button to open the "choose template" sidebar.
the interface is like this.
So when the button is pressed, the "choose template" sidebar will appear.
However, when I click the button, the sidebar won't appear. do you think that's why? is there something wrong with my coding? Thank you
My Code=
Editor.jsx
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/router";
import styles from "./Editor.module.scss";
import PropTypes from "prop-types";
import { Button } from "../../global/Button";
import ColorPicker from "./ColorPicker";
import "react-edit-text/dist/index.css";
import RightArrow from "../../../public/images/qrcode/rightArrow.svg";
let qrCode;
if (typeof window !== "undefined") {
console.log("i am client");
const QRCodeStyling = require("qr-code-styling");
qrCode = new QRCodeStyling({
width: 1000,
height: 1000,
margin: 50,
qrOptions: { typeNumber: "0", mode: "Byte", errorCorrectionLevel: "Q" },
imageOptions: { hideBackgroundDots: true, imageSize: 0.2, margin: 10 },
dotsOptions: {
type: "rounded",
color: "#756ce0",
gradient: {
type: "radial",
rotation: 0,
colorStops: [
{ offset: 0, color: "#aa80f9" },
{ offset: 1, color: "#756ce0" },
],
},
},
backgroundOptions: { color: "#ffffff", gradient: null },
image: "https://i.ibb.co/SrpHzTQ/icon-200px.png",
dotsOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#6a1a4c", color2: "#6a1a4c", rotation: "0" },
},
cornersSquareOptions: { type: "extra-rounded", color: "#756ce0" },
cornersSquareOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#000000", color2: "#000000", rotation: "0" },
},
cornersDotOptions: { type: "", color: "#613583", gradient: null },
cornersDotOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#000000", color2: "#000000", rotation: "0" },
},
backgroundOptionsHelper: {
colorType: { single: true, gradient: false },
gradient: { linear: true, radial: false, color1: "#ffffff", color2: "#ffffff", rotation: "0" },
},
});
}
import { BsFileEarmarkPdfFill } from "react-icons/bs";
import { IoIosArrowBack } from "react-icons/io";
const Editor = ({ isResponsive, template, list, merchant, setActive, color, toggleClick }) => {
const { Template } = template;
const warna = "linear-gradient(180deg, #aa80f9 0%, #756ce0 100%)";
const router = useRouter();
const qrRef = useRef();
const [colorProps, setColorProps] = useState(warna);
useEffect(() => {
setTimeout(() => {
if (qrRef.current) qrCode.append(qrRef.current);
}, 100);
}, [Template]);
useEffect(() => {
qrCode.update({
data: process.env.NEXT_PUBLIC_SHARE_URL + "/" + router.query.shareKey,
});
}, [Template]);
// const handleklik = (e) => {
// console.log('Free pizza!');
// }
return (
<>
<div className={styles.container}>
<ColorPicker colorProps={color} callback={(event) => setColorProps(event)} />
<Button onClick={toggleClick} className={styles.button}>
Open Template
</Button>
<IoIosArrowBack
className={styles.arrow + " " + styles.back}
onClick={() => {
setActive(template.id === 0 ? list.length - 1 : template.id - 1);
}}
/>
<div className={styles.paper_container}>
<Template qrRef={qrRef} merchant={merchant} color={colorProps.hex} isResponsive={isResponsive} />
<div className={styles.paper_overlay} id="paper-overlay">
<BsFileEarmarkPdfFill />
<span>Generating PDF</span>
</div>
</div>
<RightArrow
className={styles.arrow + " " + styles.next}
onClick={() => {
setActive(template.id === list.length - 1 ? 0 : template.id + 1);
}}
/>
</div>
</>
);
};
Editor.propTypes = {
template: PropTypes.string,
list: PropTypes.string,
merchant: PropTypes.string,
setActive: PropTypes.string,
color: PropTypes.string,
isResponsive: PropTypes.bool,
toggleClick: PropTypes.func,
};
export default Editor;
Template.jsx
import { useState, useEffect } from "react";
import Image from "next/image";
import styles from "./Template.module.scss";
import PropTypes from "prop-types";
import { FaCheck } from "react-icons/fa";
import { Button } from "../../global/Button";
const Card = ({ data, active, setActive }) => {
return (
<div className={styles.card} onClick={() => setActive(data.id)}>
<Image src={data.image} alt={"template " + data.id} width={116} height={164} />
{active === data.id && (
<div className={styles.overlay}>
<FaCheck />
</div>
)}
</div>
);
};
const Template = ({ list, active, setActive, download }) => {
const [isResponsive, setResponsive] = useState(typeof window !== "undefined" ? window.innerWidth <= 800 : false);
const [isHide, setHide] = useState(true);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 800) {
setResponsive(true);
} else {
setResponsive(false);
}
};
if (window !== "undefined") window.addEventListener("resize", handleResize);
}, []);
useEffect(() => {
setHide(true);
}, [isResponsive]);
return (
<div className={styles.container}>
<div className={styles.card_container} style={{ right: isHide ? null : 0, position: isResponsive && "fixed" }}>
{isResponsive && !isHide && <div className={styles.template_overlay} onClick={() => setHide(true)} />}
<h3>Pilih Template</h3>
{list.map((template) => {
return <Card data={template} key={template.id} active={active} setActive={setActive} />;
})}
</div>
<Button onClick={download} className={styles.button}>
DOWNLOAD
</Button>
</div>
);
};
Card.propTypes = {
data: PropTypes.string,
active: PropTypes.string,
setActive: PropTypes.string
};
Template.propTypes = {
list: PropTypes.string,
active: PropTypes.string,
setActive: PropTypes.string,
download: PropTypes.string,
isResponsive: PropTypes.bool
};
export default Template;
[sharekey].jsx
import { useState, useEffect } from "react";
import { jsPDF } from "jspdf";
import html2canvas from "html2canvas";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import styles from "./Qrcode.module.scss";
import { useRecoilValue } from "recoil";
import { userProfile } from "../../../utils/recoil";
import Sidebar from "../../../components/global/Wrapper/Sidebar/index";
import Editor from "../../../components/edit-survey/qrcode/Editor";
import Template from "../../../components/edit-survey/qrcode/Template";
import TemplateOne from "../../../components/edit-survey/qrcode/template/One";
import TemplateTwo from "../../../components/edit-survey/qrcode/template/Two";
import TemplateThree from "../../../components/edit-survey/qrcode/template/Three";
import TemplateFour from "../../../components/edit-survey/qrcode/template/Four";
import TemplateFive from "../../../components/edit-survey/qrcode/template/Five";
import TemplateSix from "../../../components/edit-survey/qrcode/template/Six";
const Template1 = "/images/qrcode/Template1.jpg";
const Template2 = "/images/qrcode/Template2.jpg";
const Template3 = "/images/qrcode/Template3.jpg";
const Template4 = "/images/qrcode/Template4.jpg";
const Template5 = "/images/qrcode/Template5.jpg";
const Template6 = "/images/qrcode/Template6.jpg";
const templateList = [
{ Template: TemplateOne, id: 0, image: Template1 },
{ Template: TemplateTwo, id: 1, image: Template2 },
{ Template: TemplateThree, id: 2, image: Template3 },
{ Template: TemplateFour, id: 3, image: Template4 },
{ Template: TemplateFive, id: 4, image: Template5 },
{ Template: TemplateSix, id: 5, image: Template6 },
];
const color = {
r: "170",
g: "128",
b: "249",
a: "1",
};
const Qrcode = () => {
const [activeTemplate, setActiveTemplate] = useState(0);
const profile = useRecoilValue(userProfile);
const [isResponsive, setResponsive] = useState(typeof window !== "undefined" ? window.innerWidth <= 800 : false);
const [isHide, setHide] = useState(true);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 800) {
setResponsive(true);
} else {
setResponsive(false);
}
};
if (window !== "undefined") window.addEventListener("resize", handleResize);
}, []);
useEffect(() => {
setHide(true);
}, [isResponsive]);
const download = () => {
const paper = document.getElementById("paper-pdf");
const overlay = document.getElementById("paper-overlay");
overlay.style.display = "flex";
paper.style.transform = "scale(2)";
html2canvas(paper).then((canvas) => {
const imgData = canvas.toDataURL("image/jpg");
const pdf = new jsPDF({
orientation: "potrait",
unit: "pt",
format: "a5",
});
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, "JPG", 0, 0, pdfWidth, pdfHeight);
pdf.save("QRCode.pdf");
paper.style.transform = null;
overlay.style.display = null;
});
};
return (
<Sidebar style={{ paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<div className={styles.container}>
<Editor
color={color}
template={templateList[activeTemplate]}
list={templateList}
merchant={profile.merchant}
setActive={setActiveTemplate}
toggleClick={() => setHide(!isHide)}
isResponsive={isResponsive}
/>
<Template list={templateList} active={activeTemplate} setActive={setActiveTemplate} download={download} isResponsive={isResponsive} />
</div>
</Sidebar>
);
};
export const getServerSideProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ["common", "edit-survey"])),
},
});
export default Qrcode;

you should pass down the isHide and setIsHide down to Template component. and remove the isHide, setIsHide useState from the Template component
so in [sharekey].jsx
<Template list={templateList} active={activeTemplate} setActive={setActiveTemplate} download={download} isResponsive={isResponsive} isHide={isHide} setIsHide={setIsHide}/>

Related

ApexChart: Dunot chart ir not showing labels

I'm having a problem with donut charts in ApexCharts in my React App.
I have an API that returns to me a JSON and I pass this JSON data to some charts. The chart it's showing correct data, but the label isn't showing anything.
If I change something in the ChartComponent, for example, change the 'fontSize' from 15 to 10 the values ​​of the labels are shown, but when rendering the screen, they disappear and return to 0.
see here how the graphs are appearing
see here how the graphs are when I change the 'fontSize'
App()
export default function App() {
const referenceDate = new Date();
const currentYear = referenceDate.getFullYear();
const currentMonth = referenceDate.getMonth() + 1;
const currentMonthName = referenceDate.toLocaleString("default", {
month: "long",
});
const [month, setMonth] = useState(currentMonthName);
const [monthId, setMonthId] = useState(currentMonth);
const [apiData, setApiData] = useState();
useEffect(() => {
async function fillData() {
if (month) {
await getData(currentYear, monthId).then((response) =>
setApiData(response)
);
}
}
fillData();
}, [monthId]);
const handleChange = (e) => {
const selectedMonth = e.target.value;
const selectedMonthId = Months[e.target.value].id;
setMonth(selectedMonth);
setMonthId(selectedMonthId);
};
return (
<>
<div className={styles.chartGroup}>
<ChartCard title="Business Unit Head" value={apiData ? apiData['first'] : 0}></ChartCard>
<ChartCard title="Financial" value={apiData ? apiData['second'] : 0}></ChartCard>
</div>
<div className={styles.chartGroup}>
<ChartCard title="Commercial And Pipeline [LATAM]" value={apiData ? apiData['third'] : 0}></ChartCard>
<ChartCard title="Commercial And Pipeline [NAM]" value={apiData ? apiData['fourth'] : 0}></ChartCard>
</div>
<div className={styles.chartGroup}>
<ChartCard title="HR And Recuitment" value={apiData ? apiData['fifth'] : 0}></ChartCard>
<ChartCard title="Delivery" value={apiData ? apiData['sixth] : 0}></ChartCard>
</div>
</div>
</>
);
}
const getData = async (year, month) => (await axiosInstance.get(`/homeChart/${year}/${month}`)).data;
async function generateChartData(data) {
if (data) {
return data;
} else {
console.log("no data");
}
}
ChartComponent
export default function ChartCard(props) {
let progressValue = 0;
let lapseValue = 0;
const data = props.value;
progressValue = data;
lapseValue = 100 - data;
const options = {
colors: ["#0ead69", "#e71d36"],
labels: ["Progress", "Lapse"],
title: {
text: props.title,
align: "center",
style: {
fontSize: "15px",
fontWeight: "normal",
textDecoration: "underline",
},
},
stroke: {
width: 0,
},
legend: {
show: false,
},
dataLabels: {
enabled: false,
},
plotOptions: {
pie: {
expandOnClick: true,
donut: {
background: "white",
labels: {
show: true,
total: {
show: true,
fontSize: "15",
fontWeight: 10,
formatter: function () {
return data + "%";
},
},
name: {
show: false,
},
value: {
show: true,
},
},
},
},
},
};
const series = [progressValue, lapseValue];
return (
<>
<div className={styles.ChartDiv}>
<Chart
data={data}
type="donut"
width="100%"
height={140}
series={series}
options={options}
/>
</div>
</>
);
}
JSON return
{
"first": 4,
"second": 24,
"third": 2.5,
"forth": 9.5,
"fifth": 22,
"sixth": 2
}

Extract Draft.js content

I'm using draft.js and trying to extract the content with an onClick function and log it to the console. I've spent several hours doing this, but keep getting console errors and I still can't figure out the underlying logic.
Can anyone please offer a guide?
The code is just the default draft.js one with my function and a button added:
import React from "react";
import { Editor, EditorState, getDefaultKeyBinding, RichUtils } from "draft-js";
import "./draft.css";
class TextEditor extends React.Component {
constructor(props) {
super(props);
this.state = { editorState: EditorState.createEmpty() };
this.focus = () => this.refs.editor.focus();
this.onChange = (editorState) => this.setState({ editorState });
this.handleKeyCommand = this._handleKeyCommand.bind(this);
this.mapKeyToEditorCommand = this._mapKeyToEditorCommand.bind(this);
this.toggleBlockType = this._toggleBlockType.bind(this);
this.toggleInlineStyle = this._toggleInlineStyle.bind(this);
}
_handleKeyCommand(command, editorState) {
const newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
this.onChange(newState);
return true;
}
return false;
}
_mapKeyToEditorCommand(e) {
if (e.keyCode === 9 /* TAB */) {
const newEditorState = RichUtils.onTab(
e,
this.state.editorState,
4 /* maxDepth */
);
if (newEditorState !== this.state.editorState) {
this.onChange(newEditorState);
}
return;
}
return getDefaultKeyBinding(e);
}
_toggleBlockType(blockType) {
this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
}
_toggleInlineStyle(inlineStyle) {
this.onChange(
RichUtils.toggleInlineStyle(this.state.editorState, inlineStyle)
);
}
render() {
const { editorState } = this.state;
// If the user changes block type before entering any text, we can
// either style the placeholder or hide it. Let's just hide it now.
let className = "RichEditor-editor";
var contentState = editorState.getCurrentContent();
if (!contentState.hasText()) {
if (contentState.getBlockMap().first().getType() !== "unstyled") {
className += " RichEditor-hidePlaceholder";
}
}
return (
<div className="RichEditor-root">
<BlockStyleControls
editorState={editorState}
onToggle={this.toggleBlockType}
/>
<InlineStyleControls
editorState={editorState}
onToggle={this.toggleInlineStyle}
/>
<div className={className} onClick={this.focus}>
<Editor
blockStyleFn={getBlockStyle}
customStyleMap={styleMap}
editorState={editorState}
handleKeyCommand={this.handleKeyCommand}
keyBindingFn={this.mapKeyToEditorCommand}
onChange={this.onChange}
placeholder="Tell a story..."
ref="editor"
spellCheck={true}
/>
</div>
</div>
);
}
}
function handleOnClick(e) {
const content = this.state.editorState.getCurrentContent();
console.log(content);
e.preventDefault();
console.log(EditorState.getCurrentContent);
}
// Custom overrides for "code" style.
const styleMap = {
CODE: {
backgroundColor: "rgba(0, 0, 0, 0.05)",
fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
fontSize: 16,
padding: 2,
},
};
function getBlockStyle(block) {
switch (block.getType()) {
case "blockquote":
return "RichEditor-blockquote";
default:
return null;
}
}
class StyleButton extends React.Component {
constructor() {
super();
this.onToggle = (e) => {
e.preventDefault();
this.props.onToggle(this.props.style);
};
}
render() {
let className = "RichEditor-styleButton";
if (this.props.active) {
className += " RichEditor-activeButton";
}
return (
<span className={className} onMouseDown={this.onToggle}>
{this.props.label}
</span>
);
}
}
const BLOCK_TYPES = [
{ label: "H1", style: "header-one" },
{ label: "H2", style: "header-two" },
{ label: "H3", style: "header-three" },
{ label: "H4", style: "header-four" },
{ label: "H5", style: "header-five" },
{ label: "H6", style: "header-six" },
{ label: "Blockquote", style: "blockquote" },
{ label: "UL", style: "unordered-list-item" },
{ label: "OL", style: "ordered-list-item" },
{ label: "Code Block", style: "code-block" },
];
const BlockStyleControls = (props) => {
const { editorState } = props;
const selection = editorState.getSelection();
const blockType = editorState
.getCurrentContent()
.getBlockForKey(selection.getStartKey())
.getType();
return (
<div className="RichEditor-controls">
{BLOCK_TYPES.map((type) => (
<StyleButton
key={type.label}
active={type.style === blockType}
label={type.label}
onToggle={props.onToggle}
style={type.style}
/>
))}
</div>
);
};
var INLINE_STYLES = [
{ label: "Bold", style: "BOLD" },
{ label: "Italic", style: "ITALIC" },
{ label: "Underline", style: "UNDERLINE" },
{ label: "Monospace", style: "CODE" },
];
const InlineStyleControls = (props) => {
const currentStyle = props.editorState.getCurrentInlineStyle();
return (
<div className="RichEditor-controls">
{INLINE_STYLES.map((type) => (
<StyleButton
key={type.label}
active={currentStyle.has(type.style)}
label={type.label}
onToggle={props.onToggle}
style={type.style}
/>
))}
<input type="submit" onClick={handleOnClick} />
</div>
);
};
export default TextEditor;

How to convern ANTD class-based component to react function-based component

Can anyone give a suggestion on how can I convert Ant Design class-based component into function-based? I am new to class-based, so it is pretty confusing for me to convert class components. Now, my application is a functional-based component. Any suggestion will be appreciated!
Transfer Component
import { Transfer, Button } from 'antd';
class App extends React.Component {
state = {
mockData: [],
targetKeys: [],
};
componentDidMount() {
this.getMock();
}
getMock = () => {
const targetKeys = [];
const mockData = [];
for (let i = 0; i < 20; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
};
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
this.setState({ mockData, targetKeys });
};
handleChange = targetKeys => {
this.setState({ targetKeys });
};
renderFooter = (props, { direction }) => {
if (direction === 'left') {
return (
<Button size="small" style={{ float: 'left', margin: 5 }} onClick={this.getMock}>
Left button reload
</Button>
);
}
return (
<Button size="small" style={{ float: 'right', margin: 5 }} onClick={this.getMock}>
Right button reload
</Button>
);
};
render() {
return (
<Transfer
dataSource={this.state.mockData}
showSearch
listStyle={{
width: 250,
height: 300,
}}
operations={['to right', 'to left']}
targetKeys={this.state.targetKeys}
onChange={this.handleChange}
render={item => `${item.title}-${item.description}`}
footer={this.renderFooter}
/>
);
}
}
ReactDOM.render(<App />, mountNode);
in function component to define state you can use useState hook, and also instead of lifecycles such as componentDidMount, componentDidUpdate, ... you can use useEffect hook, liek this:
import {useState, useEffect} from 'react';
import { Transfer, Button } from 'antd';
function App() {
const [state, setState] = useState({
mockData: [],
targetKeys: [],
});
const getMock = () => {
const targetKeys = [];
const mockData = [];
for (let i = 0; i < 20; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
};
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
setState({ mockData, targetKeys });
};
useEffect(()=>{
getMock();
}, [])
const handleChange = targetKeys => {
setState(prevState => ({ ...prevState, targetKeys }));
};
const renderFooter = (props, { direction }) => {
if (direction === 'left') {
return (
<Button size="small" style={{ float: 'left', margin: 5 }} onClick={getMock}>
Left button reload
</Button>
);
}
return (
<Button size="small" style={{ float: 'right', margin: 5 }} onClick={getMock}>
Right button reload
</Button>
);
};
return (
<Transfer
dataSource={state.mockData}
showSearch
listStyle={{
width: 250,
height: 300,
}}
operations={['to right', 'to left']}
targetKeys={state.targetKeys}
onChange={handleChange}
render={item => `${item.title}-${item.description}`}
footer={renderFooter}
/>
);
}

fluent ui details List implementation in Functional component

Can anybody send code on how to implement fluent UI details List in Functional Component(https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist/basic) and how to fetch data from API to details List
That's a start you will need to "refact" this code by the way this is a really good practice :
import * as React from "react";
import { Announced } from "office-ui-fabric-react/lib/Announced";
import {
TextField,
ITextFieldStyles
} from "office-ui-fabric-react/lib/TextField";
import {
DetailsList,
DetailsListLayoutMode,
Selection,
IColumn
} from "office-ui-fabric-react/lib/DetailsList";
import { MarqueeSelection } from "office-ui-fabric-react/lib/MarqueeSelection";
import { Fabric } from "office-ui-fabric-react/lib/Fabric";
import { mergeStyles } from "office-ui-fabric-react/lib/Styling";
import { Text } from "office-ui-fabric-react/lib/Text";
const exampleChildClass = mergeStyles({
display: "block",
marginBottom: "10px"
});
const textFieldStyles: Partial<ITextFieldStyles> = {
root: { maxWidth: "300px" }
};
export interface IDetailsListBasicExampleItem {
key: number;
name: string;
value: number;
}
export interface IDetailsListBasicExampleState {
items: IDetailsListBasicExampleItem[];
selectionDetails: string;
}
export const DetailsListBasicExampleFunction: React.FunctionComponent<
{} | IDetailsListBasicExampleState
> = () => {
const _allItems: IDetailsListBasicExampleItem[] = [];
const [selection, setSelection] = React.useState<Selection | undefined>();
function _getSelectionDetails(): string {
const selectionCount = selection ? selection.getSelectedCount() : 0;
switch (selectionCount) {
case 0:
return "No items selected";
case 1:
return (
"1 item selected: " +
(selection.getSelection()[0] as IDetailsListBasicExampleItem).name
);
default:
return `${selectionCount} items selected`;
}
}
const [state, setState] = React.useState({
items: _allItems,
selectionDetails: _getSelectionDetails()
});
React.useEffect(() => {
const _selection: Selection = new Selection({
onSelectionChanged: () =>
setState((prev) => {
return { ...prev, selectionDetails: _getSelectionDetails() };
})
});
setSelection(_selection);
for (let i = 0; i < 200; i++) {
_allItems.push({
key: i,
name: "Item " + i,
value: i
});
}
setState((prev) => {
return { ...prev, items: _allItems };
});
}, []);
const _columns: IColumn[] = [
{
key: "column1",
name: "Name",
fieldName: "name",
minWidth: 100,
maxWidth: 200,
isResizable: true
},
{
key: "column2",
name: "Value",
fieldName: "value",
minWidth: 100,
maxWidth: 200,
isResizable: true
}
];
// Populate with items for demos.
const _onFilter = (
ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
text: string
): void => {
console.log(text);
setState((prev) => {
return {
...prev,
items: text
? _allItems.filter((i) => i.name.toLowerCase().indexOf(text) > -1)
: _allItems
};
});
};
const _onItemInvoked = (item: IDetailsListBasicExampleItem): void => {
alert(`Item invoked: ${item.name}`);
};
return selection ? (
<Fabric>
<div className={exampleChildClass}>{state.selectionDetails}</div>
<Text>
Note: While focusing a row, pressing enter or double clicking will
execute onItemInvoked, which in this example will show an alert.
</Text>
<Announced message={state.selectionDetails} />
<TextField
className={exampleChildClass}
label="Filter by name:"
onChange={(e, t) => _onFilter(e, t ?? "")}
styles={textFieldStyles}
/>
<Announced
message={`Number of items after filter applied: ${state.items.length}.`}
/>
<MarqueeSelection selection={selection}>
<DetailsList
items={state.items}
columns={_columns}
setKey="set"
layoutMode={DetailsListLayoutMode.justified}
selection={selection}
selectionPreservedOnEmptyClick={true}
ariaLabelForSelectionColumn="Toggle selection"
ariaLabelForSelectAllCheckbox="Toggle selection for all items"
checkButtonAriaLabel="select row"
onItemInvoked={_onItemInvoked}
/>
</MarqueeSelection>
</Fabric>
) : (
<div>Loading</div>
);
};
UPDATE
To pass this sample of code in JSX this is pretty easy you just need to remove all type thing.
And to fetch data I use axios.
see the code below:
import * as React from "react";
import { Announced } from "office-ui-fabric-react/lib/Announced";
import { TextField } from "office-ui-fabric-react/lib/TextField";
import {
DetailsList,
DetailsListLayoutMode,
Selection
} from "office-ui-fabric-react/lib/DetailsList";
import { MarqueeSelection } from "office-ui-fabric-react/lib/MarqueeSelection";
import { Fabric } from "office-ui-fabric-react/lib/Fabric";
import { mergeStyles } from "office-ui-fabric-react/lib/Styling";
import { Text } from "office-ui-fabric-react/lib/Text";
import axios from "axios";
const exampleChildClass = mergeStyles({
display: "block",
marginBottom: "10px"
});
const textFieldStyles = {
root: { maxWidth: "300px" }
};
export const DetailsListBasicExampleFunction = () => {
const _allItems = [];
const [selection, setSelection] = React.useState();
function _getSelectionDetails() {
const selectionCount = selection ? selection.getSelectedCount() : 0;
switch (selectionCount) {
case 0:
return "No items selected";
case 1:
return "1 item selected: " + selection.getSelection()[0].name;
default:
return `${selectionCount} items selected`;
}
}
const [state, setState] = React.useState({
items: _allItems,
selectionDetails: _getSelectionDetails()
});
React.useEffect(() => {
const _selection = new Selection({
onSelectionChanged: () =>
setState((prev) => {
return { ...prev, selectionDetails: _getSelectionDetails() };
})
});
setSelection(_selection);
//********************** */fetch data from api***************************************
axios
.get("/data.json") //pass your url in param
.then((res) =>
setState((prev) => {
return { ...prev, items: res.data };
})
); //pass data in setState
}, []);
const _columns = [
{
key: "column1",
name: "Name",
fieldName: "name",
minWidth: 100,
maxWidth: 200,
isResizable: true
},
{
key: "column2",
name: "Value",
fieldName: "value",
minWidth: 100,
maxWidth: 200,
isResizable: true
}
];
// Populate with items for demos.
const _onFilter = (ev, text) => {
console.log(text);
setState((prev) => {
return {
...prev,
items: text
? _allItems.filter((i) => i.name.toLowerCase().indexOf(text) > -1)
: _allItems
};
});
};
const _onItemInvoked = (item) => {
alert(`Item invoked: ${item.name}`);
};
return selection ? (
<Fabric>
<div className={exampleChildClass}>{state.selectionDetails}</div>
<Text>
Note: While focusing a row, pressing enter or double clicking will
execute onItemInvoked, which in this example will show an alert.
</Text>
<Announced message={state.selectionDetails} />
<TextField
className={exampleChildClass}
label="Filter by name:"
onChange={(e, t) => _onFilter(e, t ?? "")}
styles={textFieldStyles}
/>
<Announced
message={`Number of items after filter applied: ${state.items.length}.`}
/>
<MarqueeSelection selection={selection}>
<DetailsList
items={state.items}
columns={_columns}
setKey="set"
layoutMode={DetailsListLayoutMode.justified}
selection={selection}
selectionPreservedOnEmptyClick={true}
ariaLabelForSelectionColumn="Toggle selection"
ariaLabelForSelectAllCheckbox="Toggle selection for all items"
checkButtonAriaLabel="select row"
onItemInvoked={_onItemInvoked}
/>
</MarqueeSelection>
</Fabric>
) : (
<div>Loading</div>
);
};

How to render only 5 items in react autosuggest?

I'am using react autosuggest npm package to get the json data and display it. I want to display only 5 items. How to do it?
Form.js
import React from 'react'
import Autosuggest from 'react-autosuggest';
import cities from 'cities.json';
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
// Here I get data from cities.json
return inputLength === 0 ? [] : cities.filter(lang =>
lang.name.toLowerCase().slice(0, inputLength) === inputValue
);
);
};
const getSuggestionValue = suggestion => suggestion.name;
const renderSuggestion = suggestion => (
<div>
{console.log('suggestion', suggestion)}
{suggestion.name}
</div>
);
class Form extends React.Component {
constructor() {
super();
this.state = {
value: '',
suggestions: []
};
}
onChange = (event, { newValue }) => {
this.setState({
value: newValue
});
};
onSuggestionsFetchRequested = ({ value }) => {
this.setState({
suggestions: getSuggestions(value)
});
};
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
});
};
render(){
const { value, suggestions } = this.state;
// Autosuggest will pass through all these props to the input.
const inputProps = {
placeholder: 'Search City...',
value,
onChange: this.onChange
};
return (
<div>
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
/>
<br/>
</div>
)
}
}
export default Form;
I want to render only 5 items, otherwise, computer hangs while loading huge data. Is there any other autocomplete react npm package, since I want only cities and country list. i.e when city is inputted, automatically the city name must be suggested with its relevant country.Any solution or suggestion highly appreciated. Thanks in advance
i modified you're getSuggestions() method a little i guess this should work for you.
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
// Here I get data from cities.json
return inputLength === 0 ? [] : cities.filter(lang =>
lang.name.toLowerCase().slice(0, inputLength) === inputValue
).slice(0,5);
};
Use the Slice method with start index and last Index
suggestions={suggestions.slice(0, 5)}
import {
React
,Avatar
,axiosbase
} from '../../import-files';
import Autosuggest from 'react-autosuggest';
import './autosuggest.css';
import { withStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
import Paper from '#material-ui/core/Paper';
import MenuItem from '#material-ui/core/MenuItem';
let suggestions = [ { label: 'Afghanistan' } ];
function renderInputComponent(inputProps) {
const { classes, inputRef = () => {}, ref, ...other } = inputProps;
return (
<TextField
className={classes.textField}
fullWidth
variant="outlined"
InputProps={{
inputRef: node => {
ref(node);
inputRef(node);
},
classes: {
input: classes.input,
},
}}
{...other}
/>
);
}
function renderSuggestion(suggestion, { query, isHighlighted }) {
return (
<MenuItem selected={isHighlighted} component="div">
<div>
<strong key={String(suggestion.id)} style={{ fontWeight: 300 }}>
<span className="sugg-option">
<span className="icon-wrap">
<Avatar src={suggestion.Poster}></Avatar>
</span>
<span className="name">
{suggestion.Title}
</span>
</span>
</strong>
</div>
</MenuItem>
);
}
function initSuggestions(value) {
suggestions = value;
}
function getSuggestionValue(suggestion) {
return suggestion.Title;
}
function onSuggestionSelected(event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) {
console.log('HandleSuggestion() '+suggestionValue);
}
const styles = theme => ({
root: {
height: 50,
flexGrow: 1,
},
container: {
position: 'relative',
},
suggestionsContainerOpen: {
position: 'absolute',
zIndex: 998,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
overflowY: 'scroll',
maxHeight:'376%'
},
suggestion: {
display: 'block',
},
suggestionsList: {
margin: 0,
padding: 0,
listStyleType: 'none',
},
divider: {
height: theme.spacing.unit * 2,
},
});
class IntegrationAutosuggest extends React.Component {
state = {
single: '',
popper: '',
suggestions: [],
};
componentDidMount() {
initSuggestions(suggestions);
}
// Filter logic
getSuggestions = async (value) => {
const inputValue = value.trim().toLowerCase();
var _filter = JSON.stringify({
filter : inputValue,
});
return await axiosbase.post(`${apiCall}`, _filter);
};
handleSuggestionsFetchRequested = ({ value }) => {
this.getSuggestions(value)
.then(data => {
if (data.Error) {
this.setState({
suggestions: []
});
} else {
const responseData = [];
data.data.itemsList.map((item, i) => {
let File = {
id: item.idEnc,
Title: item.englishFullName +' '+item.arabicFullName,
englishFullName: item.englishFullName,
arabicFullName: item.arabicFullName,
Poster: item.photoPath,
}
responseData.push(File);
});
this.setState({
suggestions: responseData
});
}
})
};
handleSuggestionsClearRequested = () => {
this.setState({
suggestions: [],
});
};
handleChange = name => (event, { newValue }) => {
this.setState({
[name]: newValue,
});
if(event.type=='click'){
if(typeof this.props.handleOrderUserFirstNameChange === "function"){
this.props.handleOrderUserFirstNameChange(newValue);
}
this.state.suggestions.filter(f=>f.Title===newValue).map((item, i) => {
//id
//Title
// Poster
if(typeof this.props.handleUserIDChange === "function"){
this.props.handleUserIDChange(item.id);
}
});
}
};
render() {
const { classes } = this.props;
// console.log('Re-render!!');
// console.log(this.props);
// console.log(this.state.suggestions);
const autosuggestProps = {
renderInputComponent,
suggestions: this.state.suggestions,
onSuggestionsFetchRequested: this.handleSuggestionsFetchRequested,
onSuggestionsClearRequested: this.handleSuggestionsClearRequested,
onSuggestionSelected: this.props.onSelect,
getSuggestionValue,
renderSuggestion,
};
return (
<div className={classes.root}>
<Autosuggest
{...autosuggestProps}
inputProps={{
classes,
placeholder: this.props.placeHolder,
value: this.state.single,
onChange: this.handleChange('single'),
}}
theme={{
container: classes.container,
suggestionsContainerOpen: classes.suggestionsContainerOpen,
suggestionsList: classes.suggestionsList,
suggestion: classes.suggestion,
}}
renderSuggestionsContainer={options => (
<Paper {...options.containerProps} square>
{options.children}
</Paper>
)}
/>
<div className={classes.divider} />
</div>
);
}
}
export default withStyles(styles)(IntegrationAutosuggest);

Resources