1

I have 3 select tags on one page, generated from struts2 select tag. I am using a jQuery filter function that filters the select. One textfield for every select, but all of them use the same filter function. I have another js function that is called on onChange event.

The problem is that before adding this jQuery function i was filtering the lists with form submit and reload the page and now the filtration happens instant, but when i write a filtration criteria the select somehow the select loses focus and when i click an element no select happens, or better lets say is a kind of select: the element is circled with a dotted line, not selected with a blue filled square. The js is called, the form submitted, but with the old value. However, if i first click in the select where are no elements (empty zone) and then i select an element everything is ok. How can i jump over the firs click?

And now my code:

I. The jQuery filter function and the binding to the selects and textfields.

jQuery.fn.filterByText = function(textbox) {
    return this.each(function() {
        var select = this;
        var options = [];
        $(select).find('option').each(function() {
            options.push({value: $(this).val(), text: $(this).text()});
        });
        $(select).data('options', options);
        $(textbox).bind('change keyup', function() {
            var options = $(select).empty().scrollTop(0).data('options');
            var search = $.trim($(this).val());
            var regex = new RegExp(search,'gi');

            $.each(options, function(i) {
                var option = options[i];
                if(option.text.match(regex) !== null) {
                    $(select).append($('<option>').text(option.text).val(option.value));
                }
            });
        });
    });
};

$(function() {
    $('#selectedClientId').filterByText($('#filterClient'));
    $('#selectedLocationId').filterByText($('#filterLocation'));
    $('#selectedViewPointId').filterByText($('#filterViewpoint'));
});

II. One of the selects:

<s:select size="10" cssStyle="width:220px;"
        label="Select a client"
        listKey="id" listValue="name"
        list="clientSelectList"
        name="selectedClientId" id="selectedClientId"
        headerKey="-1" headerValue="Client List"
        onchange="onChangeSelect()"
 />

III. The select's textfield:

Filter:<s:textfield name="filterClient" id="filterClient" size="15" autocomplete="off"/>

IV. The onChangeSelect():

function onChangeSelect() {
    document.getElementById('deviceListForm').action = '<s:url value="/admin/displayDeviceListPage.action"/>';
    document.getElementById('deviceListForm').submit();
}

In the image: in the first select is how looks the selected option after jquery filter and in the other 2 selects are "the good" selected options. https://i.stack.imgur.com/TAJeY.png

EDIT: So, after the first response to this post (Thanks Amit1992) I started digging further. In Mozilla after the first click (after the frame or dotted line appears) a request is made to the server with the old selected item (or null if none selected), the page refreshes as nothing happened. In Chrome, on the other hand, the first click does not make any request. It just selects (let's say) the select tag. And the second select makes a good request.

Short story:

  • mozilla: click 1 -> request with old selected value ->refresh -> no changes

  • chrome: click 1 -> selects the select tag and no request is made -> click 2 -> request as it should happen

  • IE - works ok. 1 click-> select and load page as it should . OK this really surprises me. at first I thought is useless to look in IE what happens.

EDIT2

After some digging i concluded that the problem is that when typing in the textfield the select loses focus. If I put $('#selectedClientId').focus(); in the filterByText function at the end of the $(textbox).bind('change keyup', function() the fist select is focused after every char written. But this gives me another problem. I can't write more than 1 char at a time. I have to click the textfield, write a char, click again, write a char etc.

2 Answers2

2

May be this will help you. i did some modification in your code.

 $(function() {

    $('#selectedClientId').filterByText($('#textbox'), false);
  $("#selectedClientId").change(function(){

    alert("you have selected ++ " + $(this).val());
  });
});

I used change() event of jquery instead of javascript onChange(). you can refer this link http://jsfiddle.net/amitv1093/q55k97yc/ and I recommend you to use jquery fully if you are using it.

kindly let me know if it will work.

AmitV
  • 261
  • 1
  • 4
  • 16
  • Thank you, but it's not working. All I can get is "you have selected ++ null" and the dotted square. If I press ok on the alert button and then click again it works, but is the same : 2 clicks needed and the first one will make a request with a null parameter. And the jsfiddle example is not working too. The alert shows you anything but null? Ok something is strange. I am using mostly mozzila. In mozilla jsfiddle shows me the null. I tried in chrome and nothing happens after the first click and after the second the alert appears with the good id. – Tripon Ionut Dec 03 '15 at 15:21
0

I solved the problem by changing the whole filter function. The function with problem was taken from a stack overflow question response (How to dynamic filter options of <select > with jQuery?). The problem is, from what I concluded, that the $(textbox).bind('change keyup', function() line was changing the focus on the textfield, so the first click was changing the focus to the select tag. The new function, the one that works was taken from the same post, John Magnolia's answer:

$(document).ready(function() { filterClient(); filterLocation(); //same as filterClient filterViewpoint(); //same as filterClient }); function filterClient(){ var $this, filter, $input = $('#filterClient'), $options = $('#selectedClientId').find('option'); $input.keyup(function(){ filter = $(this).val(); $options.each(function(){ $this = $(this); $this.removeAttr('selected'); if ($this.text().toLowerCase().indexOf(filter.toLowerCase()) != -1) { $this.show(); } else { $this.hide(); } }); }); }

Community
  • 1
  • 1