dsuryd/dotNetify-Elements

[Elements] Is it possible to access the VMContext state outside of an Element component?

tjackadams opened this issue ยท 3 comments

Great Library i must say ๐Ÿ‘

I am building a Form and this is how i want the workflow to look.

Submit Form > display a progress/loading indicator > redirect to another page using the form response.

So far i have the form submitting fine. For the second step, i think it could be solved by adding a bool property onto the ViewModel and performing a conditional render on the client.
But if i have a property like "SubmitInProgress", how would i then access this from the React Component?

The third step, i already have the ServerReponse outputting to an Alert component, but again ideally i would need this property in a function. I can't see in the documentation, but does the form have anything like onSuccess function? where you can access the response?

Here is the code for reference

import React, { Component } from "react";
import dotnetify from "dotnetify";
import {
  Alert,
  Button,
  Form,
  Panel,
  TextField,
  VMContext,
  withTheme
} from "dotnetify-elements";
import MuiButton from "@material-ui/core/Button";
import MuiTextField from "@material-ui/core/TextField";

const TrialFormContainer = props => (
  <VMContext vm="NewTrialForm">
    <Form>
      <Alert id="ServerResponse" />
      <Panel>
        <TextField id="FirstName" inputComponent={MuiTextField} />
        <TextField id="LastName" inputComponent={MuiTextField} />
        <TextField id="EmailAddress" inputComponent={MuiTextField} />
        <TextField id="Company" inputComponent={MuiTextField} />
        <TextField id="PhoneNumber" inputComponent={MuiTextField} />
        <Button id="ActivateTrial" inputComponent={MuiButton} submit />
      </Panel>
    </Form>
  </VMContext>
);

export default withTheme(TrialFormContainer);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotNetify;
using DotNetify.Elements;
using Newtonsoft.Json;

namespace One.Veeam.Web.Model
{
    public class NewTrialForm : BaseVM
    {
        private class FormData
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string EmailAddress { get; set; }
            public string Company { get; set; }
            public string PhoneNumber { get; set; }
        }

        public NewTrialForm()
        {
            AddProperty<string>("FirstName")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "First Name",
                    MaxLength = 20
                })
                .WithMinValidation(2)
                .WithMaxValidation(20)
                .WithRequiredValidation();

            AddProperty<string>("LastName")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Last Name",
                    MaxLength = 20
                })
                .WithMinValidation(2)
                .WithMaxValidation(20)
                .WithRequiredValidation();

            AddProperty<string>("EmailAddress")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Email Address",
                    MaxLength = 50
                })
                .WithMinValidation(3)
                .WithMaxValidation(50)
                .WithPatternValidation(Pattern.Email, "Please enter a valid email address.")
                .WithRequiredValidation();

            AddProperty<string>("Company")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Company Name",
                    MaxLength = 100
                })
                .WithMinValidation(2)
                .WithMaxValidation(100)
                .WithServerValidation(ValidateCompanyNotRegistered, "Only one Trial allowed per Company.")
                .WithRequiredValidation();

            AddProperty<string>("PhoneNumber")
                .WithAttribute(new TextFieldAttribute
                {
                    Label = "Phone Number",
                    MaxLength = 25
                })
                .WithMinValidation(8)
               // .WithMaxValidation(25)
                .WithRequiredValidation();

            AddProperty<FormData>("ActivateTrial")
                .WithAttribute(new { Label = "Active Free Trial" })
                .SubscribedBy(
                    AddProperty<string>("ServerResponse"), submittedData => Save(submittedData));

        }

        private string Save(FormData data)
        {
            // post it to veeam
            // return the username and password
            // fire off emails

            return JsonConvert.SerializeObject(new
            {
                username = "User1",
                password = "12345"
            });
        }

        private bool ValidateCompanyNotRegistered(string company)
        {
            // check the company is not registered
           return true;
        }
    }
}


Thanks in advance!

Hi, VMContext has a property called onStateChange to provide access to incoming server data (#7)

Example:

 <VMContext vm="TestVM" onStateChange={state => this.setState({ currentId: state.IdToLoad })}>

For loading indicator, I recommend doing it client-side by handling the onSubmit property of the Form.

Thanks @dsuryd .
onStateChange is exactly what i was looking for, i was just looking in the wrong repo.