---
title: Custom Auto Forms
group: Component Gallery
---
## Custom AutoForm UIs
[CoffeeShop's Admin UI](https://servicestack.net/posts/building-typechat-coffeeshop-modelling) is a good example of the rapid development model
of AutoQuery and Vue's [AutoQueryGrid](/vue/autoquerygrid) and
[Auto Form](/vue/autoform) Components was nearly able to develop the entire CRUD management UI using just AutoQuery's Typed DTOs.
The one Form that it wasn't able to generate the entire UI for is its **Many-to-Many** `CategoryOption` relationship
which requires a custom AutoForm component to be able to specify which Options a category of CoffeeShop Products can have.
### Implementing Many to Many CategoryOption Admin UI
The easier way to implement this functionality would be to have the UI call an API each time an `Option` was added or removed
to a `Category`. The problem with this approach is that it doesn't match the existing behavior where if a User **cancels**
a form they'd expect for none of their changes to be applied.
To implement the desired functionality we'll instead create a custom `UpdateCategory` implementation that also
handles any changes to `CategoryOption` using new `AddOptionIds` and `RemoveOptionIds` properties that we'll want
rendered as **hidden** inputs in our HTML Form with:
```csharp
public class UpdateCategory : IPatchDb, IReturn
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
[Input(Type = "tag"), FieldCss(Field = "col-span-12")]
public List? Sizes { get; set; }
[Input(Type = "tag"), FieldCss(Field = "col-span-12")]
public List? Temperatures { get; set; }
public string? DefaultSize { get; set; }
public string? DefaultTemperature { get; set; }
[Input(Type = "file"), UploadTo("products")]
public string? ImageUrl { get; set; }
[Input(Type = "hidden")]
public List? AddOptionIds { get; set; }
[Input(Type = "hidden")]
public List? RemoveOptionIds { get; set; }
}
```
## Custom AutoQuery Implementation
The [Custom AutoQuery Implementation](/autoquery/rdbms#custom-autoquery-implementations)
in [CoffeeShopServices.cs](https://github.com/NetCoreApps/TypeChatExamples/blob/main/TypeChatExamples.ServiceInterface/CoffeeShopServices.cs)
contains the custom implementation which continues to utilize AutoQuery's **Partial Update** functionality if there's any changes to update,
as well as removing or adding any Options the user makes to the `Category`:
```csharp
public class CoffeeShopServices(IAutoQueryDb autoQuery) : Service
{
public async Task