TransWikia.com

Identificar um com jQuery

Stack Overflow em Português Asked on February 19, 2021

Bom montei um select com jQuery, para identificar uma tag <optgroup> tenho que usar um data-i, exemplo:

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

Tem alguma forma de identificar a tag <optgroup> sem ter que usar um data-i?

Segue o código funcionando.

(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>

3 Answers

Já não uso JQuery faz milhares de anos, então o código está "mais próximo do JS vanilla", do que qualquer outra coisa...

Sua pergunta é confusa, e ao mesmo tempo meio óbvia. Existe apenas dois lugares onde é utilizado o data('i'), então ao invés de obter o data-i você pode obter o "index" do elemento baseado em todos os optgroup existente...

Para isso utilizei:

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

Ou seja, o $optgroups é todos os optgroups, então encontramos o "index" dele e simplesmente somamos +1 à ele (já que os indexes originalmente, do seu código, partem de 1).

Eu sinalizei com o ////////////////////////////////////////// onde há alterações.

(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>

Correct answer by Inkeliz on February 19, 2021

Para pegar em qual grupo pertence o valor selecionado, você pode usar a função .closest() do JQuery, e você pode comparar via a descrição do label.

Exemplo:

<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>

Para pegar o selecionado pode usar a função abaixo, que irá retornar o grupo que está selecionado.

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

Exemplo em: http://jsfiddle.net/jkeyes/zjLCp/1/

Também é possível usar o .parent()

Exemplo em: http://jsfiddle.net/zjLCp/512/

Mas se você só quer saber se a opção existe:

$("select[name=testSelect] > optgroup ").length > 0

Answered by Don't Panic on February 19, 2021

Você pode usar o change para pegar o valor selecionado no atributo value.

Exemplo:

 $('select').change(function() {
    var selected = $(':selected', this);
    alert(selected.val());
});

Answered by Netinho Santos on February 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP