Trying to build a custom widget, but can't figure out how to handle data

hi,
i’m trying to build a widget that can return a record base on a html form input, but i’m stuck on first step: i don’t know how to grist custom widget’s function, and i don’t even know which function to return an array, please can some one give me a clue?

I’d be glad to help but I don’t quite get what you’re trying to do. You want to build a form that creates records…? Could you add some details?

thanks for your reply,
i’m building a custom widget,which do one thing:find a record that match the input from a html form, and then render the result to an empty html table, so my first approach is try to pull all record in array and then store it into a variable, but i don’t know which grist function could pull all record in array.

I see, thanks for the input. You’ll need to look at these methods from the plugin API:

Both methods return the data as a dictionary keyed on column name and with the individual records represented as an array for each column. So it’ll look like this:

{
   id: [1, 2, 3, 4, 5],
   your_column: ["the value for record 1", "the value for record 2", ...etc]
   etc: ...
}

Also note that the docs for docApi.fetchTable() say: Do not modify the returned arrays in-place, especially if used directly (not over RPC). I’m not sure this warning means anything in your case, but if you intend to have your JS modify returned values in any way, you might consider making a structuredClone() of them first just to be safe.

Hope this helps. Good luck with your widget, and please do post it here (on the showcase forum) when you’re done! :smiley:

do you need a custom widget for that? To return an HTML form input, I suppose you can simply use a formula with HTML in a column and read that column with the HTML Widget.

It seems to me he wants to create a custom search mask before outputting any matching records as HTML. For the former, a custom widget certainly makes sense, doesn’t it?

thanks you guys for the help!
little update for the widget:
I’ve tried grist.onRecords()method like this

grist.onRecords((records) {

      let json1 = JSON.stringify(records);
      let arr1 = JSON.parse(json1);
      let str1 = arr1;
document.getElementById("demo").innerHTML = str1;
}
);

which return multiple [object Object], i guess it does return table data but it’s a multidimensional associative array, I have to go deeper so I can get a single record, so I changed the code to:

document.getElementById("demo").innerHTML = str1[0];

return one [object Object], change again to:

document.getElementById("demo").innerHTML = str1[0]["F"];

return the element of a record, so that’s one problem gone, and now I’m stuck on how to use the array, because it seems the onRecord function on works when the widget first load and when a records changed, I tried to do this:

let arr2 = [ ];
grist.onRecords((records) {
  let json1 = JSON.stringify(records);
  let arr1 = JSON.parse(json1);
  let str1 = arr1;
  arr2.push(str1);
}
);
document.getElementById(“demo”).innerHTML = arr2[0]["F"];

which return nothing, I’m still working on that

tried the grist.docApi.fetchTable() method, in the documentation it said return a promise, so i tried:

  grist.listTables(Table1).then(function(result) {
    document.getElementById("demo").innerHTML = JSON.stringify(result);
  });

return nothing, still working on it.

Yeah these are all async methods. Just do something like:

/*This will get a list of all table
names in the Grist document*/
let tables = await grist.docApi.listTables();

/*This will get all records from the table
called 'X', in the format I mentioned above.*/
let all_records_of_table_X = await grist.docApi.fetchTable('X');

Best of luck!

thanks for all you guy’s help,
now i can print out all the records from a table, but i still can’t use array find method to search the record i want to show, i think it’s because grist.docApi.fetchTable('X') returns a promise object, i can use JSON.stringify() to print all records, but when i try to array.find() it, it show :Uncaught (in promise) TypeError: arr1.find is not a function

async function genPermit() {
  const genAllRecords= grist.docApi.fetchTable('Table1');
  let json1 = JSON.stringify(genAllRecords);
  let arr1 = JSON.parse(json1);
  let ans1 = arr1.find ((ans2) => ans2.A == "YSHQ/PP/1278");
  document.getElementById("permitGen").innerHTML = ans1;
}

i’m still looking for a way to deal with promise object.

Daniel, no offence but I think you need to actually read what we’re writing. My last post stated clearly that you need an await before the call to grist.docApi.fetchTable(). That will solve your problem.

if this was my thread, I would answer that you are speaking like Chinese to me, and that it’s ChatGPT blame for not using the “await” before the call. :laughing:

sorry I wasn’t notice that I didn’t use await
in my code :sweat_smile:, I just started to learn javascript because of this widget, so everything is kinda new to me, i’m still on MDN looking for the different functions works, thanks for all you guys help, will try your advice in further developments!

Sorry if I sounded a bit cross, that wasn’t intended. :slight_smile: Just keep trucking, you’ll get the hang of it!