0

I have prepared a jsFiddle for my question -

screenshot

I am trying to have jQuery UI Selectable in a table with yellow header and footer rows. Once as a grid of numbers in the left cell and then as a list of letters in the right cell.

Also I am trying to have the table occupy both 100% of browser width and height.

That is why I have assigned CSS-properties width: 100% and height: 100vh to the table and overflow-y: scroll to the both selectables.

For some reason however the right scroll is not working, i.e. the whole list of letters is displayed and thus blows up the table height.

TLDR:

  • Numbers/Letters lists should have same height and be scrollable
  • Yellow header/footer should be visible at top/bottom of browser window

Here is my code -

Javascript:

  $(function() {
    $("#selectable1").selectable();
    $("#selectable2").selectable();
  });

CSS:

<table>
  <tr>
    <td colspan=2 bgcolor="yellow">Header1</td>
  </tr>
  <tr>
    <td>
      <ol id="selectable1">
        <li class="ui-state-default">1</li>
        <li class="ui-state-default">2</li>
        <li class="ui-state-default">3</li>
        <li class="ui-state-default">4</li>
        <li class="ui-state-default">5</li>
        <li class="ui-state-default">6</li>
        <li class="ui-state-default">7</li>
        <li class="ui-state-default">8</li>
        <li class="ui-state-default">9</li>
        <li class="ui-state-default">10</li>
        <li class="ui-state-default">11</li>
        <li class="ui-state-default">12</li>
      </ol>
    </td>
    <td>
      <ol id="selectable2">
        <li class="ui-state-default">A</li>
        <li class="ui-state-default">B</li>
        <li class="ui-state-default">C</li>
        <li class="ui-state-default">D</li>
        <li class="ui-state-default">E</li>
        <li class="ui-state-default">F</li>
        <li class="ui-state-default">G</li>
        <li class="ui-state-default">H</li>
        <li class="ui-state-default">I</li>
        <li class="ui-state-default">J</li>
      </ol>
    </td>
  </tr>
  <tr>
    <td colspan=2 bgcolor="yellow">Footer1</td>
  </tr>
</table>

CSS:

table {
  width: 100%;
  height: 100vh;
}

#selectable1 {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow-y: scroll;
}

#selectable2 {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 100px;
  overflow-y: scroll; /* WHY IS THIS NOT WORKING? */
}

#selectable1 li,
#selectable2 li {
  margin: 3px;
  padding: 1px;
  float: left;
  width: 100px;
  height: 80px;
  font-size: 4em;
  text-align: center;
}

The background for my question is that I am trying to create a card game with playing tables on the left and list of players in the lobby on the right -

game screenshot

5
  • 1
    It's not clear what you need help with. The Selectable or the CSS? Commented Oct 11, 2020 at 15:14
  • The CSS, is there please a way to set the digits and the letters cell to same (and maximal) height? Commented Oct 11, 2020 at 15:24
  • 1
    Do you need to retain the Table structure? If not, I would move each to a DIV and you can then more easily address the CSS issues. Commented Oct 11, 2020 at 15:45
  • I would like to move away from the html TABLE, but I don't understand how to have both header and footer TRs onscreen and then the letters/digits area. I am just not sure how to do that with DIVs Commented Oct 11, 2020 at 15:47
  • I would like the header/footer TR to take as liitle space as possible (but still be visible). And the letters/digits TR take as much space as possible and be scrollable Commented Oct 11, 2020 at 15:48

2 Answers 2

1
+50

Update:

To support IE 11, you can update your CSS to include -ms-grid specific styles and it should work but again you might have to test it thoroughly:

$(function() {
  $("#selectable1").selectable();
  $("#selectable2").selectable();
});
body {
  margin: 0;
  padding: 0;
}

.header {
  background: yellow;
  -ms-grid-row: 1; /* for IE */
}

.footer {
  background: yellow;
  -ms-grid-row: 3; /* for IE */
}

div.table {
  display: grid;
  width: 100vw;
  height: 100vh;
  
  /* for IE */
  display: -ms-grid;
  -ms-grid-columns: 1fr;
  -ms-grid-rows: 20px 1fr 20px;
}

div.container {
  display: grid;
  grid-template-columns: auto 140px;
  grid-column-gap: 10px;
  overflow: hidden;
  
  /* for IE */
  display: -ms-grid;
  -ms-grid-columns: 1fr 140px;
  -ms-grid-rows: 1fr;
  -ms-grid-row: 2;
}

div.container div {
  overflow: auto;
}

div.container div.column1 {
    -ms-grid-column: 1; /* for IE */
}

div.container div.column2 {
    -ms-grid-column: 2; /* for IE */
}

#selectable1 {
  list-style-type: none;
  margin: 0;
  padding: 0;
  flex: 1;
}

#selectable2 {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

#selectable1 li,
#selectable2 li {
  margin: 3px;
  padding: 1px;
  float: left;
  width: 100px;
  height: 80px;
  font-size: 4em;
  text-align: center;
}
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="table">
  <div class="header">Header1</div>
  <div class="container">
    <div class="column1">
      <ol id="selectable1">
        <li class="ui-state-default">1</li>
        <li class="ui-state-default">2</li>
        <li class="ui-state-default">3</li>
        <li class="ui-state-default">4</li>
        <li class="ui-state-default">5</li>
        <li class="ui-state-default">6</li>
        <li class="ui-state-default">7</li>
        <li class="ui-state-default">8</li>
        <li class="ui-state-default">9</li>
        <li class="ui-state-default">10</li>
        <li class="ui-state-default">11</li>
        <li class="ui-state-default">12</li>
      </ol>
    </div>
    <div class="column2">
      <ol id="selectable2">
        <li class="ui-state-default">A</li>
        <li class="ui-state-default">B</li>
        <li class="ui-state-default">C</li>
        <li class="ui-state-default">D</li>
        <li class="ui-state-default">E</li>
        <li class="ui-state-default">F</li>
        <li class="ui-state-default">G</li>
        <li class="ui-state-default">H</li>
        <li class="ui-state-default">I</li>
        <li class="ui-state-default">J</li>
      </ol>
    </div>
  </div>
  <div class="footer">Footer1</div>
</div>

You should be able to use CSS Grid to achieve what you want if you are willing to replace table with them:

$(function() {
  $("#selectable1").selectable();
  $("#selectable2").selectable();
});
body {
  margin: 0;
  padding: 0;
}

.header,
.footer {
  background: yellow;
}

div.table {
  display: grid;
  width: 100vw;
  height: 100vh;
}

div.container {
  display: grid;
  grid-template-columns: auto 140px;
  grid-column-gap: 10px;
  overflow: auto;
}

div.container div {
  overflow-y: auto;
  height: 100%;
}

#selectable1 {
  list-style-type: none;
  margin: 0;
  padding: 0;
  flex: 1;
}

#selectable2 {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

#selectable1 li,
#selectable2 li {
  margin: 3px;
  padding: 1px;
  float: left;
  width: 100px;
  height: 80px;
  font-size: 4em;
  text-align: center;
}
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="table">
  <div class="header">Header1</div>
  <div class="container">
    <div>
      <ol id="selectable1">
        <li class="ui-state-default">1</li>
        <li class="ui-state-default">2</li>
        <li class="ui-state-default">3</li>
        <li class="ui-state-default">4</li>
        <li class="ui-state-default">5</li>
        <li class="ui-state-default">6</li>
        <li class="ui-state-default">7</li>
        <li class="ui-state-default">8</li>
        <li class="ui-state-default">9</li>
        <li class="ui-state-default">10</li>
        <li class="ui-state-default">11</li>
        <li class="ui-state-default">12</li>
      </ol>
    </div>
    <div>
      <ol id="selectable2">
        <li class="ui-state-default">A</li>
        <li class="ui-state-default">B</li>
        <li class="ui-state-default">C</li>
        <li class="ui-state-default">D</li>
        <li class="ui-state-default">E</li>
        <li class="ui-state-default">F</li>
        <li class="ui-state-default">G</li>
        <li class="ui-state-default">H</li>
        <li class="ui-state-default">I</li>
        <li class="ui-state-default">J</li>
      </ol>
    </div>
  </div>
  <div class="footer">Footer1</div>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

This works just perfectly except in the IE browser (which I know I didn't mention). Please let me wait few days and accept the answer. Why is the overflow: auto; needed?
overflow: auto is needed to ensure that container div doesn't expand fully and display scrollbars when content height/width exceeds width/height of it's container. About IE, do you mean edge or IE 11? CSS3 Grid are not supported in IE but are supported in edge. I have updated answer to include css for IE 11.
Yes, now it works with IE 11 just perfectly, thank you. I still have to support IE because my card game is for Russian users, some still using Win 7.
1

Consider the following: https://jsfiddle.net/Twisty/uro3b2ps/17/

HTML

<div class="page">
  <div class="header">Header1</div>
  <div class="content">
    <ol id="selectable1">
      <li class="ui-state-default">1</li>
      <li class="ui-state-default">2</li>
      <li class="ui-state-default">3</li>
      <li class="ui-state-default">4</li>
      <li class="ui-state-default">5</li>
      <li class="ui-state-default">6</li>
      <li class="ui-state-default">7</li>
      <li class="ui-state-default">8</li>
      <li class="ui-state-default">9</li>
      <li class="ui-state-default">10</li>
      <li class="ui-state-default">11</li>
      <li class="ui-state-default">12</li>
    </ol>
    <ol id="selectable2">
      <li class="ui-state-default">A</li>
      <li class="ui-state-default">B</li>
      <li class="ui-state-default">C</li>
      <li class="ui-state-default">D</li>
      <li class="ui-state-default">E</li>
      <li class="ui-state-default">F</li>
      <li class="ui-state-default">G</li>
      <li class="ui-state-default">H</li>
      <li class="ui-state-default">I</li>
      <li class="ui-state-default">J</li>
    </ol>
  </div>
  <div class="footer">
    <td colspan=2 bgcolor="yellow">Footer1</td>
  </div>
</div>

CSS

.header,
.footer {
  width: 100%;
  background-color: yellow;
}

.content {
  height: 100vh;
  overflow: hidden;
}

#selectable1 {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  width: calc(100% - 150px);
  float: left;
}

#selectable2 {
  list-style-type: none;
  margin: 0;
  padding: 10px;
  width: 100px;
  height: 100vh;
  overflow-y: scroll;
}

#selectable1 li,
#selectable2 li {
  margin: 3px;
  padding: 1px;
  float: left;
  width: 100px;
  height: 80px;
  font-size: 4em;
  text-align: center;
}

There are lots of other ways to do this. inline-block is another way of the many ways to block something but allow space after it for other elements. float is also another way.

Basically, you have to set a height for the list element and this will create a scrollbar when there is overflow.

Updated

https://jsfiddle.net/Twisty/uro3b2ps/21/

#selectable2 {
  list-style-type: none;
  margin: 0;
  padding: 10px;
  width: 110px;
  height: 200px;
  overflow-y: scroll;
}

Update 2

https://jsfiddle.net/Twisty/uro3b2ps/25/

This uses jQuery to dynamically set the height based on the Window.

3 Comments

Thank you for your suggestion, but unfortunately the yellow footer is not visible, the #selectable2 seems to push it way down. I was thinking first maybe a jsfiddle issue, but after saving your code to a separate HTML file the issue persists: the footer is not visible.
You have updated your answer by setting a fixed height: 200px; for #selectabled2 but this is not a solution, the footer should be at the bottom of the screen (that is why I am trying to use height: 100vh;for the parent table). In your updated jsfiddle, the yellow footer is near the screen middle
@AlexanderFarber that was not clear from your post. Updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.