Nick
Nick

Reputation: 3337

Jquery UI selectmenu not working in dialog

The select wont open when inside of a table inside of the dialog. I included a code snippet of the problem

$('select').selectmenu();
$('.RegularDialog').dialog({
  autoOpen: false,
  modal: true,
  height: 500,
  width: 570
});
$('#OpenDialog').click(function(e) {
  $('.RegularDialog').dialog('open');
});
<head>
  <link href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css" rel="stylesheet" />
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
</head>

<body>
  <div id="Dialog" title="Edit Dialog" class="RegularDialog">
    <form action="">
      <table>
        <tr>
          <td>Select the Type</td>
          <td>
            <select id="Type">
              <option value="a">Type 1</option>
              <option value="b">Type 2</option>
              <option value="c">Type 3</option>
            </select>
          </td>
        </tr>
      </table>
    </form>
  </div>

  <button id="OpenDialog">Open Dialog</button>
</body>

Upvotes: 7

Views: 7949

Answers (6)

jeHaw Services
jeHaw Services

Reputation: 69

I know this is very old, but there is a situation when the accepted answer does not work.

If the selectmenu z-index was changed to a higher value using CSS, the option list will remain behind the dialog (at least in my case) even if the above remedy is called. In my case, there is a requirement for increasing the z-index of all ui-dialogs due to application conflicts.

There are two alternatives to fix this (in this example, the z-index for all dialogs was set to z-index: 750 using CSS):

Using JQuery:

$('#selectmenu-menu').parent().css('z-index', '751');

Using CSS / the Classes option when initializing the specific selectmenu

CSS

.maxz {
    z-index: 751;
}

JavaScript

$('#selectmenu').selectmenu({
    classes: {
        "ui-selectmenu-open": "maxz"
    }
})

What is happening:

  1. The z-index for the .ui-dialog is set through CSS (the number may vary per your application, but you get the gist of if). In this example I'll use 750.
  2. When a selectmenu element is created, the "options" are created in an unordered list. That list has an id of the original select menu, appended with "-menu".
  3. In order to bring the list above the dialog, you have to change the z-index of the list's wrapper element to at least 751, changing the z-index of the unordered list has no effect.
  4. In the first example, we address the list's wrapper element (its parent), bringing it 1 index higher than the dialog and thus to the top.
  5. In the second example the CSS takes care of the problem itself. We simply create a CSS class with a z-index with a value 1 higher than the dialog z-index that was set, and then use the 'classes' option in the selectmenu initialization to assign that class to the 'ui-selectmenu-open' (the class that is added to the ui-selectmenu-menu wrapper element when the button is clicked and the menu opens).

Alternative #1

In the first example, the above must be included after the selectmenu is initialized.

$('#menu1').selectmenu({
    *setup and functions added here*
});
$('#menu1-menu').parent().css('z-index', '751');

Note that for me, at least, trying to include the code in the create event for the affected selectmenu has no effect, it must be called separate and after the menu initialization.

Alternative #2

The second example is more efficient

You simply set the z-index value for .maxz to the highest z-index set for all the dialogs + 1. (Not sure that I would understand a reason for having 5 different dialogs with 5 different z-indices, but anything is possible.)

If there are multiple selectmenus that you need to initialize with this process and all share the same events just group these by class and initialize them by class instead of id, adding the above classes option.

However, if you have mulitiple selectmenus, each with different setup properties (i.e., classes, functions, etc.), you could add the classes to each as above, or you could add a class to each select menu, such as "s-max-z", and then execute the following after all have been initialized:

$('.s-max-z').selectmenu("option", "classes.ui-selectmenu-open", "maxz");

Notes:

Using the classes option when initializing the dialog widget (while using modal: true) to return the z-index to default and then using the accepted answer did work, almost. The z-index for the selectmenu was correctly reset and it opened above the dialog, the problem was that you can't get to the dialog to do anything!

CSS

.minz {
    z-index: initial;
}

JavaScript

$('#dialog').dialog({
    modal: true,
    classes: {
        "ui-dialog": "minz"
    }
})

What occurred was the dialog was opened behind the widget-overlay, which still had the original z-index - 1 (in my case 749) set initially for the dialogs in CSS.

Because the widget-overlay is created once and appended to the end of the body, it is not possible without a lot of extra CSS / JavaScript to keep resetting the widget-overlay's z-index for each dialog that appears.

Even with one single dialog, the CSS for the widget-overly has to be set separately (I tried it in the classes for the dialog with no affect).

Upvotes: 0

Alain Pannetier
Alain Pannetier

Reputation: 9514

Just for the record. If you (wisely) want to avoid brutally overriding the ui-front rule of jquery-ui.css, what you can do is something along the line of

    $( 'div.ui-front:has("ul[id^=dropdown_]")').css('z-index',1005);

At the time of writing (css3) there is no selector to select a parent element on a condition criterion on its children. so you're stuck with jquery.

$(document).ready(function() {
 
    $( "select[id^=dropdown]" ).selectmenu();
    $( 'div.ui-front:has("ul[id^=dropdown_]")').css('z-index',1005);
 
});
html, body {
    height: 100%;
  }
 
  * {
    margin: 0px;
    padding: 0px;
  }
 
.ui-selectmenu-button.ui-button {
    width: 100px !important;
}
 
#low, #medium, #high {
    position:absolute;
    top:20px;
    width: 150px;
    padding:10px;
    border-style: solid;
    border-width: 1px;
    border-radius: 10px;
    box-shadow: 4px 4px 4px 0 #999;
}
 
#low::before, #medium::before, #high:before {
    display:block;
    height: 2em;
    font: 1.1em arial ;
}
 
#low::before {
    content: 'z-index: 0' ;
}
 
#low {
    z-index: 0;
    background-color: #cff;
    border-color: #8aa;
    left: 20px;
}
 
#medium::before {
    content: 'z-index: 50' ;
}
 
#medium {
    z-index: 50;
    background-color: #fcf;
    border-color: #a8a;
    left: calc(50% - 75px);
}
 
#high::before {
    content: 'z-index: 1000' ;
}
 
#high {
    z-index: 1000;
    background-color: #ffc;
    border-color: #aa8;
    right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
    <div id="low">
    <select id="dropdown_01">
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
        <option>Option 4</option>
        <option>Option 5</option>
    </select>
    </div>
    <div id="medium">
    <select id="dropdown_02">
        <option>Option A</option>
        <option>Option B</option>
        <option>Option C</option>
        <option>Option D</option>
        <option>Option E</option>
    </select>
    </div>
    <div id="high">
    <select id="dropdown_03">
        <option>Option a</option>
        <option>Option b</option>
        <option>Option c</option>
        <option>Option d</option>
        <option>Option e</option>
    </select>
    </div>

Upvotes: 0

Victor Gelmutdinov
Victor Gelmutdinov

Reputation: 489

I stopped two problems with selectmenu in dialog:

1) Selectmenu overflow is hidden by dialog.

2) In Jquery 1.10 there is breaking changes, so dialogs z-index is recalculating on the fly. This hides selectmenu dropdown items after clicking somewhere inside dialog.

To fix both, you could just append selectmenu to some empty div before body:

$('select').selectmenu({ 
   appendTo: '#someDiv'
})

where someDiv is:

<body>
   ...
   <div id="somediv"></div>
</body>

And make a z-index of selectmenu significantly higher than dialog ui-front layout.

From the jqueryUI sources I spotted that dialog is calculating z-index by sibling elements (I bet they tried to find other dialogs, but using append: 'body' forcing selectmenu to be another element in z-index order.

Upvotes: 0

Nimesh
Nimesh

Reputation: 3610

You can also try this:

.ui-front{z-index:0 !important; } 
.ui-selectmenu-open {z-index:9999 !important;}

Upvotes: 0

CupawnTae
CupawnTae

Reputation: 14580

The problem is that jQuery UI is generating the "drop-down" for the select on the page, but this is outside the div that becomes your popup. Then when the dialog is displayed, it covers the "drop-down".

If you move the selectmenu() call to after the dialog appears, it works correctly.

Your snippet updated:

$('.RegularDialog').dialog({
  autoOpen: false,
  modal: true,
  height: 500,
  width: 570
});
$('#OpenDialog').click(function(e) {
  $('.RegularDialog').dialog('open');
  $('select').selectmenu();
});
<head>
  <link href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css" rel="stylesheet" />
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
</head>

<body>
  <div id="Dialog" title="Edit Dialog" class="RegularDialog">
    <form action="">
      <table>
        <tr>
          <td>Select the Type</td>
          <td>
            <select id="Type">
              <option value="a">Type 1</option>
              <option value="b">Type 2</option>
              <option value="c">Type 3</option>
            </select>
          </td>
        </tr>
      </table>
    </form>
  </div>

  <button id="OpenDialog">Open Dialog</button>
</body>

Upvotes: 13

roshan
roshan

Reputation: 2510

The select gets a display:none on dialog some how. So I did inline styling on it.

I hope this is what you expected.

  $('select').selectmenu();
  $('.RegularDialog').dialog({
    autoOpen: false,
    modal: true,
    height: 500,
    width: 570
  });
  $('#OpenDialog').click(function(e) {
    $('.RegularDialog').dialog('open');
  });
<head>
  <link href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css" rel="stylesheet" />
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
</head>

<body>
  <div id="Dialog" title="Edit Dialog" class="RegularDialog">
    <form action="">
      <table>
        <tr>
          <td>Select the Type</td>
          <td>
            <select style="display:inline-block !important;vertical-align:top;" id="Type">
              <option value="a">Type 1</option>
              <option value="b">Type 2</option>
              <option value="c">Type 3</option>
            </select>
          </td>
        </tr>
      </table>
    </form>
  </div>

  <button id="OpenDialog">Open Dialog</button>

</body>

Upvotes: -1

Related Questions