1. Fabrik 3.9 has been released. If you have updated Joomla to 3.9, this is a required update.
    Dismiss Notice

Repeat minimum option - need your help

Discussion in 'Community' started by mirceat, Jul 1, 2019.

  1. mirceat

    mirceat Member

    Level: Community
    I have several repeated groups in form that are displayed and hidden based on selections made by the users (default: hidden). In order to not populate the database with empty info, I had to set the "Repeat minimum" option to 0 (zero).

    But in some cases, i need to set the repeat group elements to be visible by default instead of asking user to press the + button. I know that i can set "Repeat minimum" to 1 but this will record an empty row in the table for other users who doesn't see this group.

    Then i tried to unset the group using a php form plugin but every time a element validation failed in form (outside or inside the repeated group), the repeated group set its div to read-only (class="fabrikElementReadOnly")

    this is the code i've used for unset:

    PHP:

    if (JFactory::getApplication()->input->get('task', '') == 'form.process') {
       switch ($groupModel->getId()) {
          case 765:
    foreach ($formModel->formData["contracts_tool_servicii_765_repeat___adresa_anexa_vpn_nou_raw"] as $anexa_vpn) {
                 if ($anexa_vpn == ''){
                 return false;
                 }
       }
         break;
     default:
             return true;
       }
       return true;
    }
    return true;

     
    also tried with $formModel->getElementData('contracts_tool_servicii_765_repeat___adresa_anexa_vpn_nou', true,'',0), same problem.

    So, how can i display the repeated groups element to be visible by default but also stop recording empty rows in tables?

    Thank you
     
  2. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    What hook are you running that PHP plugin on? Like onBeforeProcess, onAfterProcess, etc.

    Typically, by returning false, you'll be aborting form submission, not removing submitted data from the form. But depends what hook it's running on.

    -- hugh
     
  3. mirceat

    mirceat Member

    Level: Community
    i'm using onCanEditGroup. Yes, i need to abord form submission (sending and recording data) for this group if a certain field element is empty/not completed.

    In other words, if mytable___myelement is empty then don't create an empty row in table even if the repeat minimum is set to 1
     
  4. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    Well, to avoid the issue with a failed validation setting the group to read only, try this as the first line:

    Code (Text):

    if (FabrikWorker::inFormProcess() && !$formModel->failedValidation()) {
     
    However ... the way your code is written, if there are multiple repeats of the group, and any of them have that adresa_anexa_vpn_nou field empty, then none of the repeats will be written.

    Is that what you want?

    -- hugh
     
  5. mirceat

    mirceat Member

    Level: Community
    well, you're right, it should unset only the repeated groups that have that field empty...

    usually my fields are having mandatory + conditions, but now i realize sometimes users can optionally write something

    can i use $repeatCounter in this code?
     
  6. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    Nope, because you are relying on the canEdit() check here ...

    https://github.com/Fabrik/fabrik/blob/master/components/com_fabrik/models/form.php#L1860

    ... which controls whether the group model process() happens at all. And handling the multiple repeats happens within the process(). And there aren't any plugin hooks inside process().

    The only way I can think of to do what you need is to use the onBeforeProcess hook, loop through the element you are checking, then if it's empty, unset that repeat count in all the element arrays for the group. Which is kind of a pain, as you either need to specifically modify each one (which means knowing all the elements in the group), or regex the names to find the ones with the right prefix.

    Maybe something like this:

    Code (Text):

    foreach ($formModel->formData["contracts_tool_servicii_765_repeat___adresa_anexa_vpn_nou_raw"] as  $anexa_key => $anexa_vpn) {
       if ($anexa_vpn == ''){
          // found a blank one, so loop through all element ...
          foreach ($formModel->formData as $elName) {
             // find those belonging to this group ...
             if (strstr('contracts_tool_servicii_765_repeat___', $elName)) {
               // unset the appropriate key
                unset($formModel->formData[$elName][$anexa_key];
               // re-index the array to get rid of the key gap
                $formModel->formData[$elName] = array_keys($formModel->formData[$elName]);
               // do the same for the raw values
                unset($formModel->formData[$elName . '_raw'][$anexa_key];
               // re-index the array to get rid of the key gap
                $formModel->formData[$elName . '_raw'] = array_keys($formModel->formData[$elName . '_raw']);
          }
       }
    }
     
    What I'm not entirely sure about in that is what happens in the outer loop, when you modify the array in the inner loop.We're deleting the current index and re-indexing. So I have a feeling that outer loop may wind up skipping the next repeat, or otherwise get its undies in a bundle.

    So you might have to do it a different way, where you have another loop wrapped around the whole thing, and break out to it each time you find a hit and remove an index. Set a "$found = true" when you have a hit, and keep doing the outer loop till $found is false.

    But that's the basic approach ... remove the appropriate index for all elements in the group when you find an empty.

    -- hugh
     

Share This Page