Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

st-search not working for select input in Firefox #254

Closed
bavicj opened this issue Dec 11, 2014 · 28 comments
Closed

st-search not working for select input in Firefox #254

bavicj opened this issue Dec 11, 2014 · 28 comments
Labels

Comments

@bavicj
Copy link

bavicj commented Dec 11, 2014

Hi,

I am developing table with dropdown filters. I noticed that everything is fine in chrome and safari, but firefox does not work.
I found the problem in definition of directive stSearch. Problem is that it binds only to event "input", which is not fired in Firefox. When I added binding to "change" event for select tag it works. Can you verify my proposed solution?

ng.module('smart-table')
    .directive('stSearch', ['$timeout', function ($timeout) {
        return {
            require: '^stTable',
            scope: {
                predicate: '=?stSearch'
            },
            link: function (scope, element, attr, ctrl) {
                var tableCtrl = ctrl;
                var promise = null;
                var throttle = attr.stDelay || 400;

                scope.$watch('predicate', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        ctrl.tableState().search = {};
                        tableCtrl.search(element[0].value || '', newValue);
                    }
                });

                //table state -> view
                scope.$watch(function () {
                    return ctrl.tableState().search;
                }, function (newValue, oldValue) {
                    var predicateExpression = scope.predicate || '$';
                    if (newValue.predicateObject && newValue.predicateObject[predicateExpression] !== element[0].value) {
                        element[0].value = newValue.predicateObject[predicateExpression] || '';
                    }
                }, true);

                if (element.prop('tagName') == 'SELECT') {
                    element.bind('change', function (evt) {
                        evt = evt.originalEvent || evt;
                        if (promise !== null) {
                            $timeout.cancel(promise);
                        }
                        promise = $timeout(function () {
                            tableCtrl.search(evt.target.value, scope.predicate || '');
                            promise = null;
                        }, throttle);
                    });
                } else {
                    // view -> table state
                    element.bind('input', function (evt) {
                        evt = evt.originalEvent || evt;
                        if (promise !== null) {
                            $timeout.cancel(promise);
                        }
                        promise = $timeout(function () {
                            tableCtrl.search(evt.target.value, scope.predicate || '');
                            promise = null;
                        }, throttle);
                    });
                }
            }
        };
    }])
@lorenzofox3
Copy link
Owner

sounds good, you could refactor the events handler into a single function to avoid code duplication though

@shilan
Copy link

shilan commented Dec 16, 2014

thanks for your code sharing!
that can be really helpful if you could revise the code, I really need some filter, st search lookup on my tables, but I am not that good in Angularjs, I even doubt where is the best place to add this part of code :(
something like

<:select st-search="datasource" placeholder="search for FSA" class="input-sm form-control" type="search" class="form-control">
<:option selected="selected">DA<:/option>
<:option.>FI<:/option>
<:/select>

@sjobe
Copy link

sjobe commented Jan 29, 2015

I've been experiencing a similar bug on firefox too.

@mehulcrest
Copy link

Hi I am also facing the same issue in firefox and working in chrome.

input field's search functionality is working fine but
combo box and date picker controls are not working in search functionality.

my code of view file is

<div ng-controller="AppraiserAccountingCtrl">
  <div class="table-responsive">
    <table class="table" st-pipe="callServer" st-table="displayed">
      <thead>
      <tr>
        <th>
          <label>Name</label>
          <input st-search="'name'" ng-model="name" class="form-control"/>
        </th>
        <th>
          <label>Month</label>
          <select st-search="'month'" class="form-control" ng-model="month">
            <option value="0" selected>-Select Month-</option>
            <option value="1">January</option>
            <option value="2">February</option>
            <option value="3">March</option>
            <option value="4">April</option>
            <option value="5">May</option>
            <option value="6">June</option>
            <option value="7">July</option>
            <option value="8">August</option>
            <option value="9">September</option>
            <option value="10">October</option>
            <option value="11">November</option>
            <option value="12">December</option>
          </select>
        </th>
        <th>
          <label>Year</label>
          <select st-search="'year'" class="form-control" ng-model="year">
            <option value="0" selected>-Select Year-</option>
            <option value="2014">2013</option>
            <option value="2014">2014</option>
          </select>
        </th>
        <th>
          <label>From</label>
          <!--<input st-search="'fromDate'" class="form-control"/>-->
            <input st-search="'fromDate'"
                   type="text"
                   datetimepicker
                   name="fromDate"
                   id="inputFromDate"
                   class="form-control"
                   validator="date"
                   ng-model="fromDate"/>
        </th>
        <th>
          <label>To</label>
          <!--<input st-search="'toDate'" class="form-control"/>-->
            <input st-search="'toDate'"
                   type="text"
                   datetimepicker
                   name="toDate"
                   id="inputToDate"
                   class="form-control"
                   validator="date"
                   ng-model="toDate"/>
        </th>
        <th></th>
        <th ng-show="subSection=='paid'"> <!--KEEP THIS BLANK--></th>
      </tr>
      <tr>
        <th st-sort="file">File#</th>
        <th st-sort="borrower_name">Name</th>
        <th st-sort="address">Address</th>
        <th st-sort="assigned_date">Assigned Date</th>
        <th st-sort="completed_date">Completed Date</th>
        <th ng-show="subSection=='paid'" st-sort="paid_date">Paid Date</th>
        <th st-sort="appraiser_fee">Appraiser Fee</th>
      </tr>
      </thead>
      <tbody ng-show="!isLoading && displayed.length>0">
      <tr ng-repeat="row in displayed">
        <td>{{row.file}}</td>
        <td>{{row.borrower_name}}</td>
        <td>{{row.address}}</td>
        <td>{{row.assigned_date}}</td>
        <td>{{row.completed_date}}</td>
        <td ng-show="subSection=='paid'">{{row.paid_date}}</td>
        <td>{{row.appraiser_fee}}</td>
      </tr>
      </tbody>
      <tbody ng-show="isLoading">
      <tr>
        <td colspan="{{cols}}" class="text-center">{{perPage}} Loading ...</td>
      </tr>
      </tbody>
      <tbody ng-show="!displayed.length && !isLoading">
        <tr>
            <td class="text-center warning" colspan="{{cols}}">No record(s) found</td>
        </tr>
      </tbody>
      <tfoot>
      <tr>
        <td class="text-left" st-pagination="" st-items-by-page="perPage" colspan="{{cols-1}}">
        </td>
        <td class="text-right " colspan="1">
            <div class="col-md-12 pull-right">
                <label>Per Page:</label>
            </div>
            <div class="col-md-8 pull-right">
                <select st-search="'perPage'" ng-model="perPage" class="form-control ng-pristine ng-valid ng-touched">
                    <option value="5">5</option>
                    <option value="10">10</option>
                    <option value="15">15</option>
                    <option value="20" selected>20</option>
                </select>
            </div>
        </td>
      </tr>
      </tfoot>
    </table>
  </div>
</div>

and used above solution for stSearch directive

ng.module('smart-table')
    .directive('stSearch', ['$timeout', function ($timeout) {
        return {
            require: '^stTable',
            scope: {
                predicate: '=?stSearch'
            },
            link: function (scope, element, attr, ctrl) {
                var tableCtrl = ctrl;
                var promise = null;
                var throttle = attr.stDelay || 400;
                scope.$watch('predicate', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        ctrl.tableState().search = {};
                        tableCtrl.search(element[0].value || '', newValue);
                    }
                });
                //table state -> view
                scope.$watch(function () {
                    return ctrl.tableState().search;
                }, function (newValue, oldValue) {
                    var predicateExpression = scope.predicate || '$';
                    if (newValue.predicateObject && newValue.predicateObject[predicateExpression] !== element[0].value) {
                        element[0].value = newValue.predicateObject[predicateExpression] || '';
                    }
                }, true);
                if (element.prop('tagName') == 'SELECT') {
                    element.bind('change', function (evt) {
                        evt = evt.originalEvent || evt;
                        if (promise !== null) {
                            $timeout.cancel(promise);
                        }
                        promise = $timeout(function () {
                            tableCtrl.search(evt.target.value, scope.predicate || '');
                            promise = null;
                        }, throttle);
                    });
                } else {
                    // view -> table state
                    element.bind('input', function (evt) {
                        evt = evt.originalEvent || evt;
                        if (promise !== null) {
                            $timeout.cancel(promise);
                        }
                        promise = $timeout(function () {
                            tableCtrl.search(evt.target.value, scope.predicate || '');
                            promise = null;
                        }, throttle);
                    });
                }
            }
        };
    }])

Still its not working for me.

I can not even check it by console. Am I doing anything wrong?

Can you please advise?

@alanthai
Copy link

@mehulcrest Your directive looks correct. I could be wrong but it looks like you're doing more complex search that requires a custom filter for date filtering.

@mehulcrest
Copy link

@alanthai
Actually it does not work for even drop down control. Dropdown filter works in Chrome but not works in firefox.

@leijenaarj
Copy link

I had the same issue with IE8 and fixed it like so:

            var e = element[0].tagName.toLowerCase() === "input" ? "keydown" : "change";
            // view -> table state
            element.bind(e, function (evt) {
                evt = evt.originalEvent || evt || window.event; //ie8 fixes
                var target = evt.target || evt.srcElement;
                if (promise !== null) {
                    $timeout.cancel(promise);
                }
                promise = $timeout(function () {
                    tableCtrl.search(target.value, scope.predicate || '');
                    promise = null;
                }, throttle);
            });

@ivorobioff
Copy link

Will this solution be included to the next release or soon?

@BobKurtis
Copy link

@leijenaarj where did you replace that code at. Im running into the same issue.

@ivorobioff
Copy link

make sure you include debug version when doing changes.

@leijenaarj
Copy link

in st-search were the input event is used

met vriendelijke groet,

Jorgen Leijenaar
jorgen.leijenaar@7till11.com

On 23 feb. 2015, at 19:38, BobKurtis notifications@github.com wrote:

@leijenaarj where did you replace that code at. Im running into the same issue.


Reply to this email directly or view it on GitHub.

@BobKurtis
Copy link

@leijenaarj I'm sorry to bother you, I'm still rather new at javascript. I've edited the module but it isn't working. do you know what im doing wrong?

     t.module("smart-table").directive("stSearch", ["$timeout", function(t) {
        return {
            require: "^stTable",
            scope: {
                predicate: "=?stSearch"
            },
            link: function(e, a, s, n) {

                var r = n,
                    i = null,
                    c = s.stDelay || 400;
                e.$watch("predicate", function(t, e) {
                    t !== e && (n.tableState().search = {}, r.search(a[0].value || "", t))
                }), e.$watch(function() {
                    return n.tableState().search
                }, function(t) {
                    var s = e.predicate || "$";
                    t.predicateObject && t.predicateObject[s] !== a[0].value && (a[0].value = t.predicateObject[s] || "")
                }, !0)
                var e = element[0].tagName.toLowerCase() === "input" ? "keydown" : "change";
                // view -> table state
                element.bind(e, function (evt) {
                    evt = evt.originalEvent || evt || window.event; //ie8 fixes
                    var target = evt.target || evt.srcElement;
                    if (promise !== null) {
                        $timeout.cancel(promise);
                    }
                    promise = $timeout(function () {
                        tableCtrl.search(target.value, scope.predicate || '');
                        promise = null;
                    }, throttle);
                });
            }
        }

@mehulcrest
Copy link

@BobKurtis

Please change code in to bower_components -> angular-smart-table -> dist -> smart-table.debug.js
Find directive "stSearch" and change below code in it. you have to replace "change" in place of "input"

element.bind('change', function (evt) {
                        evt = evt.originalEvent || evt;
                        if (promise !== null) {
                            $timeout.cancel(promise);
                        }
                        promise = $timeout(function () {
                            tableCtrl.search(evt.target.value, scope.predicate || '');
                            promise = null;
                        }, throttle);
                    });

Now include smart-table.debug.js instead of smart-table.min.js in index.html

now please check Is it working?

@BobKurtis
Copy link

I've got it working with IE 8+ now. I'm doing some trick things with smart-table so I will explain (I'm new at this so if there may be some things I missed. First my situation. I'm using a dataList with search column in order to get a drop down list and text search all at once.

<datalist id="formNumbers">
        <option ng-repeat="num in displayedCollection "
            value="{{num.form_number}}">{{num.form_number}}</option>
    </datalist>
<th><input st-search="'form_number'"class="input-sm form-control" id="formList" type="search"  list="formNumbers" /></th>

This works great in ie10+ and Firefox but Chrome doesn't make the list scrollable which causes major page overflow but my target is IE8-11. When implementing what @leijenaarj suggested i was able to get sorting to work(albeit without dropdown list but im not concerned with that) but the dropdown list functionality for ie10+ was killed so after some research i came to the following

//slight change from what was suggested
 var e = element[0].tagName.toLowerCase() === "change" ? "input" : "keydown" ;  
//added the following binding to my controller.js
$("#formList").bind('input', function () {
        var e = $.Event('keydown');
        e.which = 13; // enter key
        $("#formList").trigger(e);
 });    

It is now working as desired in IE8+. Thank you for all you help, if i hadn't of stumbled across this page i would still be lost. If you have any suggestions on how to clean this up I'm all ears.

@btrepp
Copy link

btrepp commented Jun 3, 2015

Also just as an fyi, pretty sure this happens with IE11 to, my testing shows IE11 fires change but not input on select boxes.

Not that anyone except me seems to have used IE11 :) haha.

@emjaksa
Copy link

emjaksa commented Jun 10, 2015

I change my event handler from 'input' to 'change' which fixed the issue with select in Firefox but caused IE9 backspace in input fields to not work. I resolved this issue by changing the bind to handle both change and keydown events. Let me know what you think.
From my initial tests it works in IE9+, latest Chrome and Firefox.

// view -> table state
element.bind('change keydown', function (evt) {
    evt = evt.originalEvent || evt;
    if (promise !== null) {
        $timeout.cancel(promise);
    }

    promise = $timeout(function () {
        tableCtrl.search(evt.target.value, attr.stSearch || '');
        promise = null;
    }, throttle);
});

@gulfaraz
Copy link

@emjaksa may I know what is the behaviour when using change instead of keydown ? I've been binding 'input change' and it seems to work in most cases.

@emjaksa
Copy link

emjaksa commented Jun 10, 2015

@gulfaraz In most cases 'input change' works expect in IE9. In IE9 I found when you clear or backspace on the input field it does not update the table.

@danroot
Copy link

danroot commented Jun 11, 2015

I had a similar issue and the 'change keydown' fix worked for me. Barring any surprises, it seems like this should be changed in stSearch.js.

@JuanValladares
Copy link

I have a easiest solution:
only change the event in the select element "st-input-event="change""
example:

   <select   st-search="appVersion" class="filter_input pointer"  st-input-event="change">
   <option value=""></option>
   <option ng-repeat="item in usersCollection| unique:'appVersion' | orderBy:'appVersion'">{{item.appVersion}}</option>

and that's all.

@jjmurre
Copy link

jjmurre commented Sep 16, 2015

@JuanValladares : You just made my day!
st-seach was still not working in FF (40.0.3) for version 2.1.3 of smart-table, your solution worked like a charm.

@shilan
Copy link

shilan commented Sep 16, 2015

I have just updated smart table, now it works but not in IE.

On Wednesday, September 16, 2015, jjmurre notifications@github.com wrote:

@JuanValladares https://github.com/JuanValladares : You just made my
day!
st-seach was still not working in FF (40.0.3) for version 2.1.3 of
smart-table, you solution worked like a charm.


Reply to this email directly or view it on GitHub
#254 (comment)
.

@Korayem
Copy link

Korayem commented Nov 18, 2015

Let's update documentation with @JuanValladares answer. It saved my day too :)

@antajo
Copy link

antajo commented Jan 22, 2016

Set attr st-input-event='change'

@ghost
Copy link

ghost commented Feb 22, 2016

@JuanValladares answer worked great! IE 11 and FF 44

@senthilsendhil
Copy link

drop down filter not working in FF , I have tried example given in http://lorenzofox3.github.io/smart-table-website/... this site itself not working in FF ,, I tried adding st-input-event.. no lunck

@lindmik
Copy link

lindmik commented May 17, 2016

@senthilsendhil I just last week took AngularJS 1.5.5 and Smart Table 2.1.8 in use and with st-input-event="change" the drop down filters do work in Firefox. I had however to remove the single quotes around the property names in st-search when updating from earlier version of Smart Table. The examples on the documentation site does not work as they don't have st-input-event configured.

@senthilsendhil
Copy link

@lindmik Thanks for response , Yes I am using old Smart table , I will try to update , if any issue i might ask you again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests