WebHare community

Add form handler from whlib

There seems no way to add a custom form handler to a form from a whlib.

Use case: every form in the application should use a custom form handler (which mails the results to addresses defined by the backend). Instead of having to add it to every form, we’d like to “just” use the form handler in every form.

We already have a EXTEND WebtoolFormHooks, but is there a way to add a handler? The WebtoolFormBase provides some functions (DeleteHandlerByGUID, ListHandlers(), GetHandlers()) but there seems to be no function to add a handler.

I noticed an AddHandler function in the FormDefinition but that can probably not be used at runtime. Might work for a script that adds the handler to every form, but I’d rather just add it through a whlib; makes the form content cleaner too.

Looping in @Anferney

Form handlers were designed to run asynchronously as much as they can as any code running in the submit handling (where you’ll find ListHandlers etc) delays completion of the RPC and blocks the user (and if the code crashes for whatever reason, you’ve needlessly broken form submission)

To be able to run them asynchronously, they need to have a GUID so we can find them again. If you add them dynamically, we’re not guaranteed to have that GUID, let alone having a stable one.

Anyway, in the end - form handlers are a way to add code to the form’s submit handler. If you’re in WebtoolFormHooks, you’re already in the submit handler - so you’re already where you need to be. Why load code in a roundabout way again ?

If this is not about running your own handler but reusing the code of an existing handler, perhaps it would be easier to factor out the reusable code of that existing handler ?

Problem is that at that point, the results aren’t in the database yet. Unless there’s some way I don’t know about?

If you hook UpdateResultAfterSubmit, they’re already stored and you receive the result guid as one of the parameters

But then I’d still need to add the form handler to the form, right?

We were hoping to avoid that.

You could merge the code in the handler into your form hook ? I was under the impression you were already using <formintegration webtoolformhooks=... />

If the user isn’t going to configure it, why show it at all in the forms?

That’s why we don’t want to show it, but just add the handler at run time (or some other way to get the form results and mail it to some globally set e-mail address).

So, we already have:

PUBLIC OBJECTTYPE BredelFormHooks EXTEND WebtoolFormHooks
<
  UPDATE PUBLIC RECORD FUNCTION Submit(OBJECT work, RECORD extradata)
  {
    // we have this->form->GetResultGuid() here, but not the results

    // no data yet:
    OpenFormFileResults(
      OpenWHFSObject(this->form->formresults->getstorageobject()->id)
        ->GetSingleResult(this->form->GetResultGuid()));
>;

If I add this:

handlerobject=“mod::bredel_apps/webdesigns/bredel/forms/forms.whlib#BredelFormHandler”

with this:

PUBLIC OBJECTTYPE BredelFormHandler EXTEND FormHandlerBase
<
  UPDATE PUBLIC RECORD FUNCTION UpdateResultAfterSubmit(RECORD result)
  {
    abort(result);
    RETURN result;
  }
>;

The code only fires when I add the handler to the form. However, we want to always run this function, with or without the handler added to the form.

Something that would be equivalent to this->form->AddHandlerByGUID or something.

But why aren’t you putting your UPDATE UpdateResultAfterSubmit into your BredelFormHooks ?

oh wait, missed that. thought

  //NOW aftersubmit handlers can do their thing
  FOREVERY (RECORD handler FROM activehandlers)
    result := handler.handlerobject->UpdateResultAfterSubmit(result);
  IF (RecordExists(confirmationhandler))
    result := confirmationhandler.handlerobject->UpdateResultAfterSubmit(result);

was invoking on this->GetHookobject(), not handler.handlerobject

the obvious solution would seem to be to suggest a PR to add UpdateResultAfterSubmit or something similar to the WebtoolFormHooks