Need assistance reading the object returned by getRowId of MaterialReactTable - parsing

I am using MaterialReactTable in my application and following the Row Selection Option as outlined at this link: https://www.material-react-table.com/docs/guides/row-selection
The table is working fine and I am able to select the row I want and it returns the correct id but returns it in the format: rowSelection = {63d19bebc764a5587a48683a: true}. I am not familiar with this format.
I have tried everything I know but am unable to parse out the id from the object.
Please provide suggestion to parse out the id or suggest changes to make this solution work.
I have tried the other methods of row selection suggested on the page (useRef and '#tanstack/react-table') and could not get either to work so would like to stick to this method as I feel it is close.
Below is the code and options I am using with the MaterialReactTable
return (
<MaterialReactTable
columns={columns}
data={data}
enableRowSelection
onRowSelectionChange={setRowSelection}
enableMultiRowSelection={false}
//getRowId={(row) => row?._id }
getRowId={(originalRow) => originalRow._id}
initialState={{ showColumnFilters: true,
columnVisibility:
{ _id: false } }} //hide columns listed to start }}
manualFiltering
manualPagination
manualSorting
muiToolbarAlertBannerProps={
isError
? {
color: 'error',
children: 'Error loading data',
}
: undefined
}
muiTableBodyRowProps={({ row }) => ({
//add onClick to row to select upon clicking anywhere in the row
onClick: row.getToggleSelectedHandler(),
sx: { cursor: 'pointer' },
})}
onColumnFiltersChange={setColumnFilters}
onGlobalFilterChange={setGlobalFilter}
onPaginationChange={setPagination}
onSortingChange={setSorting}
rowCount={rowCount}
state={{
columnFilters,
globalFilter,
isLoading,
pagination,
showAlertBanner: isError,
showProgressBars: isRefetching,
sorting,
rowSelection
}}
/>
);

Given the format of the response, rowSelection = {63d19bebc764a5587a48683a: true}, I had originally assumed a key: value pair with the id being the key. My initial attempts to parse out the id as the key had failed. After trying a number of different options, I was able to use the Object.keys() function as follows:
console.log(Object.keys(rowSelection)); //used to view the key(s) returned
setCurrentRoom(Object.keys(rowSelection));
This code converted the id to a string in an array as follows: currentRoom = ['63d19bd9c764a5587a486836']

Related

Unable to set dynamic dropdown value in Zapier CLI trigger

I have my app in Zapier CLI. I have created a trigger to set dropdown values for a particular action step during zap creation.
The data comes like this :
{ "data": {
"account_status": {
"field_name": "account_status",
"field_label": "Status",
"field_type": "list",
"field_length": "50",
"field_items": "Active|Inactive|444|Closed",
"required": "0",
"related_module": "",
"related_field_name": "",
"join_table": "",
"join_lhs_field_name": "",
"join_rhs_field_name": "",
"related_data_field": ""
},
}
}
Here is my code:
Now I am trying to set the data for the dynamic dropdown using field_items value from the above result like this:
return responsePromise
.then(response => JSON.parse(response.content ) )
.then(data => {
const account_status_list = data.data.account_status.field_items;
const account_status_arr = account_status_list.split("|");
return account_status_arr.map(function(e){
e.id = e
return e
})
})
my input field for the dynamic dropdown trigger is:
{
key: 'account_status',
label:'Account Status',
required: false,
dynamic: 'account_status.account_dropdown.id'
}
On clicking the dropdown I get this error
Can anyone suggest where I am going wrong or what may I do to resolve this ?
David here, from the Zapier Platform team.
The issue is that Zapier expects an array of objects and you're returning an array of strings. It seems like you're trying to make an id field in your code snippet, but calling "Active".id = "Active" won't make an object.
Instead, you should change your map function to be something like the following:
return account_status_arr.map(function(e){
return {id: e}
})
The other thing you'll probably need to tweak is how your dynamic dropdown is set up. It's a period-separated string that follows the format trigger_key.id_key.label_key. The id and label can be the same key; it really depends on what data you need to send to the API (the label is just for show, the id is what's actually sent). In the dynamic field, you'll have a dyanmic property that'll be account_status.id.id.
There are docs here.

array observable with content observable and jqAutocomplete

I'm using Knockout 3 with the plugin jqAutocomplete by Ryan Niemeyer. I have a problem with this model:
var ViewModel = function() {
var self = this;
self.myOptionsObs = ko.observableArray([
{ id: ko.observable(1), name: ko.observable("item 1 o"), description: ko.observable("item label 1 o") },
{ id: ko.observable(2), name: ko.observable("item 2 o"), description: ko.observable("item label 2 o") },
{ id: ko.observable(3), name: ko.observable("item 3 o"), description: ko.observable("item label 3 o") }
]);
self.myValueObs = ko.observable();
};
ko.applyBindings(new ViewModel());
<input data-bind="jqAuto: { source: myOptionsObs, value: myValueObs, inputProp: 'name', template: 'itemTmpl' }" />
As you can see, there is an observable array and each element is also an observable.
The autocomplete don't work well. As you can see in this Fiddle, the left column has an observable array but its elements aren't observable. If you click in the left box and write something, a list of options appear.
But in the right column, you have the same, but the element's are all observable. If you click in the right box and write something, when the list appear, if you move the cursor up and down, you could see that the row 'name' gets deleted and filled with zeros.
What I have to change in my data-bind attribute?
This question is related with this question.
I have to say that this solution works ok for me. But the updated plugin don't.
Thanks !!
The jqAutoComplete plugin isn't setup to work with observable properties (although it could be enhanced to do so without much work).
For now, I think that your best bet is to create a computed that will always return a plain and up-to-date version of your options.
self.myOptionsObs.plain = ko.computed(function() {
return ko.toJS(self.myOptionsObs);
});
Sample: http://jsfiddle.net/rniemeyer/45cepL9b/
I'll try to take a look at some point about supporting observable properties. Shouldn't take many changes.

Twitter typeahead only showing some items returned by bloodhound

I'm using Bloodhound to fetch data from the database, then twitter typeahead to display the options below a search box.
Currently, the bloodhound part is finding the objects required, but the typeahead is not displaying them.
var artist_retriever = new Bloodhound({
// turns input query into string of tokens to send to database.
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
// URL to fetch information from
url: "/artists?query=%QUERY",
wildcard: '%QUERY',
// Manipulate the array of artists returned, for display to user.
transform: function(array_of_artists){
// array of artists is returned from DB.
// Put each artist into a readable string
array_of_artists = create_artist_descriptions(array_of_artists)
console.log(array_of_artists)
// Returns correctly:
// [
// { artist: "Joe" },
// { artist: "Bob" },
// { artist: "Smith" },
// { artist: "Tom" },
// ]
return array_of_artists
}
},
// turns return value into a string of results, with this 'key' before each result.
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('artist'),
});
// display:
// instantiate the typeahead UI
// https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md
searcher = $('.typeahead').typeahead(
// options:
{
hint: false
},
// datasets:
{
// Where to get data: User the bloodhound suggestion engine:
source: artist_retriever.ttAdapter(),
// Which attribute of each result from the database should be shown:
displayKey: 'artist',
templates: {
notFound: new_artist_option_template(),
footer: new_artist_option_template()
}
}
)
Update
It turns out that there's a weird bug in typeahead. It only seems to work with the "limit" attribute set to a maximum of 4. If you set "limit" to 5, the typeahead gives you nothing.
searcher = $('.typeahead').typeahead(
// options:
{
hint: false
},
// datasets:
{
// Where to get data: User the bloodhound suggestion engine:
source: artist_retriever.ttAdapter(),
// Which attribute of each result from the database should be shown:
displayKey: 'signature',
limit: 4, // This can do a max of 4! Odd.
templates: {
notFound: new_artist_option_template(),
footer: new_artist_option_template()
}
}
This issue has been solved. Please see update 2 directly.
I have reproduced this issue in this JSFIDDLE.
As you said, its a bug. You also reported that this bug goes away if you do limit:4.
Actually on my end, or in the FIDDLE, I have experienced that this issue comes when the number of results returned = value in limit.
To test this issue in the FIDDLE, do the following:
Note: Searching for 1947 returns exactly 5 rows.
When limit is set to 4:
Searching for 1947 returns 4 results.
When limit is set to 5:
Searching for 1947 returns nothing.
When limit is set to 6:
Searching for 1947 returns one 1 result - the first result.
Hence if you keep the limit set to 1 less than the actual number of results returned, then this will keep on working.
I have also submitted this issue in their github page. I will be keeping track of this issue and will keep updating this answer as need be.
Update 1:
Found a similar question on SO here. "Luciano García Bes" seems to have figured the solution. Please direct all upvotes there.
Basically he says:
It's counting the number of rendered hints before appending them, so
if the number of hints equals the limit it'll append an empty array.
To prevent this I just switched lines 1723 and 1724 so it looks like this:
that._append(query, suggestions.slice(0, that.limit - rendered));
rendered += suggestions.length;
Update 2:
This issue has been fixed on pull 1212. Closing our own issue 1312. The bug was corrected the same way discussed in update 1.

Using tablesorter custom parser only for filtering

I have a table with checkbox column for which filter is used so I can get only selected rows.
I've added custom parser for that column to use checkboxes' "checked" prop values for filtering.
The thing is that parser is added to column using 'sorter' property in 'headers' option for tablesorter initializer, so that when I click on some checkbox and trigger 'update' event, sorting is applied to checkbox column and selected rows are moved to the bottom of the table.
Is there a way to add parser to column so that it's used only for filtering, not for sorting?
UPD: I think I should clarify what I'm trying to do.
I have a custom parser for checkboxes that looks like the following:
var myCustomParser = {
id: 'myCustomParser',
is: function() { return false; },
format: function(cellText, table, cellNode, cellIndex) {
return $(cellNode).find('.checkbox-to-find').prop('checked') ? '1' : '0';
},
parsed: true,
type: 'text'
};
Then I add it to tablesorter and use in initializer:
$.tablesorter.addParser(myCustomParser);
//...
$table.tablesorter({
// ...
headers: {
0: {sorter: 'myCustomParser'}
},
//...
);
This enables filtering but sorting is also applied. I have a checkbox for selecting all rows in header cell for that column and when I click it sorting is applied and checkboxes are sorted.
This is what I use for now to disable sorting:
$table.tablesorter({
//...
textSorter: {
0: function() { return 0; }
},
headers: {
0: {sorter: 'myCustomParser'}
},
//...
);
Stub sorter practically disables sorting while leaving filter enabled. But this seems wrong. According to docs I can't use parser option for setting parser name. filter option also seems to be only for false and parsed values. I'd like to be able to do something like this:
$table.tablesorter({
// ...
headers: {
0: {parser: 'myCustomParser'}
},
//...
);
If this would enable parsing (and make filtering use these parsed values) while keeping sorting disabled, that would be great.
P.S. I've found out there's a parser for checkboxes in repo, but the question remains: how do I specify parser so that sorting is not enabled.
I am guessing that you are using my fork of tablesorter. If that is the case, setting the column to not sort does not stop the parser from processing the information in that column. Here is some information you may have missed in the documentation.
Column features (sort, filter or parsing) can be disabled using any of the methods within the associated section (they all do the same thing), in order of priority:
Disable sort (ref)
Parsing of column content still occurs
jQuery data data-sorter="false".
Metadata class="{ sorter: false }". This requires the metadata plugin.
Headers option headers : { 0 : { sorter: false } }.
Header (<th>) class name class="sorter-false".
Disable filter (ref)
jQuery data data-filter="false".
Metadata class="{ filter: false }". This requires the metadata plugin.
Headers option headers : { 0 : { filter: false } }.
Header (<th>) class name class="filter-false".
If using the "all" column external filter, the disabled column will be included in the query. You can exclude the disabled column by setting a range in the column attribute of the external filter (ref)
<input class="search" type="search" data-column="0-2,4,6-7">
Disable parsing (ref)
When parsing is disabled, both sorting and filtering are automatically disabled, and the column data stored within the cache is set to an empty string.
jQuery data data-parser="false".
Metadata class="{ parser: false }". This requires the metadata plugin.
Headers option headers : { 0 : { parser: false } }.
Header (<th>) class name class="parser-false".
Update: In your case, I would disable sorting (using any sorter methods above), then use a custom textExtraction function that targets the column containing checkboxes:
textExtraction : {
0 : function(node, table, cellIndex) {
return $(node).find('.checkbox-to-find').prop('checked') ? '1' : '0';
}
}

extjs4 grid - changing column editor per row basis

ExtJS4 grid anticipates appropriate editor (cellEditor or rowEditor) per column.
If a column's header field is dateField - date selector will be applied on every row in that column.
What I need is an editor with different field editors per row, not per column.
The Extjs3 solution is provided here - unfortunately doesn't fit in Extjs4 case.
(please check that link to see explanatory images, cause I can't post images yet)
There's also a single column solution called property grid, but again - it supports only one column and is very deviated from the standard Ext.grid component
I have tried manually changing grid editor by customizing column.field and reloading grid.editingPlugin.editor, but always get a blank rowEditor panel with no fields.
//by default rowEditor applies textField to all cells - I'm trying to force custom numberFiled on apropriate row
var numberField=Ext.form.field.Number();
grid.columns[0].field=numberField;
//destroy current rowEditor's instance
delete grid.editingPlugin.editor;
//now, upon doubleClick on apropriate cell it should reinitialize itself (initEditor()) - and it does, but is an empty panel
what am I missing here? once I delete editingPlugin.editor everything should start from the beginning like during the first time rowEditor is called, but it looses all the fields
Solution for Ext4:
I was looking for a solution for this and this guy said the property grid has this behavior.
I have adapted it to work in a clean way for me
on initComponent I declared:
this.editors = {
'date' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Date', {selectOnFocus: true})}),
'string' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Text', {selectOnFocus: true})}),
'number' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'int' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'boolean' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.ComboBox', {
editable: false,
store: [[ true, 'Sim' ], [false, 'Não' ]]
})})
};
I used these functions to help me (copied):
this.renderCell = function(val, meta, rec) {
var result = val;
if (Ext.isDate(val)) {
result = me.renderDate(val);
} else if (Ext.isBoolean(val)) {
result = me.renderBool(val);
}
return Ext.util.Format.htmlEncode(result);
};
this.getCellEditor = function(record, column) {
return this.editors[record.get('type')];
};
And finally, associate these functions to the column:
{text: "Valor", name : 'colunaValor', width: 75, sortable: true, dataIndex: 'valor', width:200,
renderer: Ext.Function.bind(this.renderCell, this),
getEditor: Ext.Function.bind(this.getCellEditor, this)
}

Resources