Any way I can make the Column headers of my #fluentui/react "DetailsList" always show at the top when scrolling down?
Is there another #fluentui/react that does it?
Thank you
This is now possible with a Sticky control, and a ScrollablePane.
Information from here:
https://developer.microsoft.com/en-us/fluentui#/controls/web/scrollablepane
First, you'll need to define a ScrollablePane around your list, and provide a custom header renderer.
<ScrollablePane scrollbarVisibility={ScrollbarVisibility.auto}>
<MarqueeSelection selection={this._selection}
isDraggingConstrainedToRoot={true} >
<DetailsList compact={true} items={items} columns={this._columns}
selectionMode={SelectionMode.multiple}
selection={this._selection}
selectionPreservedOnEmptyClick={true}
onRenderDetailsHeader={this.renderFixedDetailsHeader} />
</MarqueeSelection>
</SrollablePane>
Then you'll need to provide a header renderer (onRenderDetailsHeader), like this for example
private renderFixedDetailsHeader: IRenderFunction<IDetailsHeaderProps> = (props, defaultRender) => {
if (!props) {
return null;
}
const onRenderColumnHeaderTooltip: IRenderFunction<IDetailsColumnRenderTooltipProps> =
tooltipHostProps => (
<TooltipHost {...tooltipHostProps} />
);
return (
<Sticky stickyPosition={StickyPositionType.Header} isScrollSynced>
{defaultRender!({
...props,
onRenderColumnHeaderTooltip,
})}
</Sticky>
);
}
Hey Presto!
Related
I want to use the same logic when I press the APPLY button but with the ENTER key.
How do I do that?
filterParams: {
closeOnApply:true,
buttons: ['reset', 'apply'],
values: parentCampaignAndNodes.PaymentGroups
},
As you might have found out by now, you can remove the Apply button (by setting filterParams: { buttons: [] } in your column definitions) and then values are submitted onchange.
The solution you ask for is indeed still not available through the AgGrid API. I do have a workaround, but beware it uses direct DOM bindings which is not recommended when working with React.
const applyFilterOnEnter: AgGridReactProps['onFilterOpened'] = ev => {
const inputElem = ev.eGui.querySelector('.ag-filter-body .ag-input-field');
const applyButtonElem = ev.eGui.querySelector('.ag-filter-apply-panel button[ref=applyFilterButton]');
if (inputElem && applyButtonElem) {
inputElem.addEventListener('keydown', keyEv => {
if ((keyEv as KeyboardEvent).key === 'Enter') {
(applyButtonElem as HTMLButtonElement).click();
}
});
}
};
return <AgGridReact
onFilterOpened={applyFilterOnEnter}
/>
I have a FieldArray, and I want to change one of the Field's component type when adding a new line of Fields for it ( this.props.array.push("xxx", { obj })).
For example, I have a value named summaryNo.
When summaryNo === 0, I want the Field became a Picker. Else, as a simeple input Field.
Is that possible? I gave a try like the below codes:
export const renderInputOrPicker = ({ input, label, children, ...custom) => {
if (input.value instanceof Array && input.value[0] === "toBeAPicker") {
return (
<Picker mode="dropdown" {...input}
selectedValue={input.value[1]}
onValueChange={(value) => {
setTimeout(() => {
input.onChange(value);
}, 10);
}} children={children} {...custom} />
);
} else {
return (
<Item regular>
<Input {...input} />
</Item>
);
}
};
Any suggestion?
Thanks.
I thought I have figured a way out. I just don't need the input Field. What I want to do is to have a Field that can display "true" or "false" and can be controlled by the disable status.
The Picker Field can do that already. Which means I can let it read-only or editable and showing the current value.
All in all, I am still looking for the answer, a better solution for this redux form scenario!
Thanks.
I'm trying to implement this with elasticsearch and it is working But how i can force this show results which can be different from the searched terms? For example i search ardino, The elasticsearch give me the word arduino but then react-select does not show that result because ardino does not contain arduino. I know the idea of this library is exactly that and it is working ok, but i have most of the things already implemented and it is only missing that part.
The handle is giving the right behavior and it is populating the options correctly.
Thank you
<Select
name= {this.state.selectedOption}
value={this.state.selectedOption}
isSearchable={true}
onChange = {(val) => {
this._handleSearch(val.value)
}}
onInputChange = {(val) => {
this._handleSearch(val)
}}
options={this.state.options}
/>
I would recommend using the Async component which can simplify your code. You will not need the onChange handler anymore.
isSearcheable is true by default, no need to specify.
In answer to your question: Make sure you are passing in label and value keys with each result option. If you want to customize any of the results, for example adding the search term in the results, you can manually manipulate the options array.
import React, {Component} from 'react';
import AsyncSelect from 'react-select/lib/Async';
class Search extends Component {
state = {inputValue: ""}
onInputChange = (inputValue) => {
this.setState({ inputValue });
};
getSearchResults = async (inputValue) => {
// elastic search results
let options = await fetch(`searchElastic/${inputValue}`);
// input value of drop-down
const inputValue = this.state.inputValue;
// manually add input field as an option in drop-down
if (inputValue.length > 0)
options.unshift({label: inputValue, value: inputValue})
// async handling of new props
return options.map(opt => {
return {label: opt.name, value: opt.value}
})
}
render() {
return <AsyncSelect
onInputChange={this.onInputChange}
loadOptions={this.getSearchResults}
/>
}
}
export default Search;
In my React Native project using NativeBase I'd like to generate a series of Buttons or TouchableOpacities.
That means I don't want each to have a separate onPress handler but one shared one.
But when I look at what is passed to the onPress callback there doesn't seem to be any kind of ID or reference to the component that caused the press, nor can I find such a thing documented.
Am I missing something obvious? Is there another method everybody uses to achieve the same goal? Or is this actually missing functionality?
You can use your function as below:
_onPressButton = (id) = () => {
// do something with id
}
_keyExtractor = (item, index) => index;
_renderItem = ({item}) => (
<Button onPress={this._onPressButton(item.d)}>
...
</Button>
);
return (
<FlatList
data={data_array}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
);
You can try to use ref to identify a component
<Button ref={'loginButton'} onPress={this.onButtonPress()}>
Then you access it using this.refs['loginButton']
Hope it helps.
I see in CKEitor 4.5 there is a new drag and drop system. I would like to drop external DIVs or SPANs into my CkEditor and have them turn into "placeholders" "fake objects" or "protected source" objects. I.e., the dropped object should turn into arbitrary HTML that's related to the content.
The available demos seem to be about uploading content, but this is different and I'd appreciate a demo ...
Yes, it is possible. CKEditor 4.5 is in the beta phase at the moment, what means there is no tutorials yet, but here is sample how to do it.
First, you need to mark your data on dragstart. You can simple set text:
dragstart( evt ) {
evt.dataTransfer.setData( 'text', 'foo' );
} );
But then you need to make your text unique, otherwise every time someone drop foo it will be recognize as your container.
I prefer to use CKEditor data transfer facade, which let you use custom data type on every browser (including IE 8+):
dragstart( evt ) {
var evt = { data: { $: $evt } }; // Create CKEditor event.
CKEDITOR.plugins.clipboard.initDragDataTransfer( evt );
evt.data.dataTransfer.setData( 'mydatatype', true );
// Some text need to be set, otherwise drop event will not be fired.
evt.data.dataTransfer.setData( 'text', 'x' );
} );
Then in the CKEDITOR you can recognize this data and set your html to be dropped. You can replace dropped content whit whatever you need. Simple set text/html data in the drop event:
editor.on( 'drop', function( evt ) {
var dataTransfer = evt.data.dataTransfer;
if ( dataTransfer.getData( 'mydatatype' ) ) {
dataTransfer.setData( 'text/html', '<div>Bar</div>' );
}
} );
You can find working sample here: http://jsfiddle.net/oqzy8dog/3/