Help

Re: Javascript window.open()

2699 4
cancel
Showing results for 
Search instead for 
Did you mean: 
Daniel_Melnechu
6 - Interface Innovator
6 - Interface Innovator

Dear community,

I’m working on making a simple interface using a table with one record where each field is a button field. The button for a field runs an app script to do something. For example, create a new record in a particular table.

For the script that creates a record in table NNN, i’d like the script to tell the browser to switch to that table with a particular view that is set with a filter that will be showing that newly created record.

I have searched high and low as to how to get an app script to do my bidding. I ran into someone saying that all you can do is to output the URL you create and tell the user to click on that URL.

I tried adding code to use window.open(myURL, _self) but the editor says “Cannot find name ‘window’.(2304)”. So the “window” object is not accessible from scripting app.

I tried to see if anything, base, table, view, had window as a member. No love.

How can this be? I have a URL that will open (and does if you output it from the script so user can click on it) and the script i am running can’t tell to open it directly? What is the logic behind that?

Or am i missing something? I am fairly new to AT scripting but have got it mostly down as far as the model and environment so i can get down whatever i need to do. And have learned a lot from the awesome sharing of you all. Thank you.

So if anyone has a clue as to how i can open a URL programmatically from a scripting app, i’d be most interested in hearing how you do it.

Stay safe,
Dan

12 Replies 12
Daniel_Melnechu
6 - Interface Innovator
6 - Interface Innovator

My apologies, i thought i could output the URL in the script and someone could click on it. I found somewhere in the community forum how to do that, but lost the reference. So i’m still trying to make that work. I’ll be back to confirm.

Ok, was as simple as using output.markdown(theURL) and the script output now shows a clickable link. Click on it and it opens the table and the correct view. With “?blocks=hide” appended the blocks are hidden. It does open a new tab.

They do mention as much in the Script App documentation – that the DOM API’s from JavaScript are not accessible:

CleanShot 2021-01-14 at 14.27.21

Admittedly, it sounds bad, but there are reasons.

At the outset, in the script block, the DOM is off-limits. In fact, for much of the script block feature, many things are not accessible. For instance, events in the tables - it would be ideal if you could subscribe to events in a script block to understand the user’s context and interest to build better blocks.

In the Blocks SDK, it’s a completely different story. You can subscribe to events and pop open a record and do many things that you might expect. Why is this the case in custom [blocks] apps and not in script blocks? Pretty simple - custom blocks are sandboxed and needn’t work in a sanitized environment. They are separate apps from Airtable itself, whereas script blocks are like formulas - they run right inside Airtable so they have to be cautious about what they allow you to do. Otherwise, within minutes, you see Chinese and Russian characters in your data and the photo attachments would likely be quite annoying.

Have you played with the Blocks SDK? Here’s an example custom app I created that integrates MapBox and Vega-Like. And below is a search engine that watches how users are working with data and always refreshes along with location data in context to the record focus. As users select orders, the search engine locates all of the nearby partners, ranks according to historical services, and pinpoints them on a map in relation to the sales order.

image

Clicked search hits open records - all made possible by the Blocks SDK.

image

Thanks Jeremy. I missed that. But then again, i wasn’t trying to do what i am doing when i started scripting with script app.

Hi Bill,
Thanks for pointing me to Blocks SDK for custom apps. Buttons do allow you to call a custom app, so if i can create a new record in a table, and then use window.open() on the URL table/view i generate, sounds like way to go.

I’ve been programming for longtime. Just looked at the Blocks SDK. There is an example template “URL preview” which looks like a place to start.

Just updated homebrew and installed node (w/npm). Then had to uninstall node, as it was version 15 and you need version 14 (that AT doesn’t mention) but found help in this fine community. Then added the Blocks npm. (see Hello World Errors with Blocks-CLI - #7 by somehats)

Added first custom app in AT, using the “URL preview”. That is working. Now to edit the Custom app to see if i can get it to do what i want.

If you have any pointers for someone at this stage in custom apps, would love to hear them!

Peace,
Dan

Daniel_Melnechu
6 - Interface Innovator
6 - Interface Innovator

Hi Bill and anyone else,

So i went with the Hello World app and learned what i needed to get an almost working solution. This is my first foray into Node, React, and Custom Apps. I am obviously missing an architectural aspect which i will go back and try to figure out but thought i would paste my almost working solution in case there is an obvious pointer someone can make to where i need to read or learn or tweak.

So the custom app below works up until i added the window.open() call. What it does is make a new record in a table setting two fields to values. Yes, this could be done in a Scripting app… and i had that already. But the concept to move to Custom app was as per Bill’s suggestion above that in Custom app you can have access to the whole DOM. And as such call window.open(). Which i want to do to have the browser go to a particular View in the Table where i just created a record so that user sees the new record there and go edit it. Can’t do that in Scripting app.

If you comment out the window.open() call, the Custom app below makes the record in the table. If you uncomment the window.open() call the record is NOT made in the table, but the browser is redirected to the correct View on the correct Table. And i see for a quick flash that looks like an error output in the Blocks view before it goes away and browser takes you to the View.

Like i say i know i am missing something about the architecture of React and Custom app environment. But i don’t know what that is.

I had to define the createRecord() function as:

async function createRecord(table) 

since there is a call to table.createRecordAsync() and i want to await it. At least that is what i read somewhere. I could not find an equivalent table.createRecord() NOT async that would wait for the return.

Enough said. Below is the code. Thanks in advance for any pointers.

Peace
Dan

import {
initializeBlock,
useBase,
} from ‘@airtable/blocks/ui’;
import React from ‘react’;

function HelloWorldApp() {

const base = useBase();

const table = base.getTableByName('ROLODEX');
const view = table.getView("New Entry Today");

createRecord(table);

const theURL = "https://airtable.com/" +  table.id + "/" + view.id + "?blocks=hide";
// window.open(theURL, "_parent");

return;

}

async function createRecord(table) {
const first = “First”;
const last = “Last”;
const newRecord = await table.createRecordAsync( {‘First’: first, ‘Last’: last});
}

initializeBlock(() => );

I just turned off the “?blocks=hide” at the end of the URL and i can see the error better… something about disconnect? It is too fleeting. Wait… caught it with my iPhone camera… it says:

Error: Disconnected from development server
pollForLiveReload/</<@htpps://localhost:9000/__

Well that is a clue. Will look into that.

It sounds like the basic process is there and working. Now it’s time to decide how to render the final step - the editing of the record. In the earlier part of this thread, I was speaking broadly about DOM access, but in the new context of a custom app, you have even more helper functions that can simplify your app.

Take a look at this - expandRecord(). It provides everything you need with a single function call in the SDK.

For example… here’s an app I was working on today:

image

The variable thisPartnerRecord is a record in a table. Passing it to expandRecord() and we see this:

By leveraging the SDK methods, you can avoid dealing at all with the DOM and focus on the solution.

But why doesn’t window.open() work? I don’t know for sure because I try to avoid popups and popouts because browsers play a lot of tricks on you that you cannot anticipate. However, I think it’s because in React, you need to build such popups as components - it’s not the same as everyday freewheeling HTML and javascript.

Hi Bill! Thanks for pointing out that feature i think i will be using moving forward as i slowly get my custom app world happening. Maybe even adding it to my bare bones solution that creates the record and opens the view i want to show the new record.

I realized i should try the different window.open() target attribute. So changing to “_blank” almost worked in that the custom app made the record. But would still get an error, but a new error that said something to the effect if not rendering anything, then should return null. Which from my reading more about React is making sense.

Changing the return line to:

return null;

and the window.open() line to:

window.open(theURL, "_blank"); // Yes record and goes to view NO error!

i now have a working solution.

Thanks for all the help and pointers. You rock.

Peace,
Dan

Well i spoke too soon. I did “block release”. Installed the custom app into a workspace, and immediately it ran, created a new record, and then went to the View.

When i went to my Table “Buttons” that has buttons to run my various make new records scripts i am making for the user, and selected the workspace that had the freshly installed custom app, it ran again.

So my model of the world needs help. I know i am trying to fit a function based model into an interactive model, but just opening the Apps area and displaying the workspace with this custom app in it cranks it up. Looks like some more studying to be done,

So i had to comment out the createRecord call and comment the window.open call and change “return null” to “return

hi
”, then block release to install essentially a null custom app so i could open the Apps area to work on stuff.

I guess if add a dialog to have the user confirm making a new record or not. But would just opening the Apps area invoke it every time? Not a workable solution.