Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions docs/ff-concepts/layout/building-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ keywords: [FlutterFlow, Building Layout, Concepts]

# Building Layout

In FlutterFlow, you build a page layout using Widgets. **Widgets**, such as [Text](../../resources/ui/widgets/built-in-widgets/text.md), [Buttons](#), [Images](#), and [Icons](#), are visible on the screen. Others, like [Containers](#), [Rows](#), [Columns](#), and [Stacks](#), are not directly visible but help arrange and position the visible elements on the page.
In FlutterFlow, you build a page layout using Widgets. **Widgets**, such as [Text](../../resources/ui/widgets/built-in-widgets/text.md), [Buttons](../../resources/ui/widgets/built-in-widgets/button.md), [Images](#), and [Icons](../../resources/ui/widgets/built-in-widgets/icons.md), are visible on the screen. Others, like [Containers](../../resources/ui/widgets/built-in-widgets/container.md), [Rows](#), [Columns](#), and [Stacks](#), are not directly visible but help arrange and position the visible elements on the page.

These widgets are categorized into four main types: [Layout Elements](#), [Base Elements](#),
[Page Elements](#), and [Form Elements](#). To build a page, you combine different widgets from these categories to get the desired look and feel of your app.
These widgets are categorized into four main types: [Layout Elements](/tags/layout-elements), [Base Elements](/tags/base-elements),
[Page Elements](/tags/page-elements), and [Form Elements](/tags/form-elements). To build a page, you combine different widgets from these categories to get the desired look and feel of your app.

## Understanding layout concept

One of the most common layout patterns is to arrange widgets either **vertically** or **horizontally**. To display widgets in a vertical layout, use the **Column** widget. For a horizontal layout, use the **Row** widget. If you need to place one widget on top of another, use the **Stack** widget.

:::info
**Composing widgets** is a fundamental aspect of creating layouts in FlutterFlow. It involves combining different widgets to form a cohesive and functional user interface. Understanding how to effectively compose widgets allows you to design complex layouts and create intuitive, user-friendly apps. Learn more about composing widgets [**here**](#).
**Composing widgets** is a fundamental aspect of creating layouts in FlutterFlow. It involves combining different widgets to form a cohesive and functional user interface. Understanding how to effectively compose widgets allows you to design complex layouts and create intuitive, user-friendly apps. Learn more about composing widgets [**here**](../../resources/ui/widgets/composing-widgets.md).

:::

Expand Down Expand Up @@ -155,13 +155,13 @@ The review section consists of multiple different widgets. First, add a Column t

Apart from Row, Column, and Stack widgets, there are some other widgets that are widely used for building the page layout. Here are some of them:

- [Container](#)
- [Card](#)
- [ListView](#)
- [GridView](#)
- [TabBar](#)
- [PageView](#)
- [Form](#)
- [Container](../../resources/ui/widgets/built-in-widgets/container.md)
- [Card](../../resources/ui/widgets/built-in-widgets/card.md)
- [ListView](../../resources/ui/widgets/built-in-widgets/list-grid.md)
- [GridView](../../resources/ui/widgets/built-in-widgets/list-grid.md)
- [TabBar](../../ff-concepts/navigation-routing/special-page-navigation/tabbar-widget.md)
- [PageView](../../ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md)
- [Form](../../resources/control-flow/user-interactivity/forms/forms.md)

## Video guides

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
slug: /concepts/navigation/pageview
title: PageView
description: Learn how to use the PageView widget for creating swipeable pages, perfect for creating onboarding screens or multi-step forms.
tags: [PageView, FlutterFlow, UI, Widgets]
tags: [PageView, FlutterFlow, UI, Widgets, Layout Elements]
sidebar_position: 2
keywords: [PageView, FlutterFlow, UI, Widgets]
---
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions docs/ff-concepts/state-management/widget-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: Widget State
---

# Widget State

**Widget state** refers to the data or information that a widget holds, which can change over time and affect the widget's appearance or behavior. In FlutterFlow, the state is particularly important for form widgets, such as text fields, checkboxes, and radio buttons, as it allows these widgets to respond to user interactions.

Additionally, **Widget Focus State** refers to the state that indicates whether a widget, such as a text field, currently has focus or not. When a widget has focus, it is ready to receive user input, and its appearance typically changes to indicate this (e.g., a text field with a blinking cursor).

**Key Points:**

- **Dynamic Data:** Represents values that change over time (e.g., user input in a text field).
- **Automatic Management:** FlutterFlow handles the state, so developers do not need to write explicit state management code.
- **Reactive Updates:** Changes in the state automatically update the widget's display.

![widget-state.png](imgs%2Fwidget-state.png)

## Managing Widget States

FlutterFlow simplifies state management by providing built-in support for handling widget states. This means developers do not need to manually create or manage the state of form widgets. Instead, FlutterFlow automatically manages the state for these widgets, ensuring a seamless and intuitive experience.

Some examples of widget states exposed by FlutterFlow:

- **Text Fields:** The state of text fields is automatically managed, including the input text and validation states.
- **Checkboxes:** The state of checkboxes is managed, indicating whether they are checked or unchecked.
- **Radio Buttons:** The state of radio buttons is managed to reflect the selected option.


In the following example, we find widget state and widget focus state of a TextField being exposed by FlutterFlow on the page it was created and available as an option in the variable menu.

![using-widget-state.png](imgs%2Fusing-widget-state.png)

:::note[Scope]
Widget states are only available for access on the page or component where they were created.
:::

FlutterFlow allows you to update the state of these widgets through actions exposed by the platform. For example, if you want to clear a TextField when the Send button is clicked on a form-like page, then in the Actions Flow, you can find relevant actions such as **Clear TextField**. This enables dynamic interaction and state management directly within the visual development environment.

![managing-widget-state.png](imgs%2Fmanaging-widget-state.png)


## Action Triggers for Form Widgets
FlutterFlow allows you to bind action triggers to widget states, such as calling an API on focus change of a textfield or changing the appearance of a button when a checkbox is checked.

**Most common Action Triggers exposed by form widgets:**

- **On Focus Change:** Triggered when a widget, such as a text field, gains or loses focus.
E.g Showing additional tips or validation messages when the user starts typing in a text field.

- **On Submit:** Triggered when a form or text field is submitted. E.g Validating input and submitting data when the user presses the enter key or clicks a submit button.

- **On Change:** Triggered when the value of a widget changes. E.g Real-time validation or updating state as the user types in a text field or changes a selection in a dropdown.

- **On Completed:** Triggered when a specific input is completed, such as entering a pincode.
E.g Automatically moving to the next step in a process after a complete and valid pincode is entered.

- **On Selected:** Triggered when an option is selected in widgets like choice chips, checkboxes, radio buttons, or sliders. E.g Updating the UI or performing actions based on the selected option.

These triggers allow developers to create interactive and responsive applications by defining specific actions that occur in response to user interactions with form widgets.

![action-triggers-widget-state.png](imgs%2Faction-triggers-widget-state.png)


169 changes: 169 additions & 0 deletions docs/resources/control-flow/backend-logic/api/create-test-api-calls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
---
title: Create & Test API Calls
slug: create-test-api
tag: [API Calls]
keywords: [API Calls, FlutterFlow]
sidebar_position: 2
---

# Create & Test API Call

On this page, you will learn how to [create](#creating-api-calls) and [test](#testing-api-calls) the API call.

## Creating API calls

To use an API in your app, first, you have to create the API Call.

Follow the steps below to create an API Call:

1. Select **API Calls** from the left [Navigation Menu](../../../../intro/ff-ui/builder.md#navigation-menu).
2. Click on the **+ Add** button and select **Create API Call**.
3. Enter the **API Call Name**.
4. Select the **Method Type**: *GET, POST, DELETE, PUT, or PATCH*.
5. Enter the **API URL** of the service you want to access.

:::note
If you want to use a dynamic URL, for example, `<https://reqres.in/api/users/2>` where 2 is dynamic and `<https://reqres.in/api/users?page=5>` where 5 is dynamic:

1. Replace the hard-coded value with a meaningful name inside the brackets (e.g., from `https://reqres.in/api/users/2`to `https://reqres.in/api/users/[user_id]`).
2. And then, [create a new variable](rest-api.md#creating-variables) with the same name you provided inside the brackets.
:::

The further instructions are based on the **Method Type** you selected.

### For `GET` & `DELETE` call

If you selected `**GET**`or `**DELETE**` as the method type, follow the steps below:

1. Optional: If the API call requires request headers such as an authorization token, [add a header](rest-api.md#passing-request-headers).
2. Optional: If the API call requires query parameters such as page number or user id, [add query parameters](rest-api.md#passing-query-parameters).
3. Click **Add Call** to save the API Call.

:::warning
After making any changes, you must save the API call.
:::

<div class="video-container"><iframe src="https://www.loom.
com/embed/ec61a02366504d12a3200426d4738c54?sid=3f41c946-6e53-4e0b-97e2-878178e546bd" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>

<p></p>


In the above demo, a `GET` API call is defined to fetch users' data from [REQ | RES](https://reqres.in/) (which provides hosted REST API to try out HTTP requests).

A demo of using a dynamic URL in a GET request is as follows:

<div class="video-container"><iframe src="https://www.loom.
com/embed/e19f05e3fc6542b78c2871bff1997033?sid=d688dbb6-dc4d-4dc1-bb3f-438069b5f6cb" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>

<p></p>

To add such an API call:

1. Replace the hard-coded value with a meaningful name inside the brackets (e.g., from `https://reqres.in/api/users/2`to `https://reqres.in/api/users/[user_id]`).
2. And then, [create a new variable](rest-api.md#creating-variables) with the same name you provided inside the brackets.

The DELETE API Call can also be defined similarly; just make sure you select the **Method Type** as ***DELETE***.

### For `POST`, `PUT` & `PATCH` call

If you have selected **POST request**, follow the steps below:

1. Optional: If the API call requires request headers such as an authorization token, [add a header](rest-api.md#passing-request-headers).
2. [Create a request body](rest-api.md#creating-request-body) for the API call.
3. Click **Add Call** to save the API Call.

:::warning
After making any changes, you must save the API call.
:::

<div class="video-container"><iframe src="https://www.loom.
com/embed/4d421b9a216d4655aed57fb63a963dc3?sid=1a86b3dd-4f06-43e8-a771-3e35a6fb2308" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>

<p></p>

In this demo, a POST API call is defined with two variables, `userName` and `userJob`. The variables are used inside the JSON request body.

The PUT and PATCH API calls can be defined similarly; make sure you enter a valid API URL endpoint and select the correct Method Type.

## Grouping API calls

You can create a group of API calls that share the same base URL. Grouping the API calls helps you add all request headers (e.g., auth token) at once, and they will be automatically added for all the API calls inside the group.

:::warning
For [**private APIs**](rest-api.md#making-an-api-call-private), headers defined within the group will not be automatically included. You'll need to manually add headers for APIs marked as private.
:::

To create the API Group:

1. Click on the **+** button (top left side) and select the **Create API Group**.
2. Enter the **API Group Name**.
3. Enter the **API Base URL**. This should be the portion that is common in all the APIs. **Note**: Do not keep the '/' in the end.
4. You can add request headers by clicking on the **+ Add Header** button. See detailed instructions on how to [add headers](rest-api.md#headers).
5. Click **Add Group**. This will display the group on the left side.
6. Open the newly created API group, and click on the **+ Add API Call**.
7. Add the API call as you would normally do. **Note**: Inside the API endpoint, enter the URL portion that starts after the base URL.

<div class="video-container"><iframe src="https://www.loom.
com/embed/081572e9e1a94d1ea83bee59f87a5125?sid=6ddb47aa-0054-47e8-8a5b-4bc03c8fb0c0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>

<p></p>

## Import API definitions

We allow you to add multiple API call definitions by importing them directly from the [Swagger/OpenAPI](https://swagger.io/) in bulk. With just a simple click, you can add a large number of APIs, significantly reducing the time and effort needed to create them manually.

Furthermore, the ability to import Swagger/OpenAPI definitions directly into FlutterFlow eliminates the risk of errors that may occur when creating API definitions manually, ensuring that applications are reliable and efficient.

:::info
We also add all settings that are required to run the API, such as [headers](rest-api.md#headers), [query parameters](rest-api.md#query-parameters), [variables](rest-api.md#variables), and body as they are defined in the Swagger file. However, you might need to replace the hard-coded values in [Body](rest-api.md#body) text with the [variables](rest-api.md#variables).
:::

To import API call definitions:

1. Click the **Import OpenAPI** icon. This will open a new popup.
2. Click **Upload File**. Here you can upload your swagger file available in `.yml` or `.json` file format.
3. After the import is successful, you will see the list of all APIs created and added as a [group](#grouping-api-calls).

Here's an example of importing API calls in bulk, taken from [here](https://editor.swagger.io/).

<div class="video-container"><iframe src="https://www.loom.
com/embed/074601859ba4430e97047dcdc60eabf6?sid=0446b026-eb75-4a3d-bb51-543668a06bfe" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
<p></p>

## Testing API calls

You should always test your API call before using it inside your app. We make it easy for you to try the API call inside our builder.

To test the API call along with its response, follow the steps below:

1. Select an API call you have already created or are currently defining, and go to the **Response & Test** tab.
2. On the left side, you will see the **Variables** section, where you can enter the values for the variables defined for your API call.
3. On the right, the **Preview** section lets you check the API URL, request headers, request body, and response. In the **Test Response** tab, you can view the full API response, including both the JSON format and raw body text, as well as the response header.
4. Click **Test API Call** to trigger the API call. You'll notice that the status of the GET request is displayed, and if it's successful (status code `200`), the result returned from that request will also be displayed below.
5. Any value of the JSON result can be accessed by [defining the JSON path](rest-api.md#json-path).

<div class="video-container"><iframe src="https://www.loom.
com/embed/7b84e0e372924547b4779bfae3c4daeb?sid=22f42516-d522-4362-9ae4-b4aac4947fc7" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>

<p></p>


The demo below shows the testing of creating a new user using a POST request. The API Call takes two variables: `userName` and `userJob`. The successful POST request returns a status code of `201`.

:::info
The testing of `PUT` and `PATCH` requests would also be similar to this.
:::

<div class="video-container"><iframe src="https://www.loom.
com/embed/4cd816e67a044604b80fb83748312a03?sid=e4ffd651-f97c-4478-94a4-e81f0931ef08" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>

<p></p>

## Trigger API calls

There are two methods to trigger an API call in your app:

* Add an **Action** to trigger the API Call based upon a user gesture.
* Add the API Call as a **Backend Query** that gets triggered automatically when the page or widget is loaded on the screen.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ slug: /resources/backend-logic/streaming-api
title: Streaming APIs
description: Learn how to use streaming APIs in your backend logic with FlutterFlow.
tags: [Streaming APIs, Backend Logic, Control Flow, FlutterFlow]
sidebar_position: 2
sidebar_position: 3
keywords: [Streaming APIs, Backend Logic, Control Flow, FlutterFlow]
---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ The CheckboxGroup widget is used to allow a user to select multiple items. The c

You can use the CheckboxGroup widget for implementing multiple selections such as repeating days for alarm, languages a user can speak, and allowing users to select pizza toppings.

:::tip[Widget State]
Before diving into form widgets, check out our guide on [**Widget States**](../../../../../ff-concepts/state-management/widget-state.md) to efficiently manage the state and behavior of your form elements.
:::

## Adding CheckboxGroup

Here's an example of how you can use the CheckboxGroup widget in your project:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ The DropDown widget enables users to choose from a list of options. It requires

You can use this widget in any situation where you want users to select from a set of options, such as selecting a country, choosing a language, or picking a color.

:::tip[Widget State]
Before diving into form widgets, check out our guide on [**Widget States**](../../../../../ff-concepts/state-management/widget-state.md) to efficiently manage the state and behavior of your form elements.
:::

## Adding DropDown widget

Let's see how to add a *DropDown* widget and build an example that shows the selected value on a Text widget. Here's how it looks:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ sidebar_position: 2

The RadioButton widget is used to allow a user to select one option from multiple selections.

You can use the RadioButton widget for implementing a single selection such as gender selection, notification preferences, etc.
You can use the **RadioButton** widget for implementing a single selection such as gender selection, notification preferences, etc.

:::tip[Widget State]
Before diving into form widgets, check out our guide on [**Widget States**](../../../../../ff-concepts/state-management/widget-state.md) to efficiently manage the state and behavior of your form elements.
:::


## Adding RadioButton to Your Project
Expand Down
Loading