How can I hide a tab dinamically after partial update?

Hi there,

I have a model where I render a datatable containing associated items; however, when the table is empty, it should hide the other two tabs (Evaluación and Compromisos). I managed to make it work but only on page refresh. I wonder how could I hide the tabs after the ajax event? (whether I add or delete a record)

Hi @danfelbm ,

One approach is to extend the onRelationButtonDelete and onRelationButtonCreate methods and listen for these events. You can check for a specific variable and use JavaScript to hide or remove a particular node—in your case, targeting Evaluaciones and Compromisos.

Example Implementation for onRelationButtonDelete

In the file \Author\Plugin\Controller\Visitas.php, you can implement the following code:

public function onRelationButtonDelete() {
    $recordId = $this->relationObject->getParent()->getKey();
    $model = $this->formFindModelObject($recordId);

    // Call the original method
    $response = $this->asExtension('RelationController')->onRelationButtonDelete();

    if ($this->relationModel instanceof \Author\Plugin\Models\Seguimiento) {
        if (is_array($response)) {
            $response['seguimientosCount'] = $model->seguimientos()->count();
        }
    }

    return $response;
}

Adding JavaScript

Next, include a JavaScript file (or place the code in an existing file):

public function __construct() {
    parent::__construct();
    $this->addJs("/plugins/author/plugin/assets/js/visitas.js");
}

In that JavaScript file, add the following code:

$(function() {
    addEventListener('ajax:update-complete', function(event) {
        const handler = event.detail.context.handler; 
        const data = event.detail.data;

        // Check for the onRelationButtonDelete handler
        if (handler === 'onRelationButtonDelete') {
            // Verify if data exists and data.seguimientosCount is defined
            if (data && data.seguimientosCount !== undefined && data.seguimientosCount <= 0) {
                const link = document.querySelector('inspectToGetYourSelector');
                if (link) {
                    link.classList.add('d-none'); // Add the d-none class to hide the element
                }
            }
        }
    });
});

Repeat for onRelationButtonCreate

You should implement a similar approach for the onRelationButtonCreate method, ensuring to remove the d-none class if the count exceeds 0.

1 Like

Hi danfelbm,
another simplier approach is to use FilterFields method in you model. In there check if your model has child (->withDeferred()) and if has not, you can hide all the fields under the other two tabs. Tabs are hidden if they have not visible fields.

Hi @danielbidala,

If I’m not mistaken, filterFields isn’t triggered when adding or deleting a record. Have you tested this?

Hi apinard,
filterFields method is triggered when you create, add, modify or delete in relation widget.

Hi @danielbidala ,

I invite you to test it (I did). You can easily replicate the case of danfelbm using the test-plugin. You can use the Posts controller with the relation Comments.

Thank you very much @apinard and @danielbidala ! I will test this! I’m using the test-plugin as reference, but sometimes is not easy to find certain small things.
I also found out about relationExtendRefreshResults() and was testing with that too.

I was wondering guys if any of you know how to filter options of an scope based no the current model ID? I tried elaborating here:

But is definitely something I haven’t accomplished yet and I’m a bit lost…

Hi @apinard

take look:

Clip_OCMS_2024-10-03

3 Likes

Hi @danfelbm
i posted a possible solution there.

Yes, it works, and I also prefer this method.

In the form.yaml for the Visita, you can achieve this by adding dependsOn: seguimientos under the evaluaciones , compromisos fields and utilizing the filterFields of the Visita model.

Thanks for coming back with this @danielbidala

1 Like