All panels go inactive - accordion

When I change the "activeKey", all panels go inactive. Why?
import React, {useEffect, useState} from "react";
import { Collapse } from 'antd';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
export default function Abc() {
setTimeout(() => {
setOpenKey(["2"])
}, 3000)
const [openKey, setOpenKey] = useState(["1"])
return (
<div>
<Collapse accordion activeKey={openKey} >
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>
</div>
)
}
My goal is to drive through the "useState" hook, when I open or close the panels.

When you use activeKey, it's means the component is a controlled component. You should change activeKey in onChange handler in order to active other panels.
You can do like this
const [openKey, setOpenKey] = useState(["1"])
const callback = (key) => {
setOpenKey([key])
}
return (
<div>
<Collapse accordion activeKey={openKey} onChange={callback} >
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>
</div>
)

Related

Material UI - How Do I Pass In Styles Through the Select Component To Change The Popover Menu Look?

I am currently using the following to generate a select dropdown on my page:
<Select>
{options.map((option) => (
<MenuItem
className={classes.selectOption}
key={option}
value={option}
>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>
When I click on the dropdown on the page, an element with MuiPaper-root class appears on the page. This shows me the list of options in menu item format. I would like to style the MuiPaper-root element.
Is there a way to do this by passing in an attribute to the <Select> component?
Yes, you can change the paper by MenuProps
https://material-ui.com/api/select/#props
const useStyles = makeStyles((theme) => ({
paper: {
"& ul": {
backgroundColor: "red",
},
}
}));
export default function CustomizedSelects() {
const classes = useStyles();
return (
<Select MenuProps={{ classes: { paper: classes.paper} }}>
{options.map((option) => (
<MenuItem
className={classes.selectOption}
key={option}
value={option}
>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>);
}

Incorrect popover menu position when anchor element is externalized into another component

I'm new to both React and Material-UI. While examples work fine and perfectly make sense, they all use inline elements for both triggering button and the menu itself. I want to have some conditionals. For this, I'd rather have a separate component/function that renders this or that. However as soon as I move triggering button into a function, I get
Material-UI: the `anchorEl` prop provided to the component is invalid.
The anchor element should be part of the document layout.
Make sure the element is present in the document or that it's not display none.
I looked through similar questions here, but none of them looked relevant… or I didn't get them:(
Here is the code for modified example where I want to externalize button rendering into a function (to later add conditional and what not)
export default function SimpleMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const Qqq = () => {
return (
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Broken Menu
</Button>
)
}
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<p> hello</p>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Open Menu
</Button>
<Qqq />
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
Here is the fiddle
https://codesandbox.io/s/material-demo-7bnki?fontsize=14&hidenavigation=1&theme=dark . I did try to use SO code snippet, but I was getting some error about https://stacksnippets.net/js :(
What am I missing to make things work?
placing Qqq code inside SimpleManu is causing Qqq to remount on every SimpleMenu render.
Because Qqq remounted, the anchorEl reference is no longer valid.
To fix that, move Qqq outside SimpleMenu.
const Qqq = (props) => {
return (
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={props.handleClick}
>
Broken Menu
</Button>
)
}
export default function SimpleMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<p> hello</p>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
Open Menu
</Button>
<Qqq handleClick={handleClick}/>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
Code Sandbox
To see that Qqq really re mounts on every SimpleMenu render, go to the Code Sandbox and move Qqq to be inside SimpleMenu like before.
useEffect will print to console on every mount, and you can see what happens.

CX JS - Inserting html to title property of window

Is it possible to insert html content to the title of a window component in CX instead of a string? I need to customise the contents of my window title.
It is. Here is an example on how to put additional buttons in the header:
import { Button, FlexRow, Heading, HtmlElement, Window } from "cx/widgets";
export const App = (
<cx>
<div>
<Window bodyStyle="padding: 1rem">
<FlexRow putInto="header" spacing align="center">
<Heading level={4}>My Title</Heading>
<div style="flex: 1" />
<Button mod="hollow" icon="search" />
</FlexRow>
Window Contents
</Window>
</div>
</cx>
);
https://fiddle.cxjs.io/?f=oydjHF84
Another option is to use the header property. This way you can also create custom content placeholders within the header:
<Window
header={(
<cx>
<FlexRow align="center" style="width: 100%;">
<span>Title</span>
<div style="flex: 1 1 0%" />
<ContentPlaceholder name="header-tools" />
</FlexRow>
</cx>
)}
>
<LookupField
putInto="header-tools"
style="width: 220px;"
mod="header-tool"
value-bind="classificationId"
options-bind="classifications"
/>
Window content
</Window>

Data Binding from TableSelectDialog to Form

I'm using TableSelectDialog to view some Carrier details. All I need is: If I select any item (row), then all the values from that row should get automatically populated to the form input fields.
In the attached image, if Carrier Name is selected from TableSelectDialog, then the remaining fields should be populated based on that value.
You can achieve the required functionality using the Binding context that you receive from the TableSelcect Dialog.
But for binding context to work properly, both form and the table select dialog should refer to the same Model.
Below is the working code:
VIEW.XML:
Has a Button to trigger the table select dialog.
Has a form.
<l:VerticalLayout class="sapUiContentPadding" width="100%">
<l:content>
<Button class="sapUiSmallMarginBottom" text="Show Table Select Dialog"
press="handleTableSelectDialogPress">
</Button>
<VBox class="sapUiSmallMargin">
<f:SimpleForm id="SimpleFormDisplay354">
<f:content>
<Label text="Supplier Name" />
<Text id="nameText" text="{SupplierName}" />
<Label text="Description" />
<Text text="{Description}" />
<Label text="ProductId" />
<Text text="{ProductId}" />
<Label text="Quantity" />
<Text id="countryText" text="{Quantity}" />
</f:content>
</f:SimpleForm>
</VBox>
</l:content>
</l:VerticalLayout>
Controller:
onInit: function () {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
handleTableSelectDialogPress: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("sap.m.sample.TableSelectDialog.Dialog", this);
}
this.getView().addDependent(this._oDialog);
// toggle compact style
this._oDialog.open();
},
handleClose: function (oEvent) {
var aContexts = oEvent.getParameter("selectedContexts");
if (aContexts && aContexts.length) {
// MessageToast.show("You have chosen " + aContexts.map(function(oContext) { return oContext.getObject().Name; }).join(", "));
this.byId('SimpleFormDisplay354').setBindingContext(aContexts[0]);
}
oEvent.getSource().getBinding("items").filter([]);
}
Now, we also have a Select dialog and on click of any Item we call method : handleClose
In handleClose, we obtain the clicked Item binding context and then tell the form : hey! refer to this context ( which is present in the model). Binding context has a path which tells the form from where to do the relative binding.
Please feel free to contact for more information.

get value checkbox in zk

i have a grid with list checkbox
<div height="200px">
<grid id ="actListBox" model="#bind(vm.actions)" >
<template name="model">
<row style=" width:200px !important; ">
<cell rowspan="5" align="left" >
<checkbox style="height: 70px; width:1000px; overflow: auto; margin-left:10px;"
label="${each.action_name}" id ="${each.actionid}" value ="${each.actionid}" />
</cell>
</row>
</template>
</grid>
<span>
<checkbox label="Check all" value ="checkall" id="chkAll"/>
</span>
</div>
and now i want get all value of checkbox but i can't found anyway
please help me
thanks all
You can in your composer get checked Ids by iterating over actions:
#Command
public void checkedIds(final Event e){
final StringBuilder builder = new StringBuilder("Checked Ids: ");
for (final Action action : actions) {
if (action.getChecked()) {
builder.append(action.getId()).append(' ');
}
}
Messagebox.show(builder.toString());
}
I updated the ZK fiddle.