Skip to content

Navigation Menu

Sign in
Sign up

Latest commit

History

51 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

RemoteUi

RemoteUi is a plugin that makes it easier to build complex form editors using .NET and React.

Getting Started

Add the following lines of code to your ASP .NET controller or RPC:

// Define the C# models.
public class Contacts
{
 [RemoteUiField("Phone", Descripton = "Your phone number.")] 
 public string Phone { get; set; }
 
 [RemoteUiField("Skype", Description = "Your Skype username.")]
 public string Skype { get; set; }
}
// Define the C# DTO used for generating remote UI.
public class ContactsResponse
{
 // This property denotes the definition used to build a RemoteUi
 // editor, the definition is generated using RemoteUiBuilder<T>.
 public JObject Definition { get; set; }
 // This property denotes the model that is used to populate
 // RemoteUi editor fields. In other words, this model contains
 // default property values for the RemoteUi editor.
 public Contacts Value { get; set; }
}
// Create a new RemoteUi builder. Register all of your custom nested
// models here, that are used in your model tree.
var builder = new RemoteUiBuilder<Contacts>()
 // .Register<ContactsInnerModel>() etc.
 .Register<Contacts>();
 
// Return the response from your controller or RPC.
return Ok(new ContactsResponse
{
 Definition = builder.Build((IServiceProvider)null),
 Value = new Contacts
 {
 Phone = "12345",
 Skype = "@skype"
 }
});

Add the following lines to your client React app:

import * as React from "react"
import * as ReactDOM from "react-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import { RemoteUiEditor } from "@remoteui/RemoteUiEditor";
import { RemoteUiEditorStore, RemoteUiDefinition } from "@remoteui/RemoteUiEditorStore";
import { observer } from "mobx-react";
import { observable } from "mobx";
// Define the Typescript models.
interface Contacts {
 phone: string;
 skype: string;
}
// Define the API response.
interface ContactsResponse {
 definition: RemoteUiDefinition;
 value: Contacts;
}
// Fetch the response and populate the store. 
const response: ContactsResponse = await fetch(...);
const store = new RemoteUiEditorStore(response.definition, response.value);
// Display the editor form for the data received from the C# server.
const App = observer((props: { }) => {
 return <RemoteUiEditor store={store} />
});
const root = document.createElement("div");
document.body.append(root);
ReactDOM.render(<App />, root);
// To validate and send the save request containing the modified
// Contacts model to the server, extract the form data as follows:
const contacts = await store.getDataAsync();

Features

RemoteUi Field Types

RemoteUi allows configuring properties of fields in an editor, such as title, description, nullability, group or field type. Supported field types are: String, Integer, CheckBox, Radio, Select, StringList, List, Number, FileBase64, Custom, TextArea, OrderedMultiSelect. RemoteUi is able to infer most types based on C# primitive types from standard library, so in most cases you don't have to specify the type explicitly.

public class SampleRemoteUiDto
{
 [RemoteUiField(
 "Property title",
 Type = RemoteUiFieldType.String,
 Description = "Property description, can contain long messages.",
 Nullable = false)]
 public string TextField { get; set; } = string.Empty;
 [RemoteUiField("CheckBox")] // RemoteUiFieldType.CheckBox
 public bool BooleanField { get; set; }
 [RemoteUiField("Integer")] // RemoteUiFieldType.Integer
 public int IntegerField { get; set; }
 [RemoteUiField("Number")] // RemoteUiFieldType.Number
 public double DoubleField { get; set; }
}

For a Select field, you can provide possible options via RemoteUiRadioValue attributes:

public class SampleRemoteUiDto
{
 [RemoteUiRadioValue("id-1", "First possible value")]
 [RemoteUiRadioValue("id-2", "Second possible value")]
 [RemoteUiField("Property title", Type = RemoteUiFieldType.Select)]
 public string Option { get; set; } = "id-1";
}

Additionally, RemoteUi allows loading possible Select options dynamically:

public class SampleRemoteUiDto
{
 [SelectOptionProvider]
 [RemoteUiField("One option from a given set", Type = RemoteUiFieldType.Select)]
 public string Option { get; set; } = "anon";
 public class SelectOptionProvider : RemoteUiCustomRadioValuesAttribute
 {
 // The IServiceProvider parameter denotes an instance of the service provider you pass
 // into the RemoteUiBuilder<T>.Build method when configuring RemoteUi.
 public override IEnumerable<KeyValuePair<string, string>> Get(IServiceProvider services)
 {
 return new Dictionary<string, string>
 {
 {"id-1", "First possble value"},
 {"id-2", "Second possble value"},
 };
 }
 }
}

There is also a useful OrderedMultiSelect field type that allows selecting multiple values obtained from a provider that inherits from RemoteUiCustomRadioValues. The values selected via OrderedMultiSelect are kept in a deterministic order defined by a user. See an example:

public class SampleRemoteUiDto
{
 [SelectOptionProvider]
 [RemoteUiField("Multiple options from a given set", Type = RemoteUiFieldType.OrderedMultiSelect)]
 public List<string> Options { get; set; } = new List<string>();
 public class SelectOptionProvider : RemoteUiCustomRadioValuesAttribute
 {
 // The IServiceProvider parameter denotes an instance of the service provider you pass
 // into the RemoteUiBuilder<T>.Build method when configuring RemoteUi.
 public override IEnumerable<KeyValuePair<string, string>> Get(IServiceProvider services)
 {
 return new Dictionary<string, string>
 {
 {"id-1", "First possble value"},
 {"id-2", "Second possble value"},
 };
 }
 }
}

The example above results into the following UI:

image

RemoteUi Builder Configuration

In case if you'd like to support multiple languages in your application, you can pass dictionary keys to Title and Description attribute properties when defining a RemoteUiField. Then, pass a displayTransform parameter of type Func<string, string> to the RemoteUiBuilder constructor:

var builder = new RemoteUiBuilder<Contacts>(
 displayTransform: key => language[key])
 .Register<Contacts>();

If you are using a custom naming strategy in your C# APIs, you can override the naming strategy used during RemoteUi definition generation. Just pass a namingStrategy parameter to the RemoteUiBuilder constructor:

var builder = new RemoteUiBuilder<Contacts>(
 namingStrategy: new CamelCaseNamingStrategy())
 .Register<Contacts>();

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /