Initial commit

Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: Michael Cartner <32543275+michaelcartner@users.noreply.github.com>
This commit is contained in:
Eric Tuvesson
2023-09-05 12:08:55 +02:00
commit 53f0d6320e
2704 changed files with 76354 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
---
title: Google Sheets Module
hide_title: true
---
# Google Sheets Module
The Google Sheets Module makes it easy to read data from publich Google Sheets. Use it for example to use Google Sheets as a CMS system or a read-only data repository. There are three nodes included, [Query Sheet](/library/modules/gsheets/node-docs/query-sheet), [Query Sheet Aggregate](/library/modules/gsheets/node-docs/query-sheet-aggregate) and [Sheet Row](/library/modules/gsheets/node-docs/sheet-row).
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/suatch-1.png)
</div>
The module will interpret a Google Sheet as a giant table meaning the first row encountered in the sheet will decide the names of the columns, and then each row will contains values for those columns in its cells. Empty rows and columns will be skipped.
?> Note that the Google Sheet need to be made publicly available for the module to be able to access it. Also, the module is read-only, i.e. you cannot write data to the Google Sheet.

View File

@@ -0,0 +1,539 @@
---
title: Google Sheets Filtering
hide_title: true
---
# Google Sheets Filtering
## What you will learn in this guide
This guide will look at how we can apply filters to our Google Sheets data and use that in our example app.
## Overview
If you haven't already followed the previous guides for the Google Sheets Module, it's recommended to do that before starting this guide. You can find them [part 1 here](library/modules/gsheets/guides/setting-up/ and [part 2 here](/library/modules/gsheets/guides/park-details).
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/filter-view.png)
</div>
We will go though the following steps:
- Creating a visual filter component.
- Using the Query Sheet Aggregate node to pull out specific data from different columns in the Google Sheet and then ause that data to populate a Dropdown node and Slider that will be used for filtering.
- Creating filters on the Query Sheet node.
## Creating the visual Filters component and adding it to the App component
Let's first create a new visual component that we will call Filters.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/filter-comp.png)
</div>
To begin with we will style the Group node in the Filters component like this:
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/filtering/filter-group-props.png)
</div>
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/filtering/filter-group-props-2.png)
</div>
We will soon get back to building out this component, but before we do that, let's add some functionality and visuals in the App component so that we can bring up our Filter component. The first thing we will do is to add a Button. Let's call it Filter Button.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/filter-button.png)
</div>
Then let's style the button. We will remove the label and use an icon for the button just like in the images below. It's important that the Button's Position property is set to Absolute. That way we get it to float on top of our Park Details view.
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/filtering/filter-button-props.png)
</div>
Now that we have a button, let's add an area for our Filters component. Let's add a Group like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/filter-group-add.png)
</div>
This Group has a bit of styling, and again it's important that the Position is set to Absolute so that it will be on top of our Park Details. Here's the actual styling for the Group.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/app-filter-group-props.png)
</div>
Let's add our Filters component as a child to the Group. The visual node tree in the App component should now look like the first image below, and your preview should look something like the second image.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/app-tree-filters.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/preview-initial-filters.png)
</div>
## Hiding and Showing the Filters component
We don't want the Filters component to always be visible, it should only show when you click the Filter Button, and then if you click the Filter Button again, it should hide. We can easily add this functionality by using a Switch node, and hook it up like below:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/switch.png)
</div>
Now, when you click on the Filter Button you should alternately hide and show the Filters component.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/show-hide.gif)
</div>
## Finishing the visuals for the Filters component
Let's select the Filters component again and finish building the visuals. The idea is that we should be able to filter the list of national parks based on which state they are in and/or what size they have. A Dropdown node would be a good pick for a UI element to select a state from, and to choose a size, a Slider node would be good to use. Add nodes to the Filters component so that you have a visual tree that looks like the image below. We will go through each node and it's properties next.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/filters-visual-tree.png)
</div>
The Dropdown node that we will use to select which state to filter on has been styled as below:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/dropdown-props.png)
</div>
Next we have a Group node that holds two text nodes. The Group has been named Slider Info and it has the following styling:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/slider-info-group-props.png)
</div>
The two text nodes that follow have slightly different styling from each other. The first one is a Label for the Slider and it has the following styling:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/slider-label.png)
</div>
The second Text node that will hold the Current Slider Value looks like this:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/slider-value.png)
</div>
Lastly we have the Slider node where we have only changed the padding a bit:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/slider-props.png)
</div>
## Using Query Sheet Aggregate nodes to set the min and max value of the Slider
The Slider component will be used to set a number that we want to be between the smallest sized national park and the largest sized national park. In our Google Sheet we have a column for size so it would be cool if we could figure what the smallest and largest number is in this column. This is where the [Query Sheet Aggregate](/library/modules/gsheets/node-docs/query-sheet-aggregate) node comes in. This node is used to do aggregate data queries on a column from a public Google Sheet which is exactly what we are after here.
Let's first add a Query Sheet Aggregate node to our Filters component, and fill in the following properties:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/aggregate-1.png)
</div>
As you can see we need to tell the node which Google Sheet document it should look at (Document Id: 1gjttBIT4bHGFS8ynF31DoYw143ZY3UAiwopAW0N97KQ) and which sheet in that document we are interested in. Once the node has that information it will present a list of all the columns that the specific sheet has. Here we want to pick the Size (km2) column, and then we can choose how we want to aggregate the data of that column. We want to set up a Slider with a minimum and maximum value, so let's select Max to get the maximum value of the Size (km2) column.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/aggregate-column-choice.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/aggregate-max.png)
</div>
Then we connect it to the Slider like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/aggregate-slider-connect.png)
</div>
Now we need another Query Sheet Aggregate node to get the minimum value so let's add one and set it's properties as follows, and also hook it up as in the second image:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/aggregate-min-props.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/aggregate-min-connected.png)
</div>
Now the Slider has it's min and max value set, so let's now make sure that we show the current value of the slider in our Current Slider Value Text node. It would also be nice to show that the number is in km<sup>2</sup> so we will add a String Format node and set it up like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/aggregate-string-format.png)
</div>
Then let's connect everything like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/current-slider-val-connection.png)
</div>
The reason we hook up the result from the Query Sheet Aggregate - Min Size, is so that we show the initial slider value when we first open up the Filters component. The Value output from the Slider only updates as we interact with the Slider so the initial value needs to be set from the Query Sheet Aggregate - Min Size.
## Getting a list of all states
Now that we know how to use the Query Sheet Aggregate node, let's use it again, to get a list of all states that are in our Google Sheet for US national parks. This time we will set the Aggregare property to unique which means the node will return an array of all the unique values from the states column.
?> Note that some parks span two states, e.g. the Great Smoky Mountains are in both North Carolina and Tennessee. We have chosen to treat North Carolina, Tennessee as it's own option in the states list. A different solution would be to have two entries for Great Smoky Mountains, one for each state it's in.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/states-aggregate.png)
</div>
Let's connect it to our Dropdown node, and then click on the Dropdown list in the preview.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/states-dropdown-connection-1.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/states-dropdown-preview.png)
</div>
This looks pretty good, but there is one problem. There is no option for selecting All states which is the initial state of our list. To solve this, we need to add another option to the array of states.
## Adding All option to states Dropdown
The result we get from the Query Sheet Aggregate - States is an array of items, so let's create a new Array and call it AllStates and then connect the result from Query Sheet Aggregate - States to the Items input of the Array:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/allstates-array.png)
</div>
Next we want to use a Create New Object node to create a new object that we can then insert into the Array. Set up the Create New Object node like below and then we connect it like in the second image.
<div className="ndl-image-with-background">
![](/library/modules/gsheets/guides/filtering/new-object.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/new-object-connected.png)
</div>
Now that we have a new Object, we want to insert it into our Array and we do that with an Insert Object Into Array node. Connect everything like below:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/insert-new-object-connected.png)
</div>
Our AllStates Array contains one extra option, the All option. Before we connect it to our Dropdown, let's make sure that the Array is sorted alphabetically, so we will connect an Array Filter node like in the image below. Here it's important that we use the Done signal from the Insert Object Into Array node, to tell the Array Filter to do the sorting, as that ensures that the All option is in the Array before we do the sorting.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/array-filter.png)
</div>
The Array Filter node should sort on the Value property of the items in the array, and we can do that by setting it up like this:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/filtering/array-filter-props.png)
</div>
We could now make a connection from the Array Filter to the Dropdown, but as you can see the Filters component is getting quite big in terms of nodes.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/big-filters.png)
</div>
Let's turn the selected nodes below into it's own Logic Component.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/cut-out-these.png)
</div>
## Creating Add All Option component
From the Component Actions button, select Logic Component and name it Add All Option.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/logic-comp.png)
</div>
Then from the Filters node, cut out the marked nodes and paste them into the Add All Option component (use standard keyboard shortcuts for cutting and pasting). It should now look like below.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/initial-add-all.png)
</div>
Let's add a port to the Component Inputs node that we call Items:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/input-port.png)
</div>
We also want to send out the sorted array, so let's add a port on the Component Outputs node called Sorted Items.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/output-port.png)
</div>
Now we just make the following connections.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/add-all-final.png)
</div>
Back in the Filters component let's add out newly create Add All Options node, and hook it up like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/add-all-in-filters.png)
</div>
Now we have a nice Dropdown with our All option as well.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/dropdown-all.png)
</div>
Only problem is there is no initial value set in the Dropdown.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/dd-initial-value.png)
</div>
We can easily fix that but adding a String node and giving it the value "A" and then connecting it like the image below:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/dd-final.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/dd-final-preview.png)
</div>
## Adding filters.
All of our visuals are now set up. All that is missing are the actual filters. Let's work on those now.
First let's add a new Logic Component that we call State and Size Filter.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/state-size-filter-comp.png)
</div>
Add two ports to the Component Inputs node called Selected State and Size. You can also delete the Component Outputs node, we won't need that.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/state-size-filter-inputs.png)
</div>
Jump back to the Filters component and add the State and Size Filter component and hook it up like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/state-size-filter-in-filters.png)
</div>
Now, we head back to the State and Size Filter component. Let's first make a filter for Size. We will add a Query Sheet node, and set it up like this.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/query-sheet-size-filter.png)
</div>
The Query Sheet node has a very nice visual filter builder so click here to add a filter:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/add-filter.png)
</div>
Then let's build out our filter using the visual builder. The following images show you each step. T
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/build-filter-1.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/build-filter-2.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/build-filter-3.png)
</div>
In this final step it's important to change the Value to Input, and then you can change the MyInput to a better name, like Size for instance.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/build-filter-4.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/build-filter-5.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/build-filter-6.png)
</div>
We are going to add one more Query Sheet node, and this one we will call Query Sheet State and Size Filter. Then add two filters to it so the final properties for it looks like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/state-size-filter-props-1.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/state-size-filter-props-2.png)
</div>
Next, we want to take the output from our Query Sheet nodes and hook them up to the Array node with the id Parks. If you remember from the previous guides, we are using this Array to feed the Repeater node that creates our list. If the Array is updated or changed, the Repeater node will automatically rerender, so everytime we get a new result from our filter nodes the list will update.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/query-sheet-to-arrays.png)
</div>
So why did we create two Query Sheet nodes with two different filters. It's so that we can handle the case when we choose All as the option in the Dropdown list. All is not a state that exists in our sheet, so the filter that is looking at both state and size will fail everytime we feed A into it. So to handle this we will use an expression in combination with a condition node to check if we are looking at all states, in which case we will just filter on size, or if we have selected a specific state, then we can filter on both state and size. The images below first show the expression in the Expression node, and the second image shows how everything should be connected.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/expression-props.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/filtering/final-node-tree.png)
</div>
## Summary
In this guide we added filters to our National Parks and used the Query Sheets Aggregate nodes. Hope you enjoyed it, and you can import the final project by clicking the "Import" button below and follow the instructions.
import ImportButton from '/src/components/importbutton'
import useBaseUrl from '@docusaurus/useBaseUrl'
<div className="ndl-image-with-background l">
<img
src={useBaseUrl(
'/modues/gsheets/guides/filtering/filter-final-preview.gif'
)}
className="ndl-image small"
></img>
<ImportButton
zip="gsheets-part3-1.zip"
name="Google Sheets National Parks"
thumb="filter-view.png"
/>
</div>

View File

@@ -0,0 +1,217 @@
---
title: Park Details View
hide_title: true
---
# Park Details View
## What you will learn in this guide
This guide will continue to explore how we can build front ends to data from Google Sheets.
## Overview
If you haven't already looked at the guide for setting up the Google Sheets Module, it's recommended to do that before starting this guide. You can find it [here](/library/modules/gsheets/guides/setting-up).
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/park-details.png)
</div>
We will go though the following steps:
- Using the Sheet Row node.
- Building a simple details view for data from a Google Sheet
## Creating the Park Details component
First let's create a new visual component that we will call Park Details.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/park-details-new-comp.png)
</div>
Then, build out the following visual tree and then we will look at the properties for each node.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/park-details-node-tree.png)
</div>
First the properties for the top group, and the only thing that is different from the defaults is the white background:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/park-details/top-group-props.png)
</div>
Next we have the Image node which is setup like this:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/park-details/image-props.png)
</div>
The Group that we have called Text Content, only has some padding set:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/text-content-props.png)
</div>
We will be displaying the park name in the Text node that we call just Park Name, and the properties for that node are as follows:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/park-name-props.png)
</div>
There is another group in our tree, the Horizontal Group, that we use to lay out some of the other information, and the properties for this group are:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/hgroup-props.png)
</div>
All three of the Text nodes that are inside of the Horizontal Group have the same styling which is the default styling of a Text node so there is no need to change any properties for these nodes.
Finally the Text node that we have named Description has the following styling:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/park-details/description-props.png)
</div>
## Adding the Park Details to the App component
Now that we have built out and styled the visuals for our Park Details, let's add them to our App component. In the App component we will first add another group that we can call Details Container and then we add the Park Details as a child to that Group. It should look like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/app-comp-with-deets.png)
</div>
You should also see something like this in the preview window:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/deets-preview-no-data.png)
</div>
This is great, but it would be even nicer with some actual content!
## Using the Sheet Row node to get the correct details data
To get the correct content in the Park Details component, we will again use a [Sheet Row](/library/modules/gsheets/node-docs/sheet-row) node, so let's place it next to our visual tree.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/add-sheet-row.png)
</div>
We need to tell the Sheet Row node which row we want to look at, and if you remember from the previous [guide](/library/modules/gsheets/guides/setting-up/), we already have a Variable named SelectedRowId. We set this everytime we click on an item in the list. Below you can see where in the List Item component the Variable is being set.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/list-item-variable.png)
</div>
Since Variables are global we can use that same Variable in our Park Details component and connect it to the Row Id input of the Sheet Row node.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/var-to-sheet-row.png)
</div>
Now we can start to connect all the outputs from the Sheet Row node to our visual tree. Go ahead and make the following connections first, and then we will handle the remaining two.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/details-almost-connected.png)
</div>
You still don't see anything in the preview window, unless you go ahead and click on an item in the list. In the image below I clicked on the Arches park.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/arches.png)
</div>
As you can see we haven't filled in the size information or the date for when the park was established so let's tackle that now.
The size that we are getting out from the Sheet Row is in km<sup>2</sup>, so it would be nice to add that at the end of the number. To do that we will use a String Format node, with the following set up, and then connected like in the second image.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/string-format-props.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/size-connected.png)
</div>
The Established date that we get from the Sheet Row is a Date type and it looks a bit strange if we connect it directly to our text node, so let's put a [Date To String](/nodes/utilities/date-to-string) node in between. After it's connected it will look like the image below.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/date-connected.png)
</div>
The last thing we will do in this guide is to make sure we set the SelectedRowId Variable to the first item in the list. We can do that in the App component like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/first-item-selected.png)
</div>
Now everytime we reload the first item in the list will always be selected and we will always show something in the Park Details section.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/park-details/first-item-selected-preview.png)
</div>
## Summary
In this guide we added a details view to our National Parks example using data from a Google Sheet. If you want to import the final project, click the "Import" button below and follow the instructions.
import ImportButton from '/src/components/importbutton'
import useBaseUrl from '@docusaurus/useBaseUrl'
<div className="ndl-image-with-background l">
<img
src={useBaseUrl(
'/library/modules/gsheets/guides/park-details/first-item-selected-preview.png'
)}
className="ndl-image small"
></img>
<ImportButton
zip="gsheets-part2-1.zip"
name="Google Sheets Park Details"
thumb="arches.png"
/>
</div>
In the next guide we will look at how we can apply filters to our Google Sheet data.

View File

@@ -0,0 +1,364 @@
---
title: Setting up the Google Sheets Module
hide_title: true
---
# Setting up the Google Sheets Module
## What you will learn in this guide
This guide will show you how to include the Google Sheets module in a project and how to get data from a Google Sheet into your Noodl project.
## Overview
In this guide we will build a small application where we display a list of US National Parks. We will get the data for the parks from a public Google Sheet.
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/setting-up/parks-list-filled.png)
</div>
We will go though the following steps:
- Install the Google Sheets Module in a Noodl Project.
- Set up a Query Sheets node to pull data from a public Google Sheet
- Create a small list based on the data from the Google Sheet
## Install the Google Sheets Module
The easiest way to get started with the Google Sheets Module is to use the "GSheets" template when creating a new project in Noodl. In that template, the Google Sheets module is already included.
However, if you have an existing project, or want to start from a different template, it's easy to get started as well. Just follow these instructions.
When in the project, open the "Library" tab to the left. Find the "GSheet" module and click "Add".
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/setting-up/module-1.png)
</div>
After the module is imported, you should now be able to find the [Query Sheet](/library/modules/gsheets/node-docs/query-sheet), [Query Sheet Aggregate](/library/modules/gsheets/node-docs/query-sheet-aggregate) and [Sheet Row](/library/modules/gsheets/node-docs/sheet-row) nodes in the node picker. Right click in the node editor area to bring up the node picker. Look under "External libraries" to find the **Google Sheets** nodes.
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/setting-up/nodepicker-1.png)
</div>
## Getting data from a Query Sheet
In this guide we will start building from the Hello World template.
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/setting-up/hello-world.png)
</div>
Go ahead and delete the text node and you should end up just having a Group node as in the image below:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/hello-world-deleted.png)
</div>
Then style your group like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/group-props.png)
</div>
Before we build out our simple list UI, let's have a look at the Google Sheet that contains our data. You will find the document [here.](https://docs.google.com/spreadsheets/d/1gjttBIT4bHGFS8ynF31DoYw143ZY3UAiwopAW0N97KQ/)
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/google-sheet-1.png)
</div>
The document contains three different sheets, but we are only interested in the sheet named Parks.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/google-sheet-sheetnames.png)
</div>
To get all the data from the Parks sheet into our Noodl project we will use a Query Sheets node, so let's add that and have a look at the properties.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/query-sheet-node.png)
</div>
The Document Id property takes the id of the Google Sheet document, and we get that from this part of the Google Sheet URL (1gjttBIT4bHGFS8ynF31DoYw143ZY3UAiwopAW0N97KQ):
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/google-sheet-id.png)
</div>
Let's also fill in the name of the sheet we are interested wich is Parks. After you have done this, the properies of the Google Sheet node should look like this:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/query-sheet-node-filled-in.png)
</div>
We will leave the Use Column For Id property set to Unique id, but you can select a column that will become the Id of the Noodl Objects that will represent each row. It's important that the values in this column are unique. Since we have chosen Unique Id, Noodl will generate it's own id's for us.
We can now get the data from the Query Sheet on the Items output, so let's create an Array node and give it the Id Parks and connect it like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/items-to-array.png)
</div>
Now that we have all of the parks in an Array node, let's build out our list.
## Creating the Park List component
First let's create a new visual component that we will call Park List.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/create-scroll-list.png)
</div>
The Park List component will be pretty simple. First let's enable scroll on the Group, by setting the following property.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/scroll-list.png)
</div>
Next we will add a [Repeater](/nodes/ui-controls/repeater) node as a child to our Group. The [Repeater](/nodes/ui-controls/repeater) node is used to generate one component for each row in the Parks Array so let's also add an Array node and give it the Parks id.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/array-parks-id.png)
</div>
Then we connect it to the Repeater node like this.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/array-to-repeater.png)
</div>
Now let's jump back to our App component and add a Group that we will call List Container.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/main-app-list-container.png)
</div>
Let's set this List Container to be 400 px in width and then let's add the Park List component as a child.
<div className="ndl-image-with-background s">
![](/library/modules/gsheets/guides/setting-up/list-container-props.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/app-with-parks-list.png)
</div>
Now let's jump back to the Park List component and look at the Repeater properties. We need to tell the Repeater node which component it should generate, so before we fill this in, let's create our list items.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/repeater-comp.png)
</div>
## Building the list items
Let's create the visuals for our list items first by creating a new Visual Component that we call List Item.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/create-list-item-1.png)
</div>
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/create-list-item-2.png)
</div>
The list items shouldn't be too tall so let's set an explicit height to 100 pixels and let's add some padding and change the Layout to Horizontal. We also want a nice bottom border.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-group-props.png)
</div>
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-group-border.png)
</div>
The items should all show an image as well as the park name and which state the park is located, so let's add nodes so that we get the following node tree:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-tree.png)
</div>
Now set the Image properties like in the image below.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-image-props.png)
</div>
The Group that holds the two Text nodes is using all the default settings so we don't need to change anything there, but set the properties of the Park Name Text node to:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-park-name-props-1.png)
</div>
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-park-name-props-2.png)
</div>
The State Text node should have the following properties:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-state-props.png)
</div>
Now that we have visuals for our list items, we can tell the Repeater node in the Park List component to use this as the template so let's do that:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/repeater-filled-props.png)
</div>
If you reload your project now you should see the following in the preview window.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/halfway-preview.png)
</div>
This is great, now let's make sure each list item displays the correct data.
## Using the Sheet Row node in our List Items
Let's go back to our List Item component and add a Sheet Row node.
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/list-item-sheet-row.png)
</div>
The Sheet Row node can point to a specific row in the Google Sheet, but we need to tell it which row by providing an Id. That Id we will get from a [Repeater Item](/nodes/ui-controls/repeater-item) node. This all works exactly the same as it does when you are working with the Noodl Query Records and Record nodes, and you can read more about that in this [guide.](/docs/guides/cloud-data/quering-records-from-database)
Connect the Repeater Item and Sheet row like below
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/repeater-item.png)
</div>
Now, the Sheet Row node should have a bunch of new outputs. Let's hook them up like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/sheet-row-hook-up.png)
</div>
You should now see something like this in your preview window, and you should be able to scroll your list.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/parks-list-filled.png)
</div>
Before we finish, let's add a little bit of logic to highlight which List Item is selected. Create a States node and set it up like this:
<div className="ndl-image-with-background ">
![](/library/modules/gsheets/guides/setting-up/states-node.png)
</div>
Let's also add an Expression node and set it up like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/expression-node.png)
</div>
Finally we will add a Variable node with the name SelectedRowId, a Set Variable node, and a Condition node. Then we will hook it all up like this:
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/final-item-node.png)
</div>
Now when you click on an item in the list it should become highlighted.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/guides/setting-up/final-result.png)
</div>
## Summary
In this guide we built a list of National Parks using data from a Google Sheet. If you want to import the final project, click the "Import" button below and follow the instructions.
import ImportButton from '/src/components/importbutton'
import useBaseUrl from '@docusaurus/useBaseUrl'
<div className="ndl-image-with-background l">
<img
src={useBaseUrl('/modules/gsheets/guides/setting-up/parks-final.gif')}
className="ndl-image small"
></img>
<ImportButton
zip="gsheets-part1-1-2.zip"
name="Google Sheets Getting Started"
thumb="final-result.png"
/>
</div>
In the next guide, we will create a details view for our parks, and in the final guide we will look at how we can filter the data we get in the Query Sheet node.

View File

@@ -0,0 +1,86 @@
---
title: Query Sheet Aggregate
hide_title: true
---
<##head##>
# Query Sheet Aggregate
This node is used do aggregate data queries on a column from a public Google Sheet. The aggregate query will be either
- `min`/`max` - The minimum/maximum value of the specfied column.
- `unique` - An **Array** containing all unique values in the column.
- `count` - The number of entries in total of that column. Empty cells will not be counted.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/query-sheet-aggregate/query-sheet-ag-1.png)
</div>
?> Note that the Google Sheet need to be made public for Noodl to be able to access it.
<##head##>
## Results from the Aggregate Query
Note the the type of the **Result** output is dependent on which aggregate query that is run. For `min`/`max` and `count` **Result** will be a **Number**. For `unique` it will be an **Array**.
## Document Id and Sheet Name
You refer to the document through its id. You find the id in the URL of the Google Sheet.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-3.png)
</div>
You also have to specify the Sheet Name. You find the Sheet names in the Google Document at the bottom of the sheet.
<div className="ndl-image-with-background">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-4.png)
</div>
## Filters
A filter can be added to the query, meaning the aggregate will only be calculated based on the filtered rows. It can be a combination of various filter operators (`equalTo`, `notEqualTo`, `exists`, etc) depending on the type of the column. Multiple filters can be combined using `AND` and `OR`. A the values to filter against can be set dynamic by making the filter use an `Input` rateher than a static value. This will create an input on the node that you can connect.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/query-sheet-aggregate/query-sheet-ag-1.png)
</div>
## Controlling when queries are performed
If the `Do` signal is unconnected, the Query will automatically be run when the **Query Sheet Aggregate** node is created and whenever any of its inputs change. By connecting the `Do` signal, the Query will only be run when `Do` is triggered.
## Inputs
| Data | Description |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span className="ndl-data">Document Id</span> | The id of the Google Sheets document. You can find it in the URL of the sheet. |
| <span className="ndl-data">Sheet Name</span> | The name of the sheet where to capture the data in the Google Sheet. |
| <span className="ndl-data">Column</span> | The name of the column in the Google Sheet to run the aggreagate query on. |
| <span className="ndl-data">Aggregate</span> | Can be one of the following values: `Min`/`Max`/`Unique`/`Count`. `Min`/`Max` will set the miminum value in the specified column on the `Result` output. `count` will set the number of non-empty cells in the column on `Result`. Finally `Unique` will set the `Result` output to an **Array** of objects of the form `{Label:<unique value>, Value:<unique value>}` with all unique values of the column. |
| <span className="ndl-data">Filter</span> | Each filter that is set up to controlled by an input will show up as an input on the node. |
| Signal | Description |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | This signal will trigger the query to be executed. If the signal is not connected, the query will automatically be triggered when instanciated and when any of its inputs changes. |
## Outputs
| Data | Description |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Result</span> | The result of the aggregate query. It's either a <span className="ndl-data">Number</span> or an **Array** depending on what aggregation query that that was performed (see `Aggregate` input above). |
| <span className="ndl-data">Error</span> | A textual description of the latest error, when the `Failure` signal was triggered as a result of a failed Query. |
| Signal | Description |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | This signal is sent when a Query was successfully performed. |
| <span className="ndl-signal">Failure</span> | This signal is sent when a Query failed for some reason. The `Error` property will contain the error message. |

View File

@@ -0,0 +1,94 @@
---
title: Query Sheet
hide_title: true
---
<##head##>
# Query Sheet
This node is used to query data from a public Google Sheet. You can filter and sort the data. The data is organized in _Rows_ where the values of each cell in the row is exposed in a properties of the row.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-1.png)
</div>
The node works in a similar way as the [Query Records](/nodes/data/cloud-data/query-records) node where you can add filters and sorting.
<div className="ndl-image-with-background">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-2.png)
</div>
?> Note that the Google Sheet need to be made public for Noodl to be able to access it.
<##head##>
## Document Id and Sheet Name
You refer to the document through its id. You find the id in the URL of the Google Sheet.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-3.png)
</div>
You also have to specify the Sheet Name. You find the Sheet names in the Google Document at the bottom of the sheet.
<div className="ndl-image-with-background">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-4.png)
</div>
## Filters
A filter can be added to the query. It can be a combination of various filter operators (`equalTo`, `notEqualTo`, `exists`, etc) depending on the type of the column. Multiple filters can be combined using `AND` and `OR`. A the values to filter against can be set dynamic by making the filter use an `Input` rateher than a static value. This will create an input on the node that you can connect.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/query-sheet/query-sheet-5.png)
</div>
## Returned results
The results of the query is an **Array**, just as with a regular **Query Record**. The Array contains Objects that represents the rows in the Google Sheet. Each column value will be represented by a property in the respective object, with the same name as the column. When using a [Sheet Row](/library/modules/gsheets/node-docs/sheet-row) node, the **Id** of the object can be used to set the **Row Id** of the Sheet Row node.
## Controlling when queries are performed
If the `Do` signal is unconnected, the Query will automatically be run when the **Query Sheet** node is created and whenever any of its inputs change. By connecting the `Do` signal, the Query will only be run when `Do` is triggered.
## Inputs
| Data | Description |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Document Id</span> | The id of the Google Sheets document. You can find it in the URL of the sheet. |
| <span className="ndl-data">Sheet Name</span> | The name of the sheet where to capture the data in the Google Sheet. |
| <span className="ndl-data">Use Column For Id</span> | You can select a column that will become the **Id** of the Noodl Objects that will represent each row. It's important that the values in this column are unique. You can also chose `Unique Id`, then Noodl will generate it's own id's. |
| <span className="ndl-data">Use limit</span> | A<span className="ndl-data"> boolean </span> that selects whether there will be a limit or not on how many items that are loaded when the query is run. This is useful when you are handling large amount of items and you want to do pagination. |
| <span className="ndl-data">Limit</span> | This input is only available if `Use Limit` is set to<span className="ndl-data"> true </span>. It decides how many items that will be loeded when the query is triggered. To be used in combination with `Skip` to create paginations. |
| <span className="ndl-data">Skip</span> | This input is only available if `Use Limit` is set to<span className="ndl-data"> true </span>. It sets how many items that will be skipped when the query is triggered. To be used in combination with `Skip` to create paginations. For example, if `Limit` is set to 10 and `Skip` is set to 30, the query will fetch item 31-40. |
| <span className="ndl-data">Filter</span> | Each filter that is set up to controlled by an input will show up as an input on the node. |
| Signal | Description |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Do</span> | This signal will trigger the query to be executed. If the signal is not connected, the query will automatically be triggered when instanciated and when any of its inputs changes. |
## Outputs
| Data | Description |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Items</span> | An array of items that's the result of the query. The items represents a row in the Google Sheet and will contain all column values as properties on the Object, as well as an id that's set up depending on the `Set Column For Id` property is set up. |
| <span className="ndl-data">Count</span> | The number of items the latest query returned. |
| <span className="ndl-data">First Item Id</span> | The id of the first item that was returned in the latest query. |
| <span className="ndl-data">Error</span> | A textual description of the latest error, when the `Failure` signal was triggered as a result of a failed Query. |
| Signal | Description |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Success</span> | This signal is sent when a Query was successfully performed. |
| <span className="ndl-signal">Failure</span> | This signal is sent when a Query failed for some reason. The `Error` property will contain the error message. |

View File

@@ -0,0 +1,49 @@
---
title: Sheet Row
hide_title: true
---
<##head##>
# Sheet Row
This node is used do simplify handling of results from a [Query Sheet](/library/modules/gsheets/node-docs/sheet-row) node. It's typically used in a combination with a [Repeater Item](/nodes/ui-controls/repeater-item) to easily connect any columns available in a row in a Google Sheets sheet.
By setting the `Row Id` of the **Sheet Row**, and selecting the **Sheet** (if you use more than one) your **Sheet Row** will automatically show all available column values.
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/sheet-row/sheet-row-1.png)
</div>
<div className="ndl-image-with-background l">
![](/library/modules/gsheets/node-docs/sheet-row/sheet-row-2.png)
</div>
?> Note that the Google Sheet need to be made public for Noodl to be able to access it.
<##head##>
## Inputs
| Data | Description |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Sheet</span> | The name of the Sheet in which the row lies. This input only exists if you are querying multiple sheets, otherwise it will automatically select the sheet you are querying. |
| <span className="ndl-data">Row Id</span> | The id of the Sheet Row. The Id is determined by the [Query Sheet](/library/modules/gsheets/node-docs/query-sheet) node accessing the Sheet, where you can decide how the Id is generated throguh the **Use Column For Id** property. |
| Signal | Description |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Fetch</span> | Explicitly tells the **Sheet Row** to fetch data from the Google Sheet. If this signal is unconnected it will fetch automatically when the **Sheet Row** node is created. |
## Outputs
| Data | Description |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| <span className="ndl-data">Column Values</span> | Each column in the row will become and output with the same name holding the value of the cell. |
| Signal | Description |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| <span className="ndl-signal">Fetched</span> | This signal is sent when new data have been fetched from the Google Sheet to the **Sheet Row**. |

View File

@@ -0,0 +1,10 @@
---
title: Release Notes
hide_title: true
---
# Release Notes
Version 1.0 [2022-01-21]
* Query Sheet node that can filter and sort rows in a public Google Sheet document
* Query Sheet Aggregate that can apply an aggregate filter on a specific column on a public Google Sheet document
* Sheet Row node that serves as an easy to access data node representing a row in a Google Sheet document