Identify a <optgroup> with jQuery

Asked

Viewed 401 times

0

Well I set up a select with jQuery, to identify a tag <optgroup> I have to wear a data-i, example:

<optgroup label='PRODUTOS' data-i="1">

Do you have any way to identify the tag <optgroup> without having to use a data-i?

Follow the code working.

(function ($) {

    $.fn.niceSelect = function () {

        // Hide native select
        this.hide();

        // Create custom markup
        this.each(function () {
            var $select = $(this);

            if (!$select.next().hasClass('nice-select')) {
                create_nice_select($select);
            }
        });

        function create_nice_select($select) {
            $select.after($('<div></div>')
                    .addClass('nice-select')
                    .addClass($select.attr('class') || '')
                    .addClass($select.attr('disabled') ? 'disabled' : '')
                    .attr('tabindex', $select.attr('disabled') ? null : '0')
                    .html('<span class="current"></span><ul class="list"></ul>')
                    );

            var $dropdown = $select.next();
            var $options = $select.find('option');
            var $optgroups = $select.find('optgroup');
            var $selected = $select.find('option:selected');

            $dropdown.find('.current').html($selected.data('display') || $selected.text());

            $options.each(function () {
                var $option = $(this);
                var display = $option.data('display');
                var group = $option.parents('optgroup').data('i');

                $dropdown.find('ul').append($('<li></li>')
                        .attr('data-value', $option.val())
                        .attr('data-display', (display || null))
                        .attr('data-group', (group || null))
                        .addClass('option' +
                                ($option.is(':selected') ? ' selected' : '') +
                                ($option.is(':disabled') ? ' disabled' : ''))
                        .html($option.text())
                        );
            });
            $optgroups.each(function(i, g) {
              label = $(g).attr('label');
              $dropdown.find('ul li').filter(function() {
                return $(this).data('group') === $(g).data('i');
              })
              .wrapAll('<div class="optgroup"/>')
              .parent()
              .prepend('<span class="label">' + label + '</span>');
            });
        }

        /* Event listeners */
        // Unbind existing events in case that the plugin has been initialized before
        $(document).off('.nice_select');

        // Open/close
        $(document).on('click.nice_select', '.nice-select', function () {
            var $dropdown = $(this);

            $('.nice-select').not($dropdown).removeClass('open');
            $dropdown.toggleClass('open');

            if ($dropdown.hasClass('open')) {
                $dropdown.find('.option');
                $dropdown.find('.focus').removeClass('focus');
                $dropdown.find('.selected').addClass('focus');
            } else {
                $dropdown.focus();
            }
        });

        // Close when clicking outside
        $(document).on('click.nice_select', function (event) {

            if ($(event.target).closest('.nice-select').length === 0) {
                $('.nice-select').removeClass('open').find('.option');
            }
        });

        // Animation loading a page
        $('select').on('blur', function (e) {
            $(this).parents('.form-group-select').toggleClass('focused', (e.type === 'focus' || this.value !== ''));
        }).trigger('blur');

        // Option click
        $(document).on('click.nice_select', '.nice-select .option:not(.disabled)', function () {

            var $option = $(this);
            var $dropdown = $option.closest('.nice-select');

            $dropdown.find('.selected').removeClass('selected');
            $option.addClass('selected');

            var text = $option.data('display') || $option.text();
            $dropdown.find('.current').text(text);

            $dropdown.prev('select').val($option.data('value')).trigger('change');

            // Animation
            $(this).parents('.form-group-select').toggleClass('focused', ($option.data('value') !== ''));
        });

        // Keyboard events
        $(document).on('keydown.nice_select', '.nice-select', function (event) {

            var $dropdown = $(this);
            var $focused_option = $($dropdown.find('.focus') || $dropdown.find('.list .option.selected'));

            // Space or Enter
            if (event.keyCode === 32 || event.keyCode === 13) {
                if ($dropdown.hasClass('open')) {
                    $focused_option.trigger('click');
                } else {
                    $dropdown.trigger('click');
                }
                return false;

                // Down
            } else if (event.keyCode === 40) {
                if (!$dropdown.hasClass('open')) {
                    $dropdown.trigger('click');
                } else {
                    var $next = $focused_option.nextAll('.option:not(.disabled)').first();
                    if ($next.length > 0) {
                        $dropdown.find('.focus').removeClass('focus');
                        $next.addClass('focus');
                    }
                }
                return false;

                // Up
            } else if (event.keyCode === 38) {
                if (!$dropdown.hasClass('open')) {
                    $dropdown.trigger('click');
                } else {
                    var $prev = $focused_option.prevAll('.option:not(.disabled)').first();
                    if ($prev.length > 0) {
                        $dropdown.find('.focus').removeClass('focus');
                        $prev.addClass('focus');
                    }
                }
                return false;

                // Esc
            } else if (event.keyCode === 27) {
                if ($dropdown.hasClass('open')) {
                    $dropdown.trigger('click');
                }

                // Tab
            } else if (event.keyCode === 9) {
                if ($dropdown.hasClass('open')) {
                    return false;
                }
            }
        });
        return this;
    };
}(jQuery));
$('select').niceSelect();
.control-label {
    pointer-events: none;
    position: absolute;
    transform: translate3d(5px, 22px, 0) scale(1);
    transform-origin: left top;
    transition: 240ms;
}.form-group-select.focused .control-label {
    transform: scale(0.75);
}
.form-group-select {
    width: 100%;
    margin-top: 20px;
    position: relative;
    height: 45px;
    float: left;
}
.nice-select:before {
    width: 100%;
    height: 1px;
    background: #0091FF;
    position: absolute;
    left: 0;
    bottom: 0;
    content: '';
    transform: scaleX(0);
    transition: ease-in-out 240ms all;
}
.nice-select.open::before {
    transform: scaleX(1);
}
.nice-select {
    -webkit-tap-highlight-color: transparent;
    box-sizing: border-box;
    clear: both;
    cursor: pointer;
    display: block;
    height: 42px;
    line-height: 40px;
    outline: none;
    position: relative;
    text-align: left !important;
    -webkit-transition: all 0.2s ease-in-out;
    transition: all 0.2s ease-in-out;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    white-space: nowrap;
    width: 100%;
    border: 0 solid #484848;
    border-bottom-width: 1px;
    margin-top: 3px;
}
.nice-select span {
    margin-left: 5px;
}
.nice-select:hover, .nice-select:focus {
    border-color: #0091FF;
}
.nice-select:after {
    border-bottom: 2px solid #484848;
    border-right: 2px solid #484848;
    content: '';
    display: block;
    height: 5px;
    margin-top: -4px;
    pointer-events: none;
    position: absolute;
    right: 12px;
    top: 50%;
    -webkit-transform-origin: 66% 66%;
    -ms-transform-origin: 66% 66%;
    transform-origin: 66% 66%;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
    -webkit-transition: all 0.15s ease-in-out;
    transition: all 0.15s ease-in-out;
    width: 5px;
}
.nice-select.open:after {
    -webkit-transform: rotate(-135deg);
    -ms-transform: rotate(-135deg);
    transform: rotate(-135deg);
}
.nice-select.open .list {
    color: #484848;
    opacity: 1;
    pointer-events: auto;
    -webkit-transform: scale(1) translateY(0);
    -ms-transform: scale(1) translateY(0);
    transform: scale(1) translateY(0);
}
.nice-select.disabled {
    border-color: #ededed;
    color: #999;
    pointer-events: none;
}
.nice-select.disabled:after {
    border-color: #cccccc;
}
.nice-select .list {
    background-color: #FFF;
    border-radius: 4px;
    box-sizing: border-box;
    margin-top: 4px;
    opacity: 0;
    overflow: hidden;
    padding: 0;
    pointer-events: none;
    position: absolute;
    top: 100%;
    left: 0;
    -webkit-transform-origin: 50% 0;
    -ms-transform-origin: 50% 0;
    transform-origin: 50% 0;
    -webkit-transform: scale(0.75) translateY(-21px);
    -ms-transform: scale(0.75) translateY(-21px);
    transform: scale(0.75) translateY(-21px);
    -webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
    transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
    width: 100%;
    z-index: 99;
}
.nice-select .list:before {
    content: '';
    display: block;
    height: 7px;
    border-radius: 4px 4px 0px 0px;
}
.nice-select .list:after {
    content: '';
    display: block;
    height: 7px;
    border-radius: 0px 0px 4px 4px;
}
.nice-select .option {
    cursor: pointer;
    line-height: 40px;
    list-style: none;
    min-height: 40px;
    outline: none;
    padding-left: 18px;
    padding-right: 29px;
    text-align: left;
    border-left: 7px solid #FFF;
}
.nice-select .option:hover {
    background-color: #000;
    background: #EEEEEE;
    border-left: 7px solid #F65314;
}
.nice-select .option.selected {
    font-weight: bold;
}
.nice-select .option.disabled {
    background-color: transparent;
    color: #999;
    cursor: default;
}
.no-csspointerevents .nice-select .list {
    display: none;
}
.no-csspointerevents .nice-select.open .list {
    display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='form-group-select'>
  <label class='control-label'>GOSTOU?</label>
  <select name='gostou'>
                    <option value=""></option>
                    <optgroup label='PRODUTOS' data-i="1">
                        <option value="s">SIM</option>
                        <option value="n">NÃO</option>
                         <optgroup label='PRODUTOS' data-i="2">
                        <option value="s">SIM</option>
                        <option value="n">NÃO</option>
                </select>
</div>

  • Has to id, by tag or other attribute, but for me it was not very clear what is your question or problem.

  • Good and a doubt I wanted to take out the id and make the jQuery identify the <optgroup tag>

3 answers

1


I haven’t used Jquery for thousands of years, so the code is "closer to JS vanilla" than anything else...

Your question is confusing, and at the same time kind of obvious. There are only two places where the data('i'), then instead of getting the data-i you can get the "index" of the element based on all optgroup existing...

For that I used:

               var grupo_atual = $(g).parents('optgroup');
                
                var group = 1;
                $optgroups.each(function(i, gg) {
                  if ($(gg).is(grupo_atual)) {
                    group += i
                  }
                })

That is, the $optgroups is all the optgroups, then we find his "index" and simply add +1 to him (since the Dexes originally, from their code, start from 1).

I signaled with the ////////////////////////////////////////// where there are changes.

(function ($) {

    $.fn.niceSelect = function () {

        // Hide native select
        this.hide();

        // Create custom markup
        this.each(function () {
            var $select = $(this);

            if (!$select.next().hasClass('nice-select')) {
                create_nice_select($select);
            }
        });

        function create_nice_select($select) {
            $select.after($('<div></div>')
                    .addClass('nice-select')
                    .addClass($select.attr('class') || '')
                    .addClass($select.attr('disabled') ? 'disabled' : '')
                    .attr('tabindex', $select.attr('disabled') ? null : '0')
                    .html('<span class="current"></span><ul class="list"></ul>')
                    );

            var $dropdown = $select.next();

            //////////////////////////////////////////
            var $options = $select.find('optgroup option');
            //////////////////////////////////////////            

            var $optgroups = $select.find('optgroup');
            var $selected = $select.find('option:selected');
            
            $dropdown.find('.current').html($selected.data('display') || $selected.text());

            $options.each(function (_, g) {
                var $option = $(this);
                var display = $option.data('display');
                
           
                //////////////////////////////////////////
                var grupo_atual = $(g).parents('optgroup');
                
                var group = 1;
                $optgroups.each(function(i, gg) {
                  if ($(gg).is(grupo_atual)) {
                    group += i
                  }
                })
                //////////////////////////////////////////

                $dropdown.find('ul').append($('<li></li>')
                        .attr('data-value', $option.val())
                        .attr('data-display', (display || null))
                        .attr('data-group', (group || null))
                        .addClass('option' +
                                ($option.is(':selected') ? ' selected' : '') +
                                ($option.is(':disabled') ? ' disabled' : ''))
                        .html($option.text())
                        );
            });
            $optgroups.each(function(i, g) {
              label = $(g).attr('label');
              $dropdown.find('ul li').filter(function() {

                //////////////////////////////////////////
                var group = 1;
                $optgroups.each(function(i, gg) {
                  if ($(gg).is(g)) {
                    group += i
                  }
                })
                return $(this).data('group') === group;
               //////////////////////////////////////////

              })
              .wrapAll('<div class="optgroup"/>')
              .parent()
              .prepend('<span class="label">' + label + '</span>');
            });
        }

        /* Event listeners */
        // Unbind existing events in case that the plugin has been initialized before
        $(document).off('.nice_select');

        // Open/close
        $(document).on('click.nice_select', '.nice-select', function () {
            var $dropdown = $(this);

            $('.nice-select').not($dropdown).removeClass('open');
            $dropdown.toggleClass('open');

            if ($dropdown.hasClass('open')) {
                $dropdown.find('.option');
                $dropdown.find('.focus').removeClass('focus');
                $dropdown.find('.selected').addClass('focus');
            } else {
                $dropdown.focus();
            }
        });

        // Close when clicking outside
        $(document).on('click.nice_select', function (event) {

            if ($(event.target).closest('.nice-select').length === 0) {
                $('.nice-select').removeClass('open').find('.option');
            }
        });

        // Animation loading a page
        $('select').on('blur', function (e) {
            $(this).parents('.form-group-select').toggleClass('focused', (e.type === 'focus' || this.value !== ''));
        }).trigger('blur');

        // Option click
        $(document).on('click.nice_select', '.nice-select .option:not(.disabled)', function () {

            var $option = $(this);
            var $dropdown = $option.closest('.nice-select');

            $dropdown.find('.selected').removeClass('selected');
            $option.addClass('selected');

            var text = $option.data('display') || $option.text();
            $dropdown.find('.current').text(text);

            $dropdown.prev('select').val($option.data('value')).trigger('change');

            // Animation
            $(this).parents('.form-group-select').toggleClass('focused', ($option.data('value') !== ''));
        });

        // Keyboard events
        $(document).on('keydown.nice_select', '.nice-select', function (event) {

            var $dropdown = $(this);
            var $focused_option = $($dropdown.find('.focus') || $dropdown.find('.list .option.selected'));

            // Space or Enter
            if (event.keyCode === 32 || event.keyCode === 13) {
                if ($dropdown.hasClass('open')) {
                    $focused_option.trigger('click');
                } else {
                    $dropdown.trigger('click');
                }
                return false;

                // Down
            } else if (event.keyCode === 40) {
                if (!$dropdown.hasClass('open')) {
                    $dropdown.trigger('click');
                } else {
                    var $next = $focused_option.nextAll('.option:not(.disabled)').first();
                    if ($next.length > 0) {
                        $dropdown.find('.focus').removeClass('focus');
                        $next.addClass('focus');
                    }
                }
                return false;

                // Up
            } else if (event.keyCode === 38) {
                if (!$dropdown.hasClass('open')) {
                    $dropdown.trigger('click');
                } else {
                    var $prev = $focused_option.prevAll('.option:not(.disabled)').first();
                    if ($prev.length > 0) {
                        $dropdown.find('.focus').removeClass('focus');
                        $prev.addClass('focus');
                    }
                }
                return false;

                // Esc
            } else if (event.keyCode === 27) {
                if ($dropdown.hasClass('open')) {
                    $dropdown.trigger('click');
                }

                // Tab
            } else if (event.keyCode === 9) {
                if ($dropdown.hasClass('open')) {
                    return false;
                }
            }
        });
        return this;
    };
}(jQuery));
$('select').niceSelect();
.control-label{pointer-events:none;position:absolute;transform:translate3d(5px,22px,0) scale(1);transform-origin:left top;transition:240ms}.form-group-select.focused .control-label{transform:scale(.75)}.form-group-select{width:100%;margin-top:20px;position:relative;height:45px;float:left}.nice-select:before{width:100%;height:1px;background:#0091ff;position:absolute;left:0;bottom:0;content:'';transform:scaleX(0);transition:ease-in-out 240ms all}.nice-select.open::before{transform:scaleX(1)}.nice-select{-webkit-tap-highlight-color:transparent;box-sizing:border-box;clear:both;cursor:pointer;display:block;height:42px;line-height:40px;outline:0;position:relative;text-align:left!important;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;white-space:nowrap;width:100%;border:0 solid #484848;border-bottom-width:1px;margin-top:3px}.nice-select span{margin-left:5px}.nice-select:focus,.nice-select:hover{border-color:#0091ff}.nice-select:after{border-bottom:2px solid #484848;border-right:2px solid #484848;content:'';display:block;height:5px;margin-top:-4px;pointer-events:none;position:absolute;right:12px;top:50%;-webkit-transform-origin:66% 66%;-ms-transform-origin:66% 66%;transform-origin:66% 66%;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg);-webkit-transition:all .15s ease-in-out;transition:all .15s ease-in-out;width:5px}.nice-select.open:after{-webkit-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.nice-select.open .list{color:#484848;opacity:1;pointer-events:auto;-webkit-transform:scale(1) translateY(0);-ms-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}.nice-select.disabled{border-color:#ededed;color:#999;pointer-events:none}.nice-select.disabled:after{border-color:#ccc}.nice-select .list{background-color:#fff;border-radius:4px;box-sizing:border-box;margin-top:4px;opacity:0;overflow:hidden;padding:0;pointer-events:none;position:absolute;top:100%;left:0;-webkit-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform:scale(.75) translateY(-21px);-ms-transform:scale(.75) translateY(-21px);transform:scale(.75) translateY(-21px);-webkit-transition:all .2s cubic-bezier(.5,0,0,1.25),opacity .15s ease-out;transition:all .2s cubic-bezier(.5,0,0,1.25),opacity .15s ease-out;width:100%;z-index:99}.nice-select .list:before{content:'';display:block;height:7px;border-radius:4px 4px 0 0}.nice-select .list:after{content:'';display:block;height:7px;border-radius:0 0 4px 4px}.nice-select .option{cursor:pointer;line-height:40px;list-style:none;min-height:40px;outline:0;padding-left:18px;padding-right:29px;text-align:left;border-left:7px solid #fff}.nice-select .option:hover{background-color:#000;background:#eee;border-left:7px solid #f65314}.nice-select .option.selected{font-weight:700}.nice-select .option.disabled{background-color:transparent;color:#999;cursor:default}.no-csspointerevents .nice-select .list{display:none}.no-csspointerevents .nice-select.open .list{display:block}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='form-group-select'>
  <label class='control-label'>GOSTOU?</label>
  <select name='gostou'>
    <option value=""></option>
    <optgroup label='PRODUTOS'>
        <option value="s">SIM</option>
        <option value="n">NÃO</option>
     </optgroup>
     <optgroup label='PRODUTOS'>
        <option value="s">SIM</option>
        <option value="n">NÃO</option>
     </optgroup>
  </select>
</div>

0

You can use change to take the selected value from the value attribute.

Example:

 $('select').change(function() {
    var selected = $(':selected', this);
    alert(selected.val());
});
  • I don’t quite understand, can you change this example? https://jsfiddle.net/vje5xxgb/

  • Sorry, I don’t understand exactly what you want. Here’s the change with the code I posted. https://jsfiddle.net/vje5xxgb/1/

  • Sorry, buddy, I made a mess here when it came time to answer the question. What I meant was for you to change the code of my question with your answer. because I don’t understand how your solution can work with the plugin I’m using.

0

To pick which group the selected value belongs to, you can use the function .closest() of Jquery, and you can compare via the description of label.

Example:

<select name="testSelect">
   <optgroup label="fruits">
      <option value="apples">Apples</option>
      <option value="oranges">Oranges</option>
      <option value="pears">Pears</option>
   </optgroup>
   <optgroup label="cars">
      <option value="ford">ford</option>
      <option value="toyota">toyota</option>
      <option value="ferrari">ferrari</option>
   </optgroup>
</select>

To catch the selected you can use the function below, which will return the group that is selected.

$('select').change(function() {
    var selected = $(':selected', this);
    alert(selected.closest('optgroup').attr('label'));
});​

Example in: http://jsfiddle.net/jkeyes/zjLCp/1/

It is also possible to use the .parent()

Example in: http://jsfiddle.net/zjLCp/512/

But if you just want to know if the option exists:

$("select[name=testSelect] > optgroup ").length > 0
  • I understood, I tried to do this way with the plugin I’m using and it’s not working. I could change my question with your answer?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.