React Semantic UI has DropDown with properties of OnClick
is it possible to make each selection with different onClick event. Pretty much have each selection to run separate function. so in the following example I need if angular was selected a runs a function that is different than css, or design
const options = [
{ key: 'angular', text: 'Angular', value: 'angular' },
{ key: 'css', text: 'CSS', value: 'css' },
{ key: 'design', text: 'Graphic Design', value: 'design' },
{ key: 'ember', text: 'Ember', value: 'ember' },
{ key: 'html', text: 'HTML', value: 'html' },
{ key: 'ia', text: 'Information Architecture', value: 'ia' },
{ key: 'javascript', text: 'Javascript', value: 'javascript' },
{ key: 'mech', text: 'Mechanical Engineering', value: 'mech' },
]
const DropdownExampleMultipleSelection = () => (
<Dropdown placeholder='Skills' fluid multiple selection options={options} />
)
I tried doing onchange but it gives me undefined value
handleChange = (e) => {
this.setState({value: e.target.value});
console.log('Dropdown changed ' + e.target.value);
return;
}
<Dropdown onChange={(e) => {this.handleChange(e)}} />
Code Sandbox with solution: https://codesandbox.io/s/vvz2yow5k5
class DropdownExampleMultipleSelection extends Component {
handleChange = (e, { value }) => {
// array of selected values
console.log(value);
};
render() {
return (
<Dropdown
placeholder="Skills"
fluid
multiple
selection
options={options}
onChange={this.handleChange}
/>
);
}
}
You can access the values by following:
handleClick = (e, data) => {
console.log(data.value)
console.log(e._targetInst.return.key)
}
data.value will give you all selected values while e._targetInst.return.key will give you key of currently changed element.
Working fiddle: https://stackblitz.com/edit/react-5b24ux?file=index.js
You can view values on each selection by opening the chrome devtools.
Related
I am using a wrapper around Antd Select component.
import { Select as ASelect } from 'antd';
function Select({ children, ...props }) {
return <ASelect {...props}>{children}</ASelect>;
}
function Option({ children, ...props }) {
return <ASelect.Option {...props}>{children}</ASelect.Option>;
}
Select.Option = Option;
Which is throwing the below error where ever this component is used.
Warning: `children` should be `Select.Option` or `Select.OptGroup` instead of `Option`.
Usage:
<Select defaultValue="option1" style={{ width: 120 }}>
{options.map((o) => {
const { key, label } = o;
return (
<Select.Option key={key} value={key}>
{label}
</Select.Option>
);
})}
</Select>
Options Array:
const options = [
{ key: 'option1', label: 'Option 1' },
{ key: 'option2', label: 'Option 2' },
{ key: 'option3', label: 'Option 3' },
];
Live Demo
With the latest version of Antd (5.0.0) you can simply pass options as a prop.
<Select options={options} defaultValue="option1" style={{ width: 120 }} />
Options should now contain value instead of key. ( unique key for every option will be handled by Select component internally )
const options = [
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
{ value: 'option3', label: 'Option 3' },
];
children is optional now.
You need to update your base Select implementation as below else you will end up with No Data in the select. ( As you might not use children in every Select instance )
function Select(props) {
return <ASelect {...props} />;
}
Note: options prop is given more priority over children
Working Code (No console warning)
Following this guide from Jeffrey Carandang works with when a single class is added, no block validation errors.
But when I modify it to add more attributes and classes I get a block validation error.
The classes I want to add are added as expected on the front end.
I see that a validation error is expected when using blocks.getSaveContent.extraProps on existing content but the error appears when there is no content at all.
#imports
const allowedBlocks = ['core/button']
function addAttributes(settings) {
if (allowedBlocks.includes(settings.name)) {
settings.attributes = Object.assign(settings.attributes, {
buttonColor: {
type: 'string',
default: 'color-blue',
},
buttonWidth: {
type: 'string',
default: 'width-default',
},
buttonStyle: {
type: 'string',
default: 'style-default',
},
})
}
return settings
}
const withAdvancedControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { name, attributes, setAttributes, isSelected } = props
const { buttonColor, buttonWidth, buttonStyle } = attributes
function onChangeButtonColor(newValue) {
setAttributes({ buttonColor: newValue })
}
function onChangeButtonWidth(newValue) {
setAttributes({ buttonWidth: newValue })
}
function onChangeButtonStyle(newValue) {
setAttributes({ buttonStyle: newValue })
}
return (
<Fragment>
<BlockEdit {...props} />
{isSelected && allowedBlocks.includes(name) && (
<InspectorControls>
<PanelBody title="Button Settings" initialOpen={true}>
<PanelRow>
<RadioControl
label="Color"
selected={buttonColor}
options={[
{ label: 'Blue', value: 'color-blue' },
{
label: 'Light Gray',
value: 'color-light-gray',
},
{ label: 'Dark Gray', value: 'color-dark-gray' },
]}
onChange={onChangeButtonColor}
/>
</PanelRow>
<PanelRow>
<RadioControl
label="Width"
selected={buttonWidth}
options={[
{ label: 'Default', value: 'width-default' },
{ label: 'Full Width', value: 'width-full' },
]}
onChange={onChangeButtonWidth}
/>
</PanelRow>
<PanelRow>
<RadioControl
label="Style"
selected={buttonStyle}
options={[
{ label: 'Default', value: 'style-default' },
{ label: 'Outline', value: 'style-outline' },
]}
onChange={onChangeButtonStyle}
/>
</PanelRow>
</PanelBody>
</InspectorControls>
)}
</Fragment>
)
}
}, 'withAdvancedControls')
function applyExtraClass(extraProps, blockType, attributes) {
const { buttonColor, buttonWidth, buttonStyle } = attributes
if (allowedBlocks.includes(blockType.name)) {
const addedClasses = `${buttonColor} ${buttonWidth} ${buttonStyle}`
extraProps.className = classnames(extraProps.className, addedClasses)
}
return extraProps
}
addFilter(
'blocks.registerBlockType',
'editorskit/custom-attributes',
addAttributes
)
addFilter(
'editor.BlockEdit',
'editorskit/custom-advanced-control',
withAdvancedControls
)
addFilter(
'blocks.getSaveContent.extraProps',
'editorskit/applyExtraClass',
applyExtraClass
)
Any help would be appreciated.
I believe you may be over-thinking things in your use of the classname NPM package. The whole point of using it is that it strings the classes together for you. I suggest you replace classnames(extraProps.className, addedClasses) with classnames(extraProps.className, buttonColor, buttonWidth, buttonStyle).
Hi is it possible to abbreviate dropdown names when selected like the figure below
this is my code :
multiValue: [
{ value: "BUF", label: "BUF" },
{ value: "CCT", label: "CCT" },
{ value: "JHB", label: "JHB" },
{ value: "EKH", label: "EKH" },
{ value: "ETK", label: "ETK" },
{ value: "MAN", label: "MAN" },
{ value: "NMB", label: "NMB" },
{ value: "TSH", label: "TSH" }
],
handleMultiChange(option) {
this.setState({multiValue: option});
}
<Select
id='multiple'
name="filters"
placeholder="Filter City"
value={this.state.multiValue}
options={this.state.filterOptions}
onChange={this.handleMultiChange}
isMulti={this.state.isMulti}
styles={style}
/>
You could accomplish this by providing a custom MultiValueLabel component
MultiValueLabel.component.js
export default function MultiValueLabel({
data,
innerProps,
selectProps
}) {
// ...any logic you might need
// 'data' should be the full object of each selected item
// so reference whatever key is necessary
return (
<div {...innerProps}>
{data.abbr}
</div>
)
}
Then you just pass that in
<Select
components={{
MultiValueLabel
}}
... other props
/>
i'm new on react(hooks) typescript, trying to learn by doing,
here i have created antd table(which works), on the right side of table is 'Edit' it is clickable and works well, but my question is how to make each row clickable instead of that 'Edit' ? like i could click anywhere on the row and it should take me to its 'Edit' link instead of me clicking just on 'Edit':
import { useTranslation } from "react-i18next";
const { t } = useTranslation();
const columns = [
{
title: t("tilaus.state"),
dataIndex: "state",
key: "state",
render: (value: OrderState) => (
<span className="material-icons">
</span>
),
},
{
title: t("request.parcelId"),
dataIndex: "parcelId",
key: "parcelId",
},
{
title: t("request.date"),
dataIndex: "date",
key: "date",
render: (value: Date) => <div>{value.toLocaleDateString("af-AF")}</div>,
},
{
title: t("request.sender"),
dataIndex: "sender",
key: "sender",
render: (value: CustomerDto) => <div>{value.name}</div>,
},
{
title: t("request.recipient"),
dataIndex: "recipient",
key: "recipient",
render: (value: CustomerDto) => <div>{value.name}</div>,
},
{
title: t("request.price"),
dataIndex: "price",
key: "price",
},
{
title: "",
dataIndex: "id",
key: "id",
render: (value: string) => (
<Link to={"details/" + value}>{t("request.edit")}</Link>
),
},
];
<Table
dataSource={orders}
columns={columns}
pagination={false}
scroll={{ x: true }}
onRow={(record, rowIndex) => {
return {
onClick: (event) => {
handleClick(record);
},
};
}}
/>
Looks like you are using ant.d table. I've grabbed one of the examples and console logged the output. You can find it here: https://codesandbox.io/s/s1xds?file=/index.js to show you how the onclick in the entire row is being triggered.
For your specific thing, you need to change onRow prop. You can't add a Link directly to the row, but you can use history from react-router (if you are using it, docs here) or directly mutate the URL when onclick is called.
So in your case, you'll have to do this:
<Table
dataSource={orders}
columns={columns}
pagination={false}
scroll={{ x: true }}
onRow={(record, rowIndex) => {
return {
onClick: (event) => {
history.push(`/details/${record.id}`);
},
};
}}
/>
or
<Table
dataSource={orders}
columns={columns}
pagination={false}
scroll={{ x: true }}
onRow={(record, rowIndex) => {
return {
onClick: (event) => {
window.location.href = `${window.location.href}/details/${record.id}`
},
};
}}
/>
I have a table with multiple rows and I want to be able to make them all editable at once. Using the editable tag I've been able to go into edit mode and make one row at a time editable, but if I tab from one row to the next it doesn't save changes. I need to stop and click on a button to save changes. I want to be able to make changes throughout the table before hitting a save button. Is there a way to do this with material-table?
class Editable extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [
{ title: 'Name', field: 'name' },
{ title: 'Surname', field: 'surname', initialEditValue: 'initial edit value' },
{ title: 'Birth Year', field: 'birthYear', type: 'numeric' },
{
title: 'Birth Place',
field: 'birthCity',
lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
},
],
data: [
{ name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
{ name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
]
}
}
render() {
return (
<MaterialTable
title="Editable Preview"
columns={this.state.columns}
data={this.state.data}
editable={{
onRowUpdate: (newData, oldData) =>
new Promise((resolve, reject) => {
setTimeout(() => {
{
const data = this.state.data;
const index = data.indexOf(oldData);
data[index] = newData;
this.setState({ data }, () => resolve());
}
resolve()
}, 1000)
}),
}}
/>
)
}
}
You always have an option to override EditRow component and for example add an ability to save the row when you tab out of it. I'm afraid there's no other way for incorporating such functionality at the moment.