How to call Angular 4 method in HTML code generated by jQuery?

Asked

Viewed 529 times

0

I’m using a template I bought made in Angular, but not everything in Angular has a lot in jQuery.

I’m using jQuery’s Datatable (because it’s already native to the template, it has all the css ready and even is already searching the data and paging), but I need some actions in some elements that I need (want) to be processed by angular. How to mark a checkbox for example.

I am using the fnRowCallback from Datatable to handle html. In the example below I would like to change the checkbox state (html generated by the plugin in jQuery) the data to be sent to the changePropertyEnabled method (Angular component method)

...,
fnRowCallback: function (nRow, aData, iDisplayIndex) {
        const mDataEnabled = '<label class="ui-switch switch-icon">' +
          '<input type="checkbox" (change)="changePropertyEnabled(1, false)">' +
          '<span></span>' +
          '</label>';
        const mDataRemoveIcon = '<a class="text-muted font-16" href="javascript:;"><i class="ti-trash"></i></a>';
        //
        $('td:eq(0)', nRow).html(mDataEnabled);
        $('td:eq(6)', nRow).html(mDataRemoveIcon);
        return nRow;
      },
 ...


 changePropertyEnabled(id: number, enabled: boolean) {
    alert('Hello World');
  }
  • Is your HTML generating normally? Why your call with (change)="changePropertyEnabled(1, false)" is correct. And there is some specific reason that you are dynamically generating this HTML by function? You could create it normally and use a *NgIf on the call of the same.

  • It is generating yes, but the change does not work. I just found a solution now little, but I do not know if it is the best way. I used static html just to test even.

  • Because then, maybe this HTML that he manages Angular is not able to handle in the node that he created, consequently not treating the change but that’s an assumption. Maybe generating it without being static is a good try.

  • @Patricklima is just that.

1 answer

0

I was able to solve it this way:

ngAfterViewInit(): void {
    const self = this;
    const dtAccount = $('#dt-account');
    dtAccount.DataTable({
      pageLength: 10,
      fixedHeader: true,
      responsive: true,
      processing: true,
      serverSide: true,
      ajax: {
        url: this.api.getBaseUri('/service/v1/accounts'),
        type: 'POST'
      },
      fnRowCallback: function (nRow, aData, iDisplayIndex) {
        const mDataEnabled = '<label class="ui-switch switch-icon">' +
          '<input type="checkbox">' +
          '<span></span>' +
          '</label>';
        const mDataRemoveIcon = '<button class="btn btn-outline-danger btn-icon-only btn-circle btn-sm btn-thick dt-remove-icon">' +
          '<i class="ti-trash"></i>' +
          '</button>';
        //
        const mAccount = new Account();
        mAccount.fromObject(aData);
        // Custom fields
        $('td:eq(0)', nRow).html(mDataEnabled);
        $('td:eq(6)', nRow).html(mDataRemoveIcon);
        // Enabled button
        const mInputEnabled = $('td:eq(0)', nRow).find('input');
        mInputEnabled.prop('checked', mAccount.enabled);
        mInputEnabled.change(function (e) {
          mAccount.enabled = $(this).prop('checked');
          self.changePropertyEnabled(mAccount);
        });​
        // Remove button
        const mButtonRemove = $('td:eq(6)', nRow).find('.dt-remove-icon');
        mButtonRemove.click(function (e) {
          self.deleteAccount(mAccount);
        });​
        return nRow;
      },
      columns: [
        {'data': 'enabled'},
        {'data': 'firstName'},
        {'data': 'lastName'},
        {'data': 'email'},
        {'data': 'created'},
        {'data': 'modified'},
        {'data': 'id'}
      ],
      'sDom': 'rtip',
      columnDefs: [{
        targets: 'no-sort',
        orderable: false
      }]
    });

With this I kept the self to be a reference for my component, to use both in angular calls and in jQuery

const self = this;

Set in mDataEnabled the enable button

const mDataEnabled = '<label class="ui-switch switch-icon">' +
              '<input type="checkbox">' +
              '<span></span>' +
              '</label>';

I created a static HTML that wasn’t being manipulated by Angular and inserted it into html

 $('td:eq(0)', nRow).html(mDataEnabled);

I used jQuery to retrieve the element I wanted to manipulate (input)

 const mInputEnabled = $('td:eq(0)', nRow).find('input');

I added the logic of manipulation I wanted

 mInputEnabled.change(function (e) {
          mAccount.enabled = $(this).prop('checked');
          self.changePropertyEnabled(mAccount);
        });​

I used the self to talk to relate the element processed by jQuery to Angular Component.

 self.changePropertyEnabled(mAccount);

I don’t know if it’s the best way, but it worked. If there’s another better way to do it, just post it and I’ll thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.