0

I'm using Ajax to load the contents of a select:

<select id = "idResultEntryMeet" class="form-control input-md" size = 1>
</select>
...
$('#idResultEntryMeet').mousedown(function() { 
   $.post("/cgi-bin/listOptions", function(data) {
      $('#idResultEntryMeet').html(data);
   });
});

This isn't consistent across browsers, which makes me think that there's a problem with the code:

  1. IE9 never shows anything in the select
  2. FF 27 works as expected
  3. Chrome and IE11 don't show anything in the pull-down on the first mouse click, but will show the expected contents on the second mouse click. I can fix this on both browsers by pre-loading the select during the initial page load
  4. Opera and Safari require a second mouse click, even with an initial preload

Any suggestions on what's wrong with this?

EDIT Sorry, guess this wasn't obvious: the select must be dynamic. The options are constantly changing, depending on the contents of a database. The idea is that the user sees the current options when they click the pull-down on the select. Using a click (instead of mousedown) handler doesn't work, since the user can't then actually select anything they see in the pull-down.

And the CGI code returns an HTML snippet, containing the options. Firebug shows a correctly-formed select containing options on completion of the POST.

EDIT The problem is that the Ajax request has to be synchronous (Sjax?) (as more-or-less suggested in the comments), to prevent interfering with whatever happens when the select pull-down is activated. This code works with proper browsers (and almost works in IE9), but changing async to true causes consistent problems with various browsers:

$('#idResultEntryMeet').mousedown(function() {
   $.ajax({
      type  : "POST",
      url   : "/cgi-bin/listOptions",
      async : false
   }).done(function(data, textStatus, jqXHR) {
      $('#idResultEntryMeet').html(data);
   });
});
EML
  • 9,619
  • 6
  • 46
  • 78
  • `data` receives html strings, e.g ` – DontVoteMeDown Mar 25 '14 at 12:15
  • 2
    @DontVoteMeDown - `data` can be anything, noone is forcing you to use JSON. But, if the OP posted what `data` actually is, it would be possible to answer this. – adeneo Mar 25 '14 at 12:16
  • It's an HTML snippet containing the options. Firebug shows a correctly-formed select after the POST completes, with options inside it. – EML Mar 25 '14 at 12:19
  • Mousedown on a select? Does it even get fired in IE9. – epascarello Mar 25 '14 at 12:19
  • I find it interesting that this code works in FF. – A1rPun Mar 25 '14 at 12:20
  • @adeneo Would you print the html itself or json? When I say *should* I don't mean that is required to be JSON, but makes more sense. You know that. – DontVoteMeDown Mar 25 '14 at 12:20
  • @epascarello: it's `mousedown` on the pull-down. A `click` handler fails on pretty much everything; you can't select anything in the list. – EML Mar 25 '14 at 12:21
  • Think about it, once you load it, you need to remove the event or every click action is going to fire it. Also you probably want to change it to a different event like over or enter and focus. [not everyone uses a mouse] – epascarello Mar 25 '14 at 12:22
  • @epascarello: that's the whole point. It's dynamic; the options come from a changing database. – EML Mar 25 '14 at 12:23
  • I know it is dynamic, but you are causing it to reload as the people are interacting with it.... – epascarello Mar 25 '14 at 12:24
  • Are these datas retrieve from database supposed to change betwwen each page load? Why can't you just fill SELECT with option from ajax request on DOM ready? – A. Wolff Mar 25 '14 at 12:29
  • @A.Wolff: the database changes at arbirtrary times, and may change in response to user actions. The point is to stop the user having to refresh the page just to get the correct contents of the `select`. – EML Mar 25 '14 at 12:34
  • 1
    What is happening is the browser appears to not like the fact it has to redraw the select list when active. Loading it with mousedown, focus, mouseover, mouseenter will all probably have the same issue with a race condition [aka will the response get back before the user opens the options]. You might be better off with a ping that checks for new data and tells the user there is new options and they can click that message to load the new values. – epascarello Mar 25 '14 at 12:41
  • @epascarello is right. I got to the same conclusion when running a [test on jsFiddle](http://jsfiddle.net/wrp2n/). To [fix this](http://jsfiddle.net/wrp2n/1/) (in a quick and dirty way that should never see the light of day), I added a blur/focus when the ajax request was done. _NOTE: I only added the delay to test the AJAX locking mechanism._ – Ayman Safadi Mar 25 '14 at 13:09
  • @epascarello: Ok, your suggestion of the race condition got me on the right track - see the answer in my edit above. If you post this as an answer I'll accept it. – EML Mar 25 '14 at 13:47

2 Answers2

0

Try that (just tested on chrome):

$('#idResultEntryMeet').on('mousedown', function(e){
    if(!e.view) return;
    e.preventDefault();    
    var _self = this;
    $.post("/cgi-bin/listOptions", function (data) {
        $(_self).html(data);
         var mdwn = document.createEvent("MouseEvents");
        mdwn.initMouseEvent("mousedown", false, false, null, 0, 0, 0, 0, 0, true, false, false, true, 0, null);
        _self.dispatchEvent(mdwn);
    });
});

Simplified DEMO

EDIT: doesn't work on FF nor IE...

A. Wolff
  • 74,033
  • 9
  • 94
  • 155
-2

Try change your code for:

html

<select id="idResultEntryMeet" class="form-control input-md" size="1">      
</select>

js

$(document).ready(function() { 
   $.post("/cgi-bin/listOptions", function(data) {
     $('#idResultEntryMeet').html(data);
   });
});

$('#idResultEntryMeet').change(function() { 
   var valueSelected = $(this).val();
   alert(valueSelected);
   //Do something
});

Edit: you need include the delegate bind with jquery for do this dinamic.

$('#idResultEntryMeet').bind("click", function() {
    var data = '<option value="volvo">Volvo</option><option value="saab">Saab</option>';
    $('#idResultEntryMeet').html(data);
});

And need format the return of the method some like this

Daniel Melo
  • 548
  • 5
  • 12
  • Not even close to what the OP is doing. – epascarello Mar 25 '14 at 12:21
  • It's just an example, to load the select using jquery "ready". It's work for me – Daniel Melo Mar 25 '14 at 12:29
  • It has to be dynamic: see clarification above. – EML Mar 25 '14 at 12:30
  • But the only relevant difference between this and my original code is that you're binding `click`, and I was using `.mousedown`. `click` doesn't work anyway, because you can't actually select any options (see above). If I change your code to bind `mousedown`, then I get exactly the same results in Opera (haven't tried the others), ie. it still doesn't work on the first `mousedown`, and requires a second `mousedown`. – EML Mar 25 '14 at 13:21
  • I found 2 links that would be useful 1:http://stackoverflow.com/questions/20148195/clear-and-refresh-jquery-chosen-dropdown-list 2:https://forum.jquery.com/topic/how-to-refresh-a-select-box – Daniel Melo Mar 25 '14 at 13:47