Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ngTemplateRef does not work on responsive windows-mode when columns are stacked #1772

Open
lingold-gseb opened this issue Feb 29, 2024 · 3 comments
Assignees
Labels
bug pinned Issues to be ignored by Stalebot

Comments

@lingold-gseb
Copy link

lingold-gseb commented Feb 29, 2024

🪲 bug report

When I use the responsive extension, it only shows the plain text from the source and not the template-version if the windows size is in responsive mode. Back in full window size mode the template is rendered as expected.

Is there a way to fix my problem with code adjustments or is this a bug? Thanks for the support!

🔬 Minimal Reproduction

StackBlitz/GitHub Link:
https://stackblitz.com/edit/stackblitz-starters-rx7mzq?file=package.json
Step-by-step Instructions:
Minimize and maximize the window on StackBlitz to see the difference.

🎱 Expected behavior

The ngTemplateRef column should display the referenced template and not the pure rendered text from the source, in the same way as it displays the content for non-stacked/-responsive views.

📷 Screenshots

Normal View - component shown:
image
Responsive - plain data text shown:
image

📝 Additional context

see closed issue: #1723
columnDefs does not solve the issue with the rendering on responsive mode.

@shanmukhateja
Copy link
Collaborator

Hi @lingold-gseb

Can you try redrawing the table on https://datatables.net/reference/event/responsive-resize or https://datatables.net/reference/event/responsive-display?

I suspect this happens because responsive plugin resets the transform we apply on the table's cell during init.

@shanmukhateja shanmukhateja self-assigned this Mar 6, 2024
@lingold-gseb
Copy link
Author

lingold-gseb commented Mar 7, 2024

Hi @shanmukhateja
thanks for the answer! I tried to redraw the table on the suggested events, but it has no effect on the correct rendering of the templates in responsive mode. See ngAfterViewInit-method in https://stackblitz.com/edit/stackblitz-starters-yg83ku?file=src%2Fexample%2Fexample.component.ts

dtInstance.on(
          'responsive-resize',
          (e: any, datatable: any, columns: any) => {
            const count = columns.reduce((a: any, b: any) => {
              return b === false ? a + 1 : a;
            }, 0);

            console.log(count + ' column(s) are hidden');
            dtInstance.draw();
            console.log('called draw()');
          }
        );
      });

Is there a mistake in my implementation of the redraw-approach or do you have another idea how to solve the problem?
A thought perhaps: If the page is initially loaded in a minimized responsive window, the elements already will not load correctly.

Thanks!

@shanmukhateja
Copy link
Collaborator

shanmukhateja commented Mar 16, 2024

@lingold-gseb Hi sorry for the late reply.

In that case, could you try dtTrigger.next() instead of dtInstance.draw()?

The goal is to force a redraw of the table.

I think we need to investigate a way to use something like "before cell draw" callback (if it exists) and trigger our custom transformations for TemplateRef or Pipe.

Edit: I spent a few hours on this and I believe I have a solution. Are you comfortable with compiling the library locally?

// Replace the function with the same name inside "src/angular-datatables.directive.ts"

private applyNgRefTemplate(row: Node, columns: ADTColumns[], data: Object): void {
    // Filter columns using `ngTemplateRef`
    const colsWithTemplate = columns.filter(x => x.ngTemplateRef && !x.ngPipeInstance);
    colsWithTemplate.forEach(el => {
      const { ref, context } = el.ngTemplateRef;
      // get <td> element which holds data using index
      const i = columns.filter(c => c.visible !== false).findIndex(e => e.id === el.id);
      let cellFromIndex = row.childNodes.item(i);
      // Responsive plugin messes with table columns
      // The code below will trigger when `rowChild` is about to be initialized.
      if (!cellFromIndex && this.dtOptions.responsive) {
        try {
          const rowChildParent = this.dt.row(row).child();
          if (rowChildParent) {
            // now we need to locate the <td> which has the matching column index
            const objListFromIndex = rowChildParent.first().find(`*[data-dtr-index="${i}"]`)?.find('.dtr-data');
            if (objListFromIndex.length > 0) {
              cellFromIndex = objListFromIndex.get()[0];
            }
          }
        } catch (ignore) {}
      }
      // reset cell before applying transform
      $(cellFromIndex).html('');
      // render onto DOM
      // finalize context to be sent to user
      const _context = Object.assign({}, context, context?.userData, {
        adtData: data
      });
      const instance = this.vcr.createEmbeddedView(ref, _context);
      this.renderer.appendChild(cellFromIndex, instance.rootNodes[0]);
    });
  }

Let me know if this works :)

@shanmukhateja shanmukhateja added the pinned Issues to be ignored by Stalebot label Jul 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug pinned Issues to be ignored by Stalebot
Projects
None yet
Development

No branches or pull requests

2 participants