0

I'm relatively new to D3 and have been having a few issues getting started. I've created a dropdown menu using the code below

var signal = d3.select('#signal_container');
var signalName = ["Please Select", "Temperature", "Pressure", "Load"];
var signalSelect = signal
    .append('select')
    .attr('class', 'select')
    .attr('multiple', '');
var signalOptions = signalSelect
    .selectAll('option')
    .data(signalName).enter()
    .append('option')
    .text(function (d) { return d; });

I was wondering if there was a way to limit the number of options that the user can select in the multiple select dropdown menu? Say I want to set the limit at 2 and they've selected 'Temperature' and 'Load', if they were to try and select 'Pressure' it wouldn't be possible as the limit for selected options is set at 2.

Also, how would I be able to get the values of the selected options? I'm currently using

d3.select('#signal_container').select('select').property('value');

But obviously that is only getting the value of the first select options.

Thanks in advance for your help

LM2016
  • 43
  • 8

1 Answers1

0

There are lots of way to do what you are after programmatically. Here's one such implementation that handles the enable/disable of options in the click event of the options:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <div id="signal_container"></div>
  <br/>
  <button id="someButton">Get Values!</button>
  <script>
    var signal = d3.select('#signal_container');
    var signalName = ["Please Select", "Temperature", "Pressure", "Load"];
    var signalSelect = signal
      .append('select')
      .attr('class', 'select')
      .attr('multiple', '');

    var selectedValues = [];
    var signalOptions = signalSelect
      .selectAll('option')
      .data(signalName).enter()
      .append('option')
      .text(function(d) {
        return d;
      })
      .on('click', function(d) {
        var s = signalOptions.filter(function(d) {
          return this.selected;
        });
        if (s.nodes().length >= 2) {
          signalOptions.filter(function() {
              return !this.selected
            })
            .property('disabled', true);
        } else {
          signalOptions.property('disabled', false);
        }
      });

    d3.select('#someButton')
      .on('click', function(d) {
        var v = signalOptions.filter(function(d) {
          return this.selected;
        }).data();
        alert(v);
      });
  </script>
</body>

</html>

FOR COMMENTS

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <div id="signal_container"></div>
  <br/>
  <button id="someButton">Get Values!</button>
  <script>
    var signal = d3.select('#signal_container');
    var signalName = ["Please Select", "Temperature", "Pressure", "Load"];
    var signalSelect = signal
      .append('select')
      .attr('class', 'select')
      .attr('multiple', '')
      .on('change', function(d) {
        var s = signalOptions.filter(function(d) {
          return this.selected;
        });
        if (s.nodes().length >= 2) {
          signalOptions.filter(function() {
              return !this.selected
            })
            .property('disabled', true);
        } else {
          signalOptions.property('disabled', false);
        }
      });

    var selectedValues = [];
    var signalOptions = signalSelect
      .selectAll('option')
      .data(signalName).enter()
      .append('option')
      .text(function(d) {
        return d;
      });

    d3.select('#someButton')
      .on('click', function(d) {
        var v = signalOptions.filter(function(d) {
          return this.selected;
        }).data();
        alert(v);
      });
  </script>
</body>

</html>
Mark
  • 104,129
  • 18
  • 164
  • 224
  • This is exactly what I was looking for. Thanks! – LM2016 Jun 27 '17 at 15:03
  • This code doesn’t appear to work in IE. I’ve had a play around with it and it seems as though the .on(‘click’, ) isn’t being fired up. I was wondering if you had any suggestions? – LM2016 Jun 29 '17 at 11:53
  • @LM2016, my bad, IE doesn't handle [click events on options](https://stackoverflow.com/a/3341751/16363). See edits above, just change the event to be on the `select`. – Mark Jun 29 '17 at 12:19
  • I thought that might be the issue so I tried it earlier but it still didn't work. – LM2016 Jun 29 '17 at 12:41
  • @LM2016, tested my above code snippet (the 2nd one) with IE11 (11.413.15063.0). It seems to work fine. If you are targeting IE<11, I don't have anyway to test that. – Mark Jun 29 '17 at 14:37
  • Thanks for your help...turns out it was a silly typo on my part. – LM2016 Jun 30 '17 at 07:23