Problems with using link elements nested in td elements and using select dropdown filters

Problems with using link elements nested in td elements and using select dropdown filters

data100data100 Posts: 3Questions: 1Answers: 0
edited December 2016 in Free community support

Hello,

When I try to use a link in a <td>, part of the link is used as the value in the <option> for the <select> dropdown filter. I would like to have a different link for every <td> for each <tr>. Below is my code. The dropdown filter for the Office column has the options:

Edinburgh">Edinburgh
London">London

instead of just:

Edinburgh
London

<!DOCTYPE html>
<html>
<head>
    <title>DataTable</title>

    <!-- jQuery Google CDN -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    
    <!-- DataTable JavaScript CDN -->
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.js"></script>
    
    <!-- DataTable Responsive JavaScript CDN Link -->
    <script src="https://cdn.datatables.net/responsive/2.1.1/js/dataTables.responsive.min.js"></script>

    <!-- DataTable Responsive CSS CDN Link -->

    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css">

    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.1.1/css/responsive.dataTables.min.css">
</head>

<body>
<table id="example" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>

        <tfoot>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>

        <tbody>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td><a href="edinburghOffice.html">Edinburgh</a></td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
            </tr>
            <tr>
                <td>Bill Green</td>
                <td>Programmer</td>
                <td><a href="londonOffice.html">London</a></td>
                <td>32</td>
                <td>2014/05/22</td>
                <td>$150,000</td>
            </tr>
        </tbody>
    </table>

<script>
    $(document).ready(function() {
        $('#example').DataTable( {
            initComplete: function () {
                this.api().columns().every( function () {
                    var column = this;
                    var select = $('<select><option value=""></option></select>')
                        .appendTo( $(column.footer()).empty() )
                        .on( 'change', function () {
                            var val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                            );
     
                            column
                                .search( val ? '^'+val+'$' : '', true, false )
                                .draw();
                        } );
     
                    column.data().unique().sort().each( function ( d, j ) {
                        select.append( '<option value="'+d+'">'+d+'</option>' )
                    } );
                } );
            }
        } );
    } );
</script>

Thank you

Answers

  • ajith.thulaajith.thula Posts: 1Questions: 0Answers: 0

    I am facing same issue. Any solution please let me know

  • kthorngrenkthorngren Posts: 20,269Questions: 26Answers: 4,765

    Instead of simply appending d to select in this statement:
    select.append( '<option value="'+d+'">'+d+'</option>' )

    Some string manipulation would need to happen to extract the desired text from d and append that. Maybe using indexOf and substring to get just the text desired.

    Kevin

  • data100data100 Posts: 3Questions: 1Answers: 0

    I did find a solution to this problem but don't have the time to post it right now. I will post the solution I came up with tonight.

  • data100data100 Posts: 3Questions: 1Answers: 0

    My solution was not to use an <a> tag for links, but to use an onclick event. For the window location, you can link to an internal webpage or external webpage. For external webpage links, make sure you include http:// or https://. I then created a css classed called "looklikelink" which made the cursor change when the text was hovered over. My CSS for the "looklikelink" class is below:

    My HTML looked like this:

    <tr>
    <td>Example</td>
    <td class="looklikelink" onclick="window.location='html/mypage.html'">My page</td>
    <td>Example2</td>
    <td>Example3</td>
    <td>Example4</td>
    <td>Example5</td>
    <td>Example6</td>
    <td>Example7</td>
    </tr>
    

    My CSS to make the text act like a link:

    .looklikelink {
        color: #0048bc;
        text-decoration: underline;
    }
    
  • HMarkHMark Posts: 3Questions: 0Answers: 0

    By any chance, does anyone have a full solution to this problem without using an onclick event? The a tag is required for me, I have no choice. But otherwise my problem is the same and I don't have an advanced knowledge of jQuery to create an indexOf and substring method without help.

    Thanks.

  • kthorngrenkthorngren Posts: 20,269Questions: 26Answers: 4,765

    @HMark Assuming you have something like the above: <a href="londonOffice.html">London</a>

    You might be able to jQuery to get the text. Try changing the code in lines 84-86 above to something like this:

                        column.data().unique().sort().each( function ( d, j ) {
                            var textVal = $( d ).text()
                            select.append( '<option value="'+textVal+'">'+textVal+'</option>' )
                        } );
    

    Kevin

  • HMarkHMark Posts: 3Questions: 0Answers: 0

    Thank you Kevin, it does work, however, I have some columns with a boolean result and it now breaks on those. Is there a way to say if d has a link tag than use this option? I am going to work on that. My apologies for what are probably basic solutions.

  • kthorngrenkthorngren Posts: 20,269Questions: 26Answers: 4,765
    edited December 2019

    You can use column().index() to get the column index or column().header() to get the column header. From these you can determine which column the options are being built and how to handle it.

    Example using `-api column().index():

    var index = column.index();
    if (index === 3) { .  // Column with href
        column.data().unique().sort().each( function ( d, j ) {
            var textVal = $( d ).text()
            select.append( '<option value="'+textVal+'">'+textVal+'</option>' )
        } );
    } else {
         column.data().unique().sort().each( function ( d, j ) {
             select.append( '<option value="'+d+'">'+d+'</option>' )
        } );
    }
    

    Or using the header info:

    var title = $(column.header()).text();  // Using jQuery .text() method to get column title
    if (title === 'myHrefColumn') { .  // Column with href
        column.data().unique().sort().each( function ( d, j ) {
            var textVal = $( d ).text()
            select.append( '<option value="'+textVal+'">'+textVal+'</option>' )
        } );
    } else {
         column.data().unique().sort().each( function ( d, j ) {
             select.append( '<option value="'+d+'">'+d+'</option>' )
        } );
    }
    

    Kevin

  • HMarkHMark Posts: 3Questions: 0Answers: 0

    Thank you. I was able to implement the first solution successfully.

  • geogangeogan Posts: 1Questions: 0Answers: 0

    I wrote similar solution before seeing this using plain JS with no jQuery and using regular expression

                column.data().unique().sort().each( function ( d, j ) {
                    console.log(d);
                    var dplain = d.replace(/<a\b[^>]*>(.*?)<\/a>/i,"$1");
                    select.append( '<option value="'+dplain+'">'+dplain+'</option>' )
                } );
    

    I am having one problem though now. The resulting select list contains many duplicates because the unique() function still only sees the original data in the d columns which are non-unique HREFs. I don't know how to get unique to work on the modified d values, but I also don't want to actually modify the real d column values, which would make unique work correctly.

  • kthorngrenkthorngren Posts: 20,269Questions: 26Answers: 4,765

    I don't know how to get unique to work on the modified d values

    Are you using columns.render to modify the values? If yes then use the solution of cells().render() in this thread.

    Kevin

This discussion has been closed.