jQWidgets Forums

jQuery UI Widgets Forums Grid Angular 2 JQX Grid How to add hyperlink to a cell with routerLink

Tagged: 

This topic contains 8 replies, has 4 voices, and was last updated by  ryan.groves 7 years, 1 month ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author

  • amit.dube.ms
    Participant

    I am using Angular 2 JQX Grid. I am giving the column definition as

    let col = {
    datafield: colList[i].field,
    text: colList[i].header,
    width: colList[i].style.width,
    hidden:colList[i].hidden,
    resizable : true,
    editable: false,
    cellsrenderer: (row, columnfield, value, defaulthtml, columnproperties) => {
    return ‘‘+ value+’
    }
    }

    The routerLink tag gets rendered as it is in the grid


    amit.dube.ms
    Participant

    I am trying to include a hyperlink in one column of JQX Grid (Angular 2 Component), however, it seems if the routerLink Attribute Directive is used in cellrenderer function of Grid Column, it gets rendered as it is and link could not be navigated.

    Is there any way to include router link in the column definition

    Or any other way to create a link which navigates to angular route


    Ivo Zhulev
    Participant

    Hi amit.dube.ms,

    Can you please show me how you include it?

    Best Regards,
    Ivo

    jQWidgets Team
    http://www.jqwidgets.com/


    amit.dube.ms
    Participant

    Column Definition in typescript

    let col = {
                    datafield: colList[i].field,
                    text: colList[i].header,
                    width: colList[i].style.width,
                    hidden:colList[i].hidden,
                    resizable : true,
                    editable: false,
                    cellsrenderer: (row, columnfield, value, defaulthtml, columnproperties) => {
    
                    }
                }
                if(colList[i].field === 'tktNo'){
                    col.cellsrenderer = (row?: Number, columnfield?: String, value?: any, defaulthtml?: String, columnproperties?: any, rowdata?: any) => {
    
                        return "<a [routerLink]=['/wmlsp/ticketdetail/" + rowdata.tktId +"']>"+ value +"</a>";
                    }
                }

    Source definition

    this.gridSource=
               {
                    datatype: "array",
                    datafields: datafields,
                    id: id,
                    localdata:null
                };
                if(localdata){
                  source.localdata = localdata;
                }

    Grid Widget Creation is done as below

    let dataAdapter = new $.jqx.dataAdapter(this.gridSource);
       this.gridSettings.source = dataAdapter;
       this.ticketsGrid.createWidget(this.gridSettings);

    Ivo Zhulev
    Participant

    Hi amit.dube.ms,

    I’ve made a simple grid and added it(the grid is created in the basic way,as in our examples) and it renders okey.
    Try that way.

    Best Regards,
    Ivo

    jQWidgets Team
    http://www.jqwidgets.com/


    ryan.groves
    Participant

    I am experiencing this same issue. This post is over 1 year old, but figured I would post my issue here, since it is the same topic.

    My app is using angular routing to create a spa. I have implemented the jQWidgets grid component (jqxGridComponent). I need to render a hyperlink in a cell, which that hyperlink needs to use the [routerLink] property on the anchor element, so that upon user click, the correct routed UI component is displayed in the router outlet without re-bootstrapping the app (i.e. re-launching the app, the reloading the router configuration, etc.). My understanding, per the documentation and Ivo’s comment above, for this to work I must use of the cellsrender function with the grid columns. I implemented the cellsrender function and the hyperlink does not work, meaning, the user click is not using the angular routing to display the routed UI component in the router outlet. The user click does nothing. The [routerLink] property appears to be disregarded. I have inspected the cell element in chrome and verified the routerLink property is there, but just does nothing.

    I built a simplified grid example to illustrate this issue. The code is below. This issue also applies to the jqxDataTableComponent. Please review the code below and provide your response to resolve this issue. Thank you in advance!

    Environment
    • Angular v2.3
    • Angular Router v3.3
    • jQWidgets v4.5.3
    • Device type: PC
    • Browser: Chrome 65, IE11

    HTML
    <jqxGrid [auto-create]="false" #gridReference></jqxGrid>

    TypeScript

    @ViewChild('gridReference') mygrid: jqxGridComponent;
        private data = new Array();
        dataAdapter;
    
        ngAfterViewInit(): void {
    
            var firstNames =
                [
                    "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene"
                ];
            var lastNames =
                [
                    "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier"
                ];
            var productNames =
                [
                    "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Cramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist"
                ];
            var priceValues =
                [
                    "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0"
                ];
            for (var i = 0; i < 50; i++) {
                var row = {};
                var productindex = Math.floor(Math.random() * productNames.length);
                var price = parseFloat(priceValues[productindex]);
                var quantity = 1 + Math.round(Math.random() * 10);
                row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)];
                row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)];
                row["productname"] = productNames[productindex];
                row["price"] = price;
                row["quantity"] = quantity;
                row["total"] = new Number(price * quantity).toFixed(2);
                this.data[i] = row;
            }
            var source =
                {
                    localdata: this.data,
                    datatype: "array"
                };
            this.dataAdapter = new $.jqx.dataAdapter(source);
    
            var cellsrenderer = function (row, column, value) {
                return '<div style="text-align: center; margin-top: 5px;">' + value + '</div>';
            }
    
            var linkrenderer = function (row, column, value) {
                return "<a [routerLink]=['/home/admin'] title='link test'>" + value + "</a>";
            }
    
            var columnrenderer = function (value) {
                return '<div style="text-align: center; margin-top: 5px;">' + value + '</div>';
            }
    
            let gridsettings: jqwidgets.GridOptions = {
                width: 850,
                source: this.dataAdapter,
                pageable: true,
                autoheight: true,
                sortable: true,
                altrows: true,
                enabletooltips: true,
                editable: false,
                selectionmode: 'multiplecellsadvanced',            
                columns: [
                    { text: 'First Name', dataField: 'firstname', renderer: columnrenderer, cellsrenderer: cellsrenderer, width: 100 },
                    { text: 'Last Name', dataField: 'lastname', renderer: columnrenderer, cellsrenderer: cellsrenderer, width: 100 },
                    { text: 'Product', dataField: 'productname', renderer: columnrenderer, cellsrenderer: linkrenderer, width: 180 },
                    { text: 'Quantity', dataField: 'quantity', renderer: columnrenderer, cellsrenderer: cellsrenderer, width: 80 },
                    { text: 'Unit Price', dataField: 'price', renderer: columnrenderer, cellsrenderer: cellsrenderer, width: 90 },
                    { text: 'Total', dataField: 'total', renderer: columnrenderer, cellsrenderer: cellsrenderer, width: 90 }
                ]
            };
    
            this.mygrid.createComponent(gridsettings);
    
       }

    Stanislav
    Participant

    Hello ryan,

    Here is an example:

    app.component.ts

    
     source: any =
        {
            datatype: 'xml',
            datafields: [
                { name: 'title', type: 'string' },
                { name: 'link', type: 'string' },
                { name: 'pubDate', type: 'date' },
                { name: 'creator', map: 'dc\\:creator', type: 'string' },
            ],
            root: 'channel',
            record: 'item',
            url: '../assets/sampledata/feed.xml'
        };
    
        dataAdapter: any = new jqx.dataAdapter(this.source);
    
        linkrenderer = (row: number, column: any, value: any): any => {
            if (row == 0) {
                let format = { target: '"_self"' };
                let value = 'myLink';
                let html = jqx.dataFormat.formatlink('test', format);
                return html;
            } else if (row == 1){
                let format = { target: '"_self"' };
                let value = 'Third';
                let html = jqx.dataFormat.formatlink('third', format);
                return html;
            } else if (row == 2) {
                let format = { target: '"_self"' };
                let value = 'value';
                let html = jqx.dataFormat.formatlink('home', format);
                return html;
            } else {
                let format = { target: '"_self"' };
                let html = jqx.dataFormat.formatlink(value, format);
                return html;
            }
        }
    
        columns: any[] =
        [
            { text: 'Link', datafield: 'link', width: 550, cellsrenderer: this.linkrenderer },
            { text: 'Title', datafield: 'title', width: 200 },
            { text: 'Publish Date', datafield: 'pubDate', width: 250, cellsformat: 'D' },
            { text: 'Creator', datafield: 'creator', width: 200 }
        ];
    

    app.component.html

    
    <div style="font-size: 13px; font-family: Verdana; float: left">
    
        <jqxGrid [width]="850" [source]="dataAdapter" [columns]="columns"
                 [pageable]="true" [autorowheight]="true">
        </jqxGrid>
    
    </div>
    <nav>
        <a routerLink ='/home'>value</a>
    </nav>
    
    <nav>
        <a routerLink='/test'>myLink</a>
    </nav>
    
    <nav>
        <a routerLink='/third'>Third</a>
    </nav>
    <router-outlet routerLink='/myHome'></router-outlet>
    

    routing.module:

    
    import { RouterModule, Routes } from '@angular/router';
    import { FirstLinksComponent } from './firstlink.component';
    import { SecondLinkComponent } from './secondlink.component';
    import { ThirdLinkComponent } from './thirdlink.component';
    
    const appRoutes: Routes = [
    
        { path: '', redirectTo: '/home', pathMatch: 'full' },
        {
            path: 'home',
            component: FirstLinksComponent
        },
        {
            path: 'test',
            component: SecondLinkComponent
        },
        {
            path: 'third',
            component: ThirdLinkComponent
        }
       
    ];
    
    export const RoutingModule = RouterModule.forRoot(appRoutes, {
        useHash: false
    });
    
    export const appRoutingProviders: any[] = [
    ];
    

    firstlink.component.ts:

    
    import { Component, ViewChild } from '@angular/core';
    
    @Component({
        selector: 'FirstLink',
        templateUrl: 

    <div class=”view-style”>
    Text {{component}}
    </div>
    `
    })

    export class FirstLinksComponent {
    component: string = ‘First Link Component’;
    }

    
    
    secondlink.component.ts
    

    import { Component, ViewChild } from ‘@angular/core’;

    @Component({
    selector: ‘SecondLink’,
    templateUrl: ‘./testlinks.component.html’
    })

    export class SecondLinkComponent {
    component: string = ‘This is my second link!’;
    }

    
    
    thirdlink.component.ts:
    

    import { Component, ViewChild } from ‘@angular/core’;

    @Component({
    selector: ‘ThirdLink’,
    templateUrl: ‘./thirdlink.component.html’
    })

    export class ThirdLinkComponent {
    component: string = ‘Third Link of the Grid.’;
    }
    `

    Best Regards,
    Stanislav

    jQWidgets Team
    http://www.jqwidgets.com/


    ryan.groves
    Participant

    Hello Stanislav,

    The solution example you provided does not use the [routerLink] attribute property to bind the route path. Instead your solution example is using the href attribute property. If you render your solution example and then inspect the hyperlink element, you will see the following: home. This is an unacceptable solution, because it does not use Angular routing.

    The solution I am looking for is when I inspect the hyperlink element, I will see the following: home. As mentioned earlier, the solution must use the industry standard HTML5 style URLs (useHash: false) and not the hash-based style URLs (useHash: true).

    Can you please provide a solution example for this?

    We have been discussing this for over 2 weeks, so this is becoming frustrating. This is a basic core feature in Angular, so this should not be difficult to support.


    ryan.groves
    Participant

    Re-posting with proper code formatting…

    Hello Stanislav,

    The solution example you provided does not use the [routerLink] attribute property to bind the route path. Instead your solution example is using the href attribute property. If you render your solution example and then inspect the hyperlink element, you will see the following: <a target="_self" href="home">home</a>. This is an unacceptable solution, because it does not use Angular routing.

    The solution I am looking for is when I inspect the hyperlink element, I will see the following: <a [routerLink]="home">home</a>. The solution must use the industry standard HTML5 style URLs (useHash: false) and not the hash-based style URLs (useHash: true).

    Can you please provide a solution example for this?

    We have been discussing this for over 2 weeks, so this is becoming frustrating. This is a basic core feature in Angular, so this should not be difficult to support.

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.