Tabulator - custom cell editor not fully opened - reactjs

The requirement is to have 'inline editing' of some cell in Tabulator based table.
The cell requires a custom editor since the input is a custom component (which is already used in another form, outside of Tabulator).
Our environment is React + Tabulator (v4.7) + BlueprintJS as the components library.
The problem is that the component won't fully open as a custom editor in Tabulator, while working fine outside of Tabulator, in a regular form.
Why the component won't fully open?
The custom component serving as the 'editor' for this cell is using Blueprint (BP) 'popover' so it has a popover target and a content. This is how it looks like in a form edit:
The problem is that upon clicking, the popover target is being rendered but the popover content is not, so the custom 'dropdown' input component is never appearing:
Relevant code sections
Tabulator column definition:
{
title: "Some Col Title",
field: "someField",
formatter: someFieldFormatter,
editor: "someFieldEditor" as Tabulator.Editor,
editorParams: (cell) => {
return { cell, zones: zonesDataTree };
},
},
Defining custom cell editor:
Tabulator.prototype.extendModule("edit", "editors", {
someFieldEditor: (
cell: CellComponent,
onRendered: Function,
success: Function,
cancel: Function,
editorParams: SomeFieldCellEditorParams
): Element => {
const elem = document.createElement("div");
// SomeFieldCellEditor is a React component that wraps around the same component used in
// the "regular form" scenario mentioned in the screenshot
const someFieldCellEditorComponent: any = React.createElement(SomeFieldCellEditor, {
theData: editorParams.data,
});
ReactDOM.render(someFieldCellEditorComponent, elem);
return elem;
},
});

This is happening because the element is contained inside of the cell.
To prevent corruption of the table layout, tabulator cells have overflow:hidden defined on their CSS.
Most dropdown libraries have a an option that lets you set where in the DOM the list should be appended. You can use this potion to append the list to the body tag which should resolve the issue.
On a side note, did you know that Tabulator comes with built in Select and AutoComplete Editors

Related

Ag Grid partial cell formatting - e.g. how to have some text in a cell styled - bold, italic, colored (but not other text)

In a simple HTML table, if I want to apply text formatting to a portion in a cell, such as:
<td>Qty: <b>5</b></td>
It's very simple to make part of the text bold, and part of it not. I've looked through a bunch of Ag Grid docs, and I'm not seeing a simple way to do that.
(I'd prefer not to need a cell renderer component for this; just a simple method using a value-formatter.)
Here's some of what I've looked at, but it doesn't provide such:
https://www.ag-grid.com/javascript-data-grid/cell-content/
https://blog.ag-grid.com/conditional-formatting-for-cells-in-ag-grid/
https://www.ag-grid.com/javascript-data-grid/value-formatters/
I'm hoping there's a way like:
valueFormatter(params) {
return 'Qty: <b>' + params.value + '</b>';
},
But I've tried that, and it doesn't interpret/format using the HTML tags.
Value formatter can do only string formatting. You have to use cell renderer, as described in the docs. For example:
myRenderer.jsx:
export default props => {
const cellValue = props.valueFormatted ?? props.value;
return (
<span>Qty: <b>{cellValue}</b></span>
);
}
gridComponent.jsx:
import MyRenderer from './myRenderer.jsx';
/* ... */
<AgGridReact frameworkComponents={{ myRenderer: MyRenderer }}>
<AgGridColumn field="qty" cellRenderer="myRenderer" />
</AgGridReact>
I found a way to do this; it uses the cellRenderer, but does not require a separate component - it can be defined directly from the columnDefs:
{
field: 'ItemID',
headerName: 'Item ID',
cellRenderer: params => `<b>ID:</b> ${params.data.ItemID}`,
},
This lets you provide minor selective formatting directly within the columnDefs, without needing to create a separate relatively mundane component for each field. Makes the code shorter, faster to write, and easier to maintain.

Is there a way to add new tab in WordPress Gutenberg editor

I am completely new to Gutenberg and I need to add a new tab in the setting section Please check this screenshot
I Have created some blocks for Gutenberg but no experience in this. I tried this code
import { TabPanel } from '#wordpress/components';
const onSelect = ( tabName ) => {
console.log( 'Selecting tab', tabName );
};
const MyTabPanel = () => (
<TabPanel className="my-tab-panel"
activeClass="active-tab"
onSelect={ onSelect }
tabs={ [
{
name: 'tab1',
title: 'Tab 1',
className: 'tab-one',
},
{
name: 'tab2',
title: 'Tab 2',
className: 'tab-two',
},
] }>
{
( tab ) => <p>{ tab.title }</p>
}
</TabPanel>
);
But didn't help me. Anyone here please help me.
Thanks in advance
In the screenshot you provided, the location you are attempting to add a tab to is the Settings Header
(gutenberg/packages/edit-post/src/components/sidebar/settings-header) for which there is not currently a slot in the Gutenberg API to extend from (although this could potentially be done, it's best to not interfere with core UI).
The prefered method to add to the Admin UI is to use an provided SlotFill for custom content, currently there are:
PluginBlockSettingsMenuItem
PluginDocumentSettingPanel
PluginMoreMenuItem
PluginPostPublishPanel
PluginPostStatusInfo
PluginPrePublishPanel
PluginSidebar
PluginSidebarMoreMenuItem
The PluginSidebar slot is useful for adding custom content that is specific for your plugins/blocks purpose. The main point to consider is whether the content you wish to add applies just to your block, the post/page as a whole or is some other 'global' setting to do with a plugin.
If your content applies to the whole post/page, the PluginPostStatusInfo slot may be a good location to add to. You could also add your own Panel that appears underneath the "Document" tab.
If the content is block-specific, then you can use the to add custom controls underneath "Block" tab that contextually show when your block is selected. This would also be a good place for meta field values that are specific to the block or custom controls for colors/display options related to your block.
The official WordPress Gutenberg documentation also has a tutorial on Block Controls: Block Toolbar and Settings Sidebar which walks through some common scenarios for adding your own settings in Blocks.

ReactJs Material-Table How to show/hide filter options

I am using material-Table plugin for my reactJS application to display table of data.
I have requirement to show the filtering on column. But when I enabled filtering=true then it creates one more row on Header section below the heading. Which takes unnecessary space and its shown always.
I want to hide the filter section. Maybe I show the filter icon next to column and when clicked it show the filtering text line. I saw this option is on tubular-react tables. But can I do in with material-table?
Its not supported out of the box, but if you save the filtering state in a useState and set that to true update the table, like this:
function Table(){
const [filtering, setFiltering] = React.useState(false);
retrun <div>
<MaterialTable options={{filtering}}/>
<button onClick={() => {setFiltering(currentFilter => !currentFilter)}}>Show Filtering</button>
</div>
}
So the solution came out like below. (I am using class)
In Material-table, need to add a button for filter. which will toggle the filter section.
Also add the options={{Filtering: this.state.filter}}. We also need to define a small function to toggle the flag.
options={{Filtering: this.state.filter}
actions={[
{
icon: 'filter',
tooltip: 'Enable Filter',
isFreeAction: true,
onClick: (event) => { this.functionName(!this.state.filter)}
}
]}

How do I get the buttons in an Ext.FormPanel?

I cannot see to get the buttons from an Ext.FormPanel defined like this:
Ext.apply({
....
buttons: [
{
text: 'Save',
itemId: 'btnSave'
}
]
});
I've tried getComponent on the FormPanel instance, but that doesn't return btnSave. Is btnSave on a different element than the rest of the form?
You can't use getComponent() because the buttons are not part of the items config.
getComponent() - "Examines this container's items property and gets a direct child component of this container."
You could give the button an id and then use Ext.getCmp() or use component query as #limscoder shows.
You should be able to use the container's "query" method to retrieve descendant components:
panel.query("#btnSave")
In Extjs 4.2, I had similar code to yours with buttons at the bottom of a window.
This worked for me:
var bbar = this.getDockedItems('toolbar[dock="bottom"]')[0];
var button = bbar.getComponent('btnSave');
The toolbar and items are not in your code but they are implied with buttons:[{}]

Ext Js Radio button with input text in its label

In ExtJs I would like to achieve the equivalent of:
<input type="radio"><label><input type="text"></label>
Where the input box is associated to the radio button.
new Ext.form.RadioGroup({
id:"alerts",
items: [
new Ext.form.Radio({
boxLabel:'Now',
}),
new Ext.form.Radio({
boxLabel:'On',
})
]
);
I would like the "On" label to have a Ext.form.TextField next to it.
I have tried adding a Ext.form.TextField to the RadioGroup but it will not show (as I assume its because its not a Radio) and I am unable to add items to the Radio object.
Any advice apprecaited, thanks.
Add an <input/> element in the boxLabel, then on the RadioGroup render event create a TextField and apply it to that element
new Ext.form.RadioGroup({
id:"alerts",
items: [
{boxLabel: 'Now',},
{boxLabel: 'On <input id="on_date" type="text"/>'}, // contains <input/> id is "on_date"
],
listeners: {
change: function() {
// really, check if "on" was clicked
if(true) {
Ext.getCmp('on_date_field').focus();
} else {
// otherwise, disable the field?
}
},
render: function() {
new Ext.form.TextField({
id: 'on_date_field',
applyTo: 'on_date', // apply textfield to element whose id is "on_date"
});
}
}
});
I've confirmed that this works with TextField, and although I haven't tried it, it should work with DateField or ComboBox too. Also untested, but instead of creating an <input/>, you could create a container element and create the TextField and renderTo that element.
I don't think that's possible unless you override the RadioButton class and change its rendering logic (and I think that would be more complex than you would think to make a textfield render correctly the way you proposed). A better approach would be to simply add the radio and the textfield as two separate fields and link them programmatically. In Ext 3.2 you could use a CompositeField to do this easily. In the radio's handler fn you can set focus to its associated textbox or whatever other logic you'd need.

Resources