Jump to content

[SOLVED] Settings fields that don't save to database


jploch
 Share

Recommended Posts

Hey there!

Iam working on a module (pagebuilder based on pagetable) that creates fields on install and adds them to a template, so the user don't have to create those fields manually. I don't need these fields to be saved in database, they are just used to generate and save some settings in a textarea field on that page (my module saves css values based on breakpoints and I don't want to create fields for every breakpoint, so I just use the fields to manipulate the css and than save all the css in one textarea).

So my question is, if it will be bad for performance or bad practice to save all these fields to the database, even if I don't need them there?
Or is there a way to create fields that don't save to bd?

I could just insert the field markup with JS, but that would only work for certain admin themes and is kind of hacky. I hope this makes sense ?

Link to comment
Share on other sites

If I understand you correctly, you only need the inputfields to appear in the form, but you don't need actual tables in the database for persistent storage for those fields? In this case, I wouldn't create a new field at all, but instead add the inputfields you want using hooks. For custom inputs / markup you can use InputfieldMarkup, for everything else use the appropriate Inputfield module. This should work in any ProcessWire form context. For example, here's a hook that adds my InputfieldHCaptcha module to the edit form of a page in the backend:

wire()->addHookAfter('ProcessPageEdit::buildForm', function (HookEvent $event) {
    $form = $event->return;
    $submitButton = $form->getChildByName('submit_save');
    if ($submitButton) {
        $hCaptcha = $event->wire('modules')->get('InputfieldHCaptcha');
        $hCaptcha->set('label', __('Spam Protection'));
        // ... configuration goes here
        $form->insertBefore($hCaptcha, $submitButton);
    }
    $event->return = $form;
});

See InputfieldHCaptcha. Like that you should be able to add any inputfield you want to the form. This approach has the added benefit that you don't leave behind dead fields after your module is uninstalled.

  • Like 3
Link to comment
Share on other sites

33 minutes ago, MoritzLost said:

If I understand you correctly, you only need the inputfields to appear in the form, but you don't need actual tables in the database for persistent storage for those fields

Thanks @MoritzLost ! yep thats what I meant. So just to understand your approach better. You insert the fields after buildForm so they won't get saved to bd when the page is saved? This would be called everytime the page is loaded, wouldn't this be bad for performance with a lot of fields?

  • Like 1
Link to comment
Share on other sites

@jploch Exactly! Regular ProcessWire fields have both a fieldtype (responsible for storing stuff in the database) and an inputfield (responsible for displaying the input form element, validating the input etc). The hCaptcha module only comes with an inputfield without a corresponding fieldtype, because the captcha response doesn't really need to be stored. The module just needs to display some markup in the frontend and validate the input after submission, which is both done in the inputfield. Because you can't create a regular ProcessWire field without a corresponding fieldtype and database table (at least as far as I'm aware), an instance of the inputfield is inserted in the edit form through a hook.

Quote

This would be called everytime the page is loaded, wouldn't this be bad for performance with a lot of fields?

I don't think it will make any noticable difference, since the the inputfields need to be constructed for each page load anyway, regardless of whether they come from regular fields or a hook. Maybe a super tiny overhead because of the hook, but then we're talking nanoseconds ?

  • Like 2
Link to comment
Share on other sites

this looks like a good fit for my usecase! Now I hit another roadblock. I want the fields to be grouped together in a fieldset that can be collapsed. How would I do this with the inputfields approach? 

EDIT:
Figured it out, here is my final code:

$this->addHookAfter('ProcessPageEdit::buildForm', function (HookEvent $event) {
            
    $form = $event->return;
    $page = $event->object->getPage();
            
    // make sure we're editing a page and not a user
    if ($event->process != 'ProcessPageEdit') return;
    if (!$page->template->hasField("pgrid")) return;
     
    $submitButton = $form->getChildByName('submit_save');
    if ($submitButton) {
      
     $fieldset = $event->wire('modules')->get('InputfieldFieldset');
     $fieldset->label = 'Fieldset Test';

     $field1 = $event->wire('modules')->get('InputfieldText');
     $field1->set('label', __('Test123'));
     $field1->set('name', __('test123'));
     $field1->addClass('test123');
     $fieldset->append($field1); // append the field
      
      $form->insertBefore($fieldset, $submitButton);
    }
    $event->return = $form;
});

@MoritzLost thanks again for your help, this was very helpful!

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...