I need to show the number of selected options instead of the actually selected options. Here is what I'd like to achieve, which I created a mockup with manipulating the DOM in the browser inspection.
In the baseweb/baseui documentation, it is mentioned that it can be achieved by overriding, however, when I use override property, it affects the style and behavior as you can uncomment and see the result.
Here is the code-snippet:
https://codesandbox.io/s/nifty-johnson-erkfr
I asked the same question in the Baseweb Slack channel and here is the answer from one of the guys behind it.
overrides={{
MultiValue: {
component: (data) => {
if (selectedOption.length) {
const isFirst = selectedOption[0].id === data.value.id;
if (isFirst) {
return <Tag {...data} closeable={false}>{selectedOption.length} Selected</Tag>
}
}
return null
}
}
}}
Hope it saves someone else's time.
Related
I'm using a ListView control from #pnp/spfx-controls-react library version 2.5.0
There is a documented property called defaultSelection which is:
The index of the items to be select by default
I'm trying to use it like this to autoselect the first row of the table:
<ListView
items={this.state.items}
viewFields={this._viewFields}
selectionMode={SelectionMode.single}
selection={this._updateSelectedItems}
defaultSelection={[0]}
/>
But when the page loads it never selects anything. Also no errors in the console.
I've also used a bare example found here: https://github.com/RaspeR87/sp-dev-fx-webparts/tree/master/spfx-react-controls/ListView to try it on a simple project but again it never selects anything.
Did anyone manage to make use of this property? Every input appreciated.
Here is a hack to solve the problem:
// Add a useRef to your ListView control
const refListView = useRef<any>(null);
// Set selection on load
useEffect(() => {
// Set mySelection as default selection
const mySelection = [1,4,6];
mySelection.forEach(i => {
setTimeout(() => {
refDocs.current._selection.setIndexSelected(i, true, false);
}, 0);
});
}, []);
// ListView control
<ListView ref={refListView }...
Yes, I have the same test result as yours. You may post this issue in the PNP react control Github repository.https://github.com/pnp/sp-dev-fx-controls-react/issues
When you employ the CKEditor, the user might try to be edgy and paste several thousand lines at once. The browser wouldn't like that. One strategy would be to intercept the paste event and trim the data to a more manageable chunk.
Looking around I found this question - this is basically the same situation, I only can't get my head around how to achieve the same with the React component.
I'd also appreciate different and more insightful strategies.
In short, I posed a question directly in the developer's github issue tracker. With a lot of trail and error in the Javascript console and their eventual answer I managed to control the text coming in the CKEditor with a paste event.
Key points:
I used onInit prop. onReady didn't work for me.
The data in the paste event is divided in elements (like html ones) and is being accessed a bit weirdly.
I guess the best way to explain what I did would be to just show the code, so:
<CKEditor
id={id}
editor={ClassicEditor}
data={value}
onInit={editor => {
const documentView = editor.editing.view.document
documentView.on('paste', (event, data) => {
editor.plugins.get('Clipboard').on('inputTransformation', (event, data) => {
let accumulated = editor.getData()
for (const element of data.content.getChildren()) {
if (element._textData !== undefined) {
accumulated += element._textData
} else {
accumulated += element.getChild(0)._textData
}
if (accumulated.length >= SOME_LENGTH) {
event.stop()
editor.setData('')
editor.setData(accumulated.slice(0, SOME_LENGTH))
break
}
}
})
})
}}
onChange={(event, editor) => {
const data = editor.getData()
inputOnChange(data)
}}
/>
So that's it. I hope this shortens someone else's struggle a bit.
Conditional row styling on ag grid where I want to do rowstyle on user choice of cell value
gridoptions.getRowStyle = function(params) {
if (params.node.data === 'cell value typed by user in external/custom component i.e outside grid') {
return { 'background': value selected by user in cutom componet outside grid };
}
}
#sandeep's answer works perfectly. I just want to chime in another way to solve the problem which is to use context. context is just another javascript object which contains any information that you want to share within AgGrid. The data will be accessible in most AgGrid callbacks for example cell renderers, editors's render callback and in your case getRowStyle callback
const sickDays = // data from external component
const color = // data from external component
<AgGridReact
getRowStyle={(params) => {
const { styles, data } = params.context;
if (params.node.data["sickDays"] === data.sickDays) {
return { backgroundColor: styles.color };
}
return null;
}}
context={{
data: { sickDays },
styles: { color }
}}
/>
Live Demo
here is a plunkr which should give you idea to solve the problem. since i don't know much about your component hence i used two input boxes with button to set background color to row but you can use complex styles as well.
I am using api.redrawRows() since the operation we are performing needs to work on row.
I was working on a electron-react project for epub file. Right now, I am planning to make the app capable of selecting text field and highlight it.
To achieve it, I was trying to use web's Window.getSelection api. However, there are some really weird things come up like in this.
In short, I am unable to capture the Selection object. It seems like even if I log the Selection object, this object could somehow jump to something else. Also, I cannot even serialize the Selection object with JSON.stringfy. This is super surprising, and this is my first time seeing something like this (I will get empty object to stringfy the Selection object).
So how to use Window.getSelection properly under react-electron environment? Or this api will not work well for text content which is generated by react's dangerouslySetInnerHTML?
Looks like the window.getSelection api needs to toString the selected object.
const getSelectionHandler = () => {
const selection = window.getSelection();
console.log("Got selection", selection.toString());
};
Super simple textarea and button to get selection react demo
this solution might help someone, catch last selection
const selection = useRef('');
const handleSelection = () => {
const text = document.getSelection().toString();
if (text) {
selection.current = text;
}
}
useEffect(() => {
document.addEventListener('selectionchange', handleSelection);
return () => {
document.removeEventListener('selectionchange', handleSelection);
};
});
I am in the process of refactoring code from a React-Flux-Bootstrap app to Redux with Material-ui. What I would really like to do is have a form that starts with one input to begin with (i.e. title) and then be able to add multiple extra inputs by clicking on a button. These inputs will all be the same but obviously will need to be differentiated between (i.e. name).
Ideally I would like to be able to be able to enter in as many names as I want, collect them as an array and then send them back to my database. I am more concerned with actually creating the form itself and the code for collecting the inputs.
If someone could give me a quick example as to how I might start going about achieving this I would very much appreciate it!
Thanks for your time
The React "comments" tutorial has a good example of user input driving a growing list: https://facebook.github.io/react/docs/tutorial.html. You want to look at the CommentList class.
To data drive the list of form fields, you could do something like this:
getInitialState() {
return {
formFields: [{key: "one", value: "first"}, {key: "two", value: "second"}]
}
},
getOnChange(key) {
let handler = () => {
let newValue = this.refs[key].getValue()
let newState = {}
newState[key] = newValue
this.setState(newState)
}
return handler
},
render() {
return (
<Paper>
{this.state.formFields.map((item, index) => {
return (<TextField ref={item.key} key={item.key} defaultValue={item.value} onChange={this.getOnChange(item.key)}/>)
})}
</Paper>
)
}
I used a closure for onChange to demonstrate variability, but there are other ways to accomplish this.