# Prompts
*Interact with users and gather input using Ivy's [alert](./17_Alerts.md) and [dialog](../../02_Widgets/03_Common/15_Dialog.md) system.*
## Basic Usage
Here's a simple example using [UseAlert](./17_Alerts.md), [Layout](./04_Layout.md), and [Button](../../02_Widgets/03_Common/01_Button.md) to show a confirmation alert:
```csharp
public class BasicPromptView : ViewBase
{
public override object? Build()
{
var (alertView, showAlert) = UseAlert();
var client = UseService<IClientProvider>();
return Layout.Vertical(
new Button("Delete Item", onClick: _ =>
{
showAlert("Are you sure you want to delete this item?", result =>
{
if (result == AlertResult.Ok)
{
// Item would be deleted here
client.Toast("Item deleted!", "Success");
}
}, "Delete Item");
}),
alertView
);
}
}
```
```mermaid
flowchart LR
A[User Action] --> B{Input Type}
B -->|Confirm| C[UseAlert<br/>showAlert]
B -->|Text| D[Form.ToDialog]
B -->|Multiple| E[Custom Form<br/>ToDialog]
B -->|Chain| F[Alert → Alert]
C --> G[AlertResult]
D --> H[Form Submit]
E --> H
F --> G
```
### Text Input Prompts
Collect text input from users using dialogs with [forms](./08_Forms.md):
```csharp
public record RenameRequest
{
public string Name { get; set; } = "Current Item Name";
}
public class RenameView : ViewBase
{
public override object? Build()
{
var client = UseService<IClientProvider>();
var isOpen = UseState(false);
var renameData = UseState(new RenameRequest());
UseEffect(() => {
if (!isOpen.Value && !string.IsNullOrEmpty(renameData.Value.Name))
{
// Item would be renamed here
client.Toast($"Renamed to: {renameData.Value.Name}", "Success");
}
}, [isOpen]);
return Layout.Vertical(
new Button(
"Rename",
onClick: _ => isOpen.Set(true)
),
isOpen.Value ? renameData.ToForm()
.Label(e => e.Name, "Enter new name:")
.ToDialog(isOpen,
title: "Rename Item",
submitTitle: "Rename"
) : null
);
}
}
```
### Custom Prompts
Create custom dialogs with multiple inputs:
```csharp
public record CustomOptions
{
public bool Option1 { get; set; }
public bool Option2 { get; set; }
public string CustomText { get; set; } = "";
}
public class CustomPromptView : ViewBase
{
public override object? Build()
{
var client = UseService<IClientProvider>();
var isOpen = UseState(false);
var options = UseState(new CustomOptions());
UseEffect(() => {
if (!isOpen.Value && (options.Value.Option1 || options.Value.Option2 || !string.IsNullOrEmpty(options.Value.CustomText)))
{
// Options would be saved here
client.Toast("Options saved!", "Success");
}
}, [isOpen]);
return Layout.Vertical(
new Button(
"Custom Prompt",
onClick: _ => isOpen.Set(true)
),
isOpen.Value ? options.ToForm()
.Builder(e => e.Option1, e => e.ToBoolInput("Option 1"))
.Builder(e => e.Option2, e => e.ToBoolInput("Option 2"))
.Builder(e => e.CustomText, e => e.ToTextInput("Custom text"))
.ToDialog(isOpen,
title: "Select Options",
submitTitle: "Save"
) : null
);
}
}
```
## Examples
### Confirmation with Custom Options
```csharp
public record DeleteOptions
{
public bool DeleteAssociatedFiles { get; set; }
public bool ArchiveInsteadOfDelete { get; set; }
public string ReasonForDeletion { get; set; } = "";
}
public class DeleteWithOptionsView : ViewBase
{
public override object? Build()
{
var (alertView, showAlert) = UseAlert();
var client = UseService<IClientProvider>();
var isOptionsOpen = UseState(false);
var deleteOptions = UseState(new DeleteOptions());
UseEffect(() => {
if (!isOptionsOpen.Value && (deleteOptions.Value.DeleteAssociatedFiles || deleteOptions.Value.ArchiveInsteadOfDelete || !string.IsNullOrEmpty(deleteOptions.Value.ReasonForDeletion)))
{
// Deletion with options would be performed here
client.Toast("Item deleted with custom options", "Success");
}
}, [isOptionsOpen]);
return Layout.Vertical(
new Button(
"Delete with Options",
onClick: _ => {
showAlert(
"This will permanently delete the item. Do you want to configure deletion options?",
result => {
if (result == AlertResult.Yes)
{
isOptionsOpen.Set(true);
}
else if (result == AlertResult.No)
{
// Simple delete without options
client.Toast("Item deleted", "Success");
}
},
"Delete Options",
AlertButtonSet.YesNoCancel
);
}
).Destructive(),
alertView,
isOptionsOpen.Value ? deleteOptions.ToForm()
.Builder(e => e.DeleteAssociatedFiles, e => e.ToBoolInput("Delete associated files"))
.Builder(e => e.ArchiveInsteadOfDelete, e => e.ToBoolInput("Archive instead of delete"))
.Builder(e => e.ReasonForDeletion, e => e.ToTextInput("Reason for deletion"))
.ToDialog(isOptionsOpen,
title: "Delete Options",
submitTitle: "Delete"
) : null
);
}
}
```