0

I have a vaadin-grid in my angular2 project with different columns like (column heder: firstname, lastname, age, city, country). I'm trying for the functionality to hide and show a lastname column. whenever i clicked on column header of firsname then only the lastname column has to hide/show in the vaadin-grid.

Can any one help me to acheive my task.

Thank you.

app.html

      <h2>hello</h2>
            <vaadin-grid>
            <table>
                <colgroup>
                    <col name="Name" click="res()">
                    <col name="Value">
                    <col name="Progress" hidable>
                </colgroup>

                <tbody>
                    <tr>
                        <td>Project A</td>
                        <td>10000</td>
                        <td>0.8</td>
                    </tr>
                    <tr>
                        <td>Project B</td>
                        <td>999999</td>
                        <td>0.8</td>
                    </tr>
                </tbody>
            </table>
        </vaadin-grid>

app.component.ts

    import { Component } from '@angular/core';
import { PolymerElement } from '@vaadin/angular2-polymer';


@Component({
  selector: 'my-app',
  templateUrl: 'app/app.html',

    styles: [`
                vaadin-grid {
                    height: 100%;
                }
          `],
    directives: [
        PolymerElement('vaadin-grid')
    ]
})
export class AppComponent {
    res(){
        console.log("hi tis is method");

    }
 }
Nunna Suma
  • 469
  • 1
  • 11
  • 23

2 Answers2

1

Such a use case of the <vaadin-grid> element will make a bad UX. The headers of the grid are not designed to be clickable by default. Therefore they look inactive, so the user will not think of them as of clickable links or buttons.

As for the Vaadin Grid, please consider making the columns hidable by specifying the <col hidable> attribute. This will enable user to toggle the displayed columns by selecting those in a nice drop-down menu on the right of the grid header. See the Hiding Columns section in the grid documentation for an example.

If you want to toggle between different contents with a single click, it would be better to use the elements specifically designed for that instead, for example, <paper-tabs>.


Solution in Plunker: https://plnkr.co/edit/Sz92H4?p=preview

Your use case was difficult to implement, because the requirements are not designed in the Vaadin Grid API as well. I had to apply some unpleasant workarounds in order to achieve it. Please use the solution for learning rather than blindly copying the code. The caveats are explained below.

How to bind for the grid header click event

First of all, in Vaadin Grid, the DOM contents are not dynamic. They are treated as an initial configuration, and they are not used directly as the grid contents. Therefore, you can not bind the header click in the template.

In my solution, we attach the event listener on the grid itself. After catching a click on the grid, we need to manually determine if the header was clicked and find the clicked column index. In order to do that, we:

  1. Get the event target reference. The click happens somewhere in the local DOM of the grid. event.target will return the grid instead of the actual event target if Polymer uses Shadow DOM (disabled by default). Use Polymer API to ensure to have the correct target regardless of Polymer settings:

    var target: Element = (<any> window).Polymer.dom(event).rootTarget;
    
  2. Check the click target and all the elements up in the DOM tree until the end (if Polymer is in Shadow DOM mode) or the grid itself (if Polymer uses Shady DOM, which is the default mode) to find the column header cell element. For this check, we use Polymer API to check the element class name. We set a custom class name for the first name column header in the ngAfterViewInit() method.

    • If the header cell element is found, stop the search and call this.toggleLastNameVisible();.
    • If the header cell element is not found, then it’s not the first name grid header that was clicked. Do nothing.

Note that we want to react on click, but we have to listen for the "mouseup" event on the grid instead of the click event. The reason is that sometimes the grid re-renders its contents after a header click, which breaks the header cell element finding. Mouseup works here, because it is fired before the grid process clicks.

How to programmatically show and hide the columns

Now that we solved the header click binding problem, we have to display the selected column and hide the others. Once again, we can not just bind the <col [hidden]="showOrHide"> attribute in the template, as well as we can not use *ngIf to remove the hidden columns. Because the grid DOM contents are not dynamic.

We had to get the grid element reference and use the grid API:

@ViewChild('grid') gridRef: any;

toggleLastNameVisible(visible?: boolean) {
  this._isLastNameVisible = visible !== undefined ? visible : !this._isLastNameVisible;
  var grid: any = this.gridRef.nativeElement;
  // Assuming that the last name is the second column
  grid.set('columns.1.hidden', !this._isLastNameVisible);
}

Note that the ref is added in the template: <vaadin-grid #grid ...>

You can learn more about the grid API by reading through the Vaadin Grid Documentation and the API Reference. Hope that helps to understand better how the grid works.

Anton Platonov
  • 336
  • 1
  • 5
  • Thank you @AntonPlatonov. I have gone through your code in the plunker but it is not my requirement. My task is a table with columns(First name, Last name, Age, Country) whenever i clicked on firstname column heading then only the lastname column have to show/hide and remaining columns must not be changed/effected by that method. – Nunna Suma Jul 18 '16 at 09:37
  • Sorry, missed that from reading your question. However, now that we know how to bind to the header click and toggle columns, the rest is straitforward. I’ve changed the solution in plunker accordingly. – Anton Platonov Jul 19 '16 at 14:45
0

You can do this on the basis of *ngIf .

use the *ngIf condition on your lastname with a boolean variable as false by default and make it true everytime you click on the first name.

i hope it works for u :)

Akshay Rao
  • 3,454
  • 1
  • 15
  • 19