Two-step form – pre-fill from API

Nguyen dat
Member | 1

Hi, I don't know if it's the right use of MVC but how easy is to do two step form filling?

As an example, I have a form with these input fields:

Serial number
Manufactured date

There would be two buttons. Next to the SN field, there's Lookup. If the SN is in manufacturer's database (available via API), it will get the details and pre-fill the rest of the form. And then there's Save button which will create the record.

I know that ideally it would be done with i.e. Ajax but how would a JS-free implementation work? I can imagine adding functions to a presenter but it could be done smarter – similarly to error handling?

Thank you!

Member | 51

In theory, this is all the code you need as far as presenter (the view layer) is concerned.
In reality, you will want to put the code in appropriate classes so that presenter only serves as a connector that passes variables from parameters (serialNumber in GET) into components (the form via loadDataBySN).

The flow here goes like this:

  • in actionDefault, we check for parameter serialNumber.. If it exists, we try to load data from our storage
  • if we are able to load data, we get the articleForm component and set its defaults to our loaded values
    • the component is retrieved by $this['articleForm'], which in accordance to nette component model creates a Form via the createComponentArticleForm method
  • the createComponentArticleForm creates new instance of plain Form, adds some inputs with validation and most importantly sets the onSuccess callback. this only gets called if the sn is valid..
    • the success callback checks, which submit button was used to submit the form and if it was our ‘load by SN’, we reload current view and set parameter serialNumber for data preloading
    • otherwise, the form must have been submitted by ‘Save button’ so we call saveArticle
  • once all this is done, the presenter renders template productArticle/default.latte in which we request some control named ‘articleForm’ to be rendered
    • this retrieves the component in same manner as when we accessed it via $this['articleForm'], namely the presenter checks, if component with this name exists. If yes, it just returns the already created instance