Chris Cooning
Chris Cooning

Reputation: 133

Issue with jquery table row search

I'm creating a table dynamically and parsing it into a table. Once the table is displayed, I'd like users to be able to do a live search through all the rows. I'm having issues with getting this to work properly.

Source included - skip to next code section to see js specifically related to the live search of table rows.

    <html>
<head>
        <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Pairings</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.6/underscore-min.js"></script>
        <script src="http://www.parsecdn.com/js/parse-1.1.12.min.js"></script>

        <script id="openDay" type="text/template">
<input type="text" id="search" placeholder="Type to search">

                <table data-role="table" id="pairingsTable" data-mode="columntoggle" class="ui-responsive table-stroke">
                        <thead>
                                <th data-priority="2">Grp</th>
                                <th>Pro / Am</th>
                                <th data-priority="1">Thr</th>
                                <th data-priority="3">Fri</th>
                                <th data-priority="4">Sat</th>
                        </thead>
                        <tbody>
        </script>

        <script id="closeDay" type="text/template">
                        </tbody>
                </table>
        </script>

        <script id="pairing" type="text/template">
                <tr>
                        <td><%= this.model.get("GroupID") %></td>
                        <td style="padding:6px;"><%= this.model.get("Professional1") %> and <%= this.model.get("Amateur1") %><br>
                        <%= this.model.get("Professional2") %> and <%= this.model.get("Amateur2") %></td>
                        <td><%= this.model.get("ThursdayCourse") %><br>
                        <%= this.model.get("ThursdayTeeTime") %> <%= this.model.get("TenthTee1") %></td>
                        <td><%= this.model.get("FridayCourse") %><br>
                        <%= this.model.get("FridayTeeTime") %> <%= this.model.get("TenthTee2") %></td>
                        <td><%= this.model.get("SaturdayCourse") %><br>
                        <%= this.model.get("SaturdayTeeTime") %> <%= this.model.get("TenthTee3") %></td>
                </tr>
        </script>
        <script>
        $(function(){

                Parse.$ = jQuery;
                // Connect to Parse

                Parse.initialize("soyC2zYsel97QtRsNhhNUxLoBgKe6kxnX0WxUBYT", "mZL82WFBjR2UUwJrwIu5WYLoRr0FzjPlHiTrD8zj");

                var Pairing = Parse.Object.extend("golfTourney");

                var Pairings = Parse.Collection.extend({
                        model: Pairing
                });

                var PairingView = Parse.View.extend({
                        template:  _.template($("#pairing").html()),

                        initialize: function(){
                                _.bindAll(this, 'render');
                        },

                        render: function(){
                                return this.template(this.model);
                        }
                });

                var AppView = Parse.View.extend({
                        el: $("div"),
                        openTemplate: _.template($("#openDay").html()),
                        closeTemplate: _.template($("#closeDay").html()),

                        initialize: function() {
                                _.bindAll(this, 'render');
                                var self = this;

                                this.collection = new Pairings;
                                this.collection.query = new Parse.Query(Pairing);
                                this.collection.query.ascending("GroupID");
                        this.collection.fetch();

                        this.collection.bind('reset', function(){
                                self.render();
                        });
                        },
                        render: function(collection) {
                                var self = this, html = this.openTemplate();

                                console.log(this.collection);

                                this.collection.sortBy(function(m){
                                        return m.get("GroupID");
                                })

                                this.collection.forEach(function(m){
                                        var pairing = new PairingView({model: m});
                                        html += pairing.render();
                                });

                                html += this.closeTemplate();
                                this.$el.append(html);
                        }
                });

                var appview = new AppView();
        });

This is the js in question....

        $('#pairingsTable').load(function(){

                var $rows = $('#pairingsTable tr');
                $('#search').keyup(function() {
                        var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();

                        $rows.show().filter(function() {
                                var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
                                return !~text.indexOf(val);
                        }).hide();
                });
        });
        </script>

</head>
<body>

        <div>

        </div>

</body>
</html>

What am I missing here? Can I not use this method since my content is being generated dynamically?

thanks

Upvotes: 0

Views: 294

Answers (1)

Cymen
Cymen

Reputation: 14429

The problem is indeed that the DOM is created after the page is loaded. So you need to somehow bind to the keyup event on #search once the view is rendered. There are a couple ways to do this but here is one way:

$(function(){
    Parse.$ = jQuery;
    // Connect to Parse

    Parse.initialize("soyC2zYsel97QtRsNhhNUxLoBgKe6kxnX0WxUBYT", "mZL82WFBjR2UUwJrwIu5WYLoRr0FzjPlHiTrD8zj");

    var Pairing = Parse.Object.extend("golfTourney");

    var Pairings = Parse.Collection.extend({
        model: Pairing
    });

    var PairingView = Parse.View.extend({
        template:  _.template($("#pairing").html()),

        initialize: function(){
            _.bindAll(this, 'render');
        },

        render: function(){
            return this.template(this.model);
        }
    });

    var AppView = Parse.View.extend({
        el: $("div"),
        openTemplate: _.template($("#openDay").html()),
        closeTemplate: _.template($("#closeDay").html()),

        initialize: function() {
            _.bindAll(this, 'render');
            var self = this;

            this.collection = new Pairings;
            this.collection.query = new Parse.Query(Pairing);
            this.collection.query.ascending("GroupID");
            this.collection.fetch();

            this.collection.bind('reset', function(){
                    self.render();
            });
        },

        render: function(collection) {
            var self = this, html = this.openTemplate();

            this.collection.sortBy(function(m){
                return m.get("GroupID");
            })

            this.collection.forEach(function(m){
                var pairing = new PairingView({model: m});
                html += pairing.render();
            });

            html += this.closeTemplate();
            this.$el.append(html);
            $(document).trigger('list-rendered');        
        }
    });

    var appview = new AppView();
});

$(document).on('list-rendered', function() {
    var $rows = $('#pairingsTable tr');
    $('#search').on('keyup', function() {
        var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();

        $rows.show().filter(function() {
            var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
            return !~text.indexOf(val);
        }).hide();
    });
});​

Now we are triggering a custom event named list-rendered at the end of the render method with $(document).trigger('list-rendered');. That event is listened for and bound to with the code at the bottom.

Working jsfiddle: http://jsfiddle.net/QZYwq/

Upvotes: 1

Related Questions