Chosen: Torne os rótulos optgroup clicáveis

Criado em 26 out. 2011  ·  38Comentários  ·  Fonte: harvesthq/chosen

Ao usar um select com optgroups, ter todos os itens em um grupo adicionados à seleção quando o rótulo do grupo é clicado seria um recurso muito útil. Isso tornaria a seleção de um grupo menos um item muito fácil também.
Por exemplo, tenho um formulário de filtro com países agrupados por zona. No momento, se alguém deseja selecionar um grupo menos um item, ele deve selecionar todos os itens um por um. Com esse recurso, ele simplesmente clica no grupo e remove o país que não deseja.

Feature Request

Comentários muito úteis

@ Fr3nzzy : se me permite, a seleção de html padrão também não permite a pesquisa ... ainda é muito conveniente, e é por isso que Chosen é ótimo - melhora a seleção padrão. Acho que podemos aplicar o mesmo raciocínio aqui.

@ greg0ire : +1, também estou procurando por isso: o)

Todos 38 comentários

Isso será útil, mas o html-select padrão não permite isso.

@ Fr3nzzy : sim, mas se fosse opcional, isso não seria um problema, seria?

@ Fr3nzzy : se me permite, a seleção de html padrão também não permite a pesquisa ... ainda é muito conveniente, e é por isso que Chosen é ótimo - melhora a seleção padrão. Acho que podemos aplicar o mesmo raciocínio aqui.

@ greg0ire : +1, também estou procurando por isso: o)

@ pilap82 No entanto, o select permite encontrar um item digitando seu nome.

é justo :)

Talvez não seja o melhor lugar para um patch, mas espero que possa ajudar:

$( '.chzn-results .group-result' ).each( function () {
    var self      = $( this )
        , options = $( '~li', self )
        , next    = options.filter( '.group-result' ).get( 0 )
    ;
    self.data( 'chzn-options', options.slice( 0, options.index( next ) ) );
} )
.click( function () { 
    $( this ).data( 'chzn-options' ).mouseup()
 } )
.hover( function () { 
    $( this ).data( 'chzn-options' ).addClass( 'highlighted' );
 }, function () { 
    $( this ).data( 'chzn-options' ).removeClass( 'highlighted' );
 } )
.css( { cursor: 'pointer' } );

Esta é uma ótima idéia. Estou disposto a enviar uma solicitação pull se a equipe principal estiver aberta para mesclá-la. O que você acha @pfiller?

amostra de seleção de lote com escolhido:

http://vafada.github.com/chosen-dojo/

Bem feito!

Eu gostaria de ver isso adicionado ao Escolhido, mas a escuta de eventos deve ser adicionada de uma forma menos intensiva. A solução de @adriengibrat aplica um ouvinte a cada grupo que não tem um desempenho tão bom se houver centenas de grupos. Já temos um evento de clique no div de resultados da pesquisa que pode ser testado em relação aos grupos de opções. Se a opção for definida, css deve ser usado para alterar a cor de fundo.

+1. Eu estava pensando que quando o optgroup fosse selecionado, ele (opcionalmente) desabilitaria / ocultaria todos os seus filhos.

+1 para este recurso

@pfiller alguma atualização sobre este ou o branch search_improvements? Adoraria vê-lo fundido com o master.

Também preciso de grupos selecionáveis. Eu originalmente tentei mudar o código - então fui inspirado pela resposta frequentemente oferecida para "pular o optgroup e adicionar espaços para indentar os subitens". Isso parecia horrível, mas já que Chosen é bem estilizado por CSS ... que tal usar um não optgroup select e usar uma classe em cada opção para fazer com que pareça uma exibição agrupada?

Você pode ver uma versão básica neste violino: http://jsfiddle.net/slothbear/9xqpF/

Não gastei muito tempo com o estilo, mas você vai entender. Isso fornece dois recursos que eu preciso - optgroups selecionáveis ​​e optgroups pesquisáveis. Tudo sem optgroups.

Estou perto de avançar com essa técnica em meu projeto, mas estou procurando feedback. Parece funcionar. Você pode pensar em uma maneira melhor? Ou alguma pegadinha?

_Já percebi que provavelmente deveria mencionar - que o violino está usando o fork do Koenpunt de Chosen, para habilitar a adição de opções. Mas não acho que isso afete este exemplo._

_Também procuro orientação. Eu sei que esta técnica está provavelmente muito longe da Filosofia Escolhida para ficar perto dos recursos select - mas se uma opção for apropriada para este recurso, eu ficaria feliz em fazer o trabalho._

1 para este recurso, achei escolhido enquanto procurava uma maneira de apoiar este

(Eu estava procurando ser capaz de selecionar um título de grupo OU selecionar um item de grupo) de acordo com o do Slothbear acima

Edit: No final, eu emulei isso fazendo o seguinte.
Observe as classes, também adicionei .clickable ao css que define o cursor como um ponteiro.

<select name="category" data-placeholder="Choose a category..." class="chosen-select">
    <option value="group-1 class="group-result clickable">Group Title</option>
    <option value="1" class="group-option">Item Name</option>
    <option value="2" class="group-option">Item Name</option>
</select>

Aqui está minha solução. Embora seja específico para minhas necessidades, pode-se facilmente ajustá-lo e alterá-lo de acordo com as necessidades dele.

Exemplo:
carros
-car1
-car2
-car3
plano
-plane1
-plane2

O que fiz foi criar uma nova opção no início de todos os grupos, dessa forma, as opções 'Todos' virão logo após os grupos:
carros
-Todos os carros
-car1
-car2
-car3
pessoas
-Todas as pessoas
-pessoa1
-pessoa2

Em 'results_option_build', passe a opção 'All' para 'result_add_group' como segundo parâmetro quando os dados são um grupo e pule a opção 'All' na próxima iteração:

if (data.group) {
conteúdo + = this.result_add_group (dados, _ref [++ _ i])

Agora, vamos para 'result_add_group' e substitua o grupo pela opção que passamos, mas mantenha o estilo do grupo:
result_add_group = function (group, option) {
.
.
Retorna "

  • "+ group.search_text +"
  • ";

    É isso .. Se quiser, mude o cursor para ponteiro em css.

    Nenhum deles parece levar em consideração a capacidade de pesquisa. Por padrão, em escolhido, se você pesquisar uma opção, ela também mostrará o rótulo do grupo. Este método não funciona, se eu tiver vários grupos e eles tiverem opções idênticas, isso fará com que eu acabe apenas com uma lista de itens visualmente idênticos.

    Seria muito interessante estar integrado como opção na biblioteca, pois facilitaria o gerenciamento de seleção múltipla. Você se referiu a squeeze em alguma versão? uma saudação

    Eu implementei isso apenas usando o javascript, é uma correção temporária. Eu não o uso para várias seleções, porém, eu o uso para agrupamento personalizado. Acabei fazendo com que os grupos fossem opções, mas parecessem grupos, e dei aos 'grupos' palavras-chave que, quando você fizer uma pesquisa pela subopção, o grupo aparecerá como faria normalmente em choose.js http: // stackoverflow. com / q / 22336052/744228

    Eu adicionei isso à minha cópia local do escolhido porque era um requisito para o meu projeto. No final, foi bastante fácil.

    Na função set_default_values coloco this.group_selectable = this.options.group_selectable != null ? this.options.group_selectable === true : false; no final.

    Então em result_add_group mudei as classes atribuídas ao grupo para serem

    if (this.group_selectable) {
            group_el.className = "active-result group-result";
          } else {
            group_el.className = "group-result";
          }
    group_el.setAttribute("data-group-array-index", group.array_index);
    

    E por último, mas não menos importante, em result_select um pequeno hack e adicionado

    if (high[0].getAttribute("data-group-array-index")) {
              var that = this;
              high.nextUntil('.group-result').each(function(index, element) {
                that.result_highlight = $(element);
                that.result_select(evt);
              });
            }
    

    um pouco antes
    item = this.results_data[high[0].getAttribute("data-option-array-index")];

    Veja o código completo em https://gist.github.com/ruhley/9944574

    https://gist.github.com/ruhley/9944574#file -chosen-jquery-js-L1005

    var itm = that.results_data[element.getAttribute("data-option-array-index")];
    if(itm && !itm.selected){
        that.result_highlight = $(element);
        that.result_select(evt);
    }
    

    Um pouco tarde para a festa, mas: +1 para este recurso!

    @ruhley +1 para sua solução, funciona
    Apenas um pequeno detalhe que está na página de código completa, mas não no segmento de código: há um
    outro{
    faltando no final.

    Oi,
    Obrigado @ruhley pelo seu código.
    Mas com suas modificações, o grupo não é desabilitado após ser clicado e pode ser selecionado novamente.

    Aqui estão minhas melhorias (com base no 1.4.2 escolhido):

    • Após a linha 158, na função "set_default_values", adicione:
    this.group_selectable = this.options.group_selectable != null ? this.options.group_selectable === true : false;
    

    _Adição do parâmetro_

    • Altere a linha 222, na função "results_option_build", com:
    content += this.result_add_group(data, _ref.slice(_i+1, _i+data.children+1));
    

    _Dê as crianças para a função "result_add_group" ._

    • Altere a linha 272, redefinição da função "result_add_group", com:
    AbstractChosen.prototype.result_add_group = function(group, childrens) {
    

    _Para receber as crianças_

    • Após a linha 285 ( group_el = document.createElement("li"); ), na função "result_add_group", adicione:
    if (this.group_selectable) {
      var all = true;
      $.each(childrens, function(index, element) {
        if(!element.selected){
          all = false;
        }
      });
      if(!all) {
        classes.push("active-result");
      } else {
        classes.push("result-selected");
      }
    }
    group_el.setAttribute("data-group-array-index", group.array_index);
    

    _Isto torna o grupo clicável se pelo menos um filho não for selecionado. (esta parte é improvável por causa da variável "all") ._

    • Após a linha 1052 ( high.addClass("result-selected"); ), na função "result_select", adicione:
    if (high[0].getAttribute("data-group-array-index")) {
      var that = this;
      high.nextUntil('.group-result').each(function(index, element) {
        if($(element).hasClass('active-result')) {
          that.result_highlight = $(element);
          that.result_select(evt); 
        }
      });
    } else {
    

    _Isto só adiciona crianças não selecionadas._

    • Após a linha 1083, na função "result_select":
    }
    

    _Precisa fechar a condição de um grupo clicado._

    Não se esqueça de indentar corretamente esse trecho de código;)

    Aqui está uma versão completa do meu arquivo: https://gist.github.com/GuillaumeSTEIN/7a4ece3c6bb487d16df0
    Aqui está uma diferença (1 ano disponível): https://www.diffnow.com/?report=8zhe9
    Divirta-se

    Ainda não foi implementado?

    @GuillaumeSTEIN Eu tentei sua versão completa do script, nada parece mudar.
    Preciso adicionar alguns parâmetros ou classes especiais ao HTML para que funcione?
    Talvez você possa fazer um exemplo prático em http://codepen.io/ ou jsfiddle?

    Sim, você precisa definir a opção: group_selectable como true para ativar este recurso

    obrigado @GuillaumeSTEIN , funcionou, mas o que sinto falta do script @adriengibrat , é destacar todas as opções do grupo atual.

    grupos selecionados têm uma classe de "seleção de resultados".
    Você pode fazer algum CSS. Aqui está o que escrevi, pode ser necessário adaptá-lo às suas necessidades:

     select.form-control + .chosen-container-multi .chosen-results li.result-selected{
         display: list-item;
         color: #ccc;
         cursor: default;
         background-color: white;
     }
    

    Eu dei uma olhada nele # 2678

    Este seria um recurso muito útil! Eu adoraria ver isso implementado!

    1 para este recurso.

    Se alguém achar isso útil, eu pego @slothbear jsfiddle e o aprimoro com:

    • Botão "Limpar tudo"
    • Selecionar o item da categoria raiz desativa e desmarca as crianças. Porque ? No meu caso, eu usaria o escolhido para gerar um filtro de hierarquia, onde selecionar um nó pai implica que iria pesquisar em todas as categorias de filhos, e não desejamos poluir a IU colocando todos os filhos como selecionados.

    http://jsfiddle.net/Zardoz/pf6dhrbc/6/

    Acabei de atualizar para 1.8.3 escolhido para que os resultados permaneçam abertos depois de selecionar um resultado em uma seleção múltipla (adicionado na versão 1.7.0). Excelente recurso, feliz por ter sido adicionado. No entanto, eu estava usando 1.6.1 e usei o código aqui para permitir que um grupo inteiro fosse adicionado ao clicar no nome do grupo: http://robido.com/jquery/add-selectdeselect-optgroup-click-events-harvests- escolhido-jquery-plugin /

    Esse código tem funcionado muito bem, até agora. Usando 1.8.3 e hide_results_on_ select: false faz com que algo quebre, e só seleciona a opção de resultado atualmente destacada. Quando essa linha é removida (configurando-a de volta para o padrão de true, ocultar ao selecionar), ela funciona bem e seleciona todas as opções de resultados do grupo. Portanto, algo em hide_results_on_ select: false está quebrando / interferindo com a capacidade de reunir todos os não .result-selecionados em um .group-result. Sacrificar essa capacidade pelo novo recurso é brutal.

    Analisarei todos os comentários acima para ver se isso foi considerado uma falha do novo recurso, mas não posso dizer qual versão as pessoas estão usando quando estão testando isso.

    Alguma ideia?

    Certo. eu tive o suficiente. "atualizar" para 1.8.3 não foi nada além de um jogo de bater uma toupeira na semana passada. problemas de css, problemas de atividades inesperadas, etc. Eu atualizei para obter os resultados de manter abertos no recurso de seleção múltipla (que levou anos para implementar em primeiro lugar), mas descobri que sempre volta ao topo ao selecionar a partir dos resultados, então que bom é isso - tudo isso esperando por nada. o desempenho em um único select com muitas opções diminuiu para um rastreamento de alguma forma. e muitos outros problemas para listar aqui. bom trabalho mantendo essa coisa funcionando por tantos anos, eu gostei. mas as melhorias tiveram um custo de degradar a experiência do usuário e eu não posso permitir isso. estou pesquisando como retirar o escolhido e usar o select2. É 2018, hora de encontrar uma ferramenta selecionada que corresponda às expectativas do usuário, que estão cada vez mais difíceis de atender. desculpe e obrigado

    Eu mudei para select2 também, mas não tirei um dump em escolhido antes disso. Você tem uma maneira estranha de dizer "obrigado".

    Olá,
    Se você deseja usar optgroup e poder clicar nele e adicionar automaticamente todas as opções desse grupo, basta adicionar ao seu javascript: (o acionador de evento ".grupo-resultado" pode ser mais restritivo)

    Tenho certeza de que isso pode ser adicionado à classe AbstractChosen, com algo como AbstractChosen.prototype.optgroup_click = function (evt) ....

    $('body').on('click','.group-result',function(){
        // id of select
        var quest=$(this).parent().parent().parent().attr('id');
        quest='#'+quest.substring(0,quest.lastIndexOf('_'));
        // number of optgroup
        var total=$(quest+' optgroup').length;
        // number of group after group-result clicked
        var nb=0;
        $(this).nextAll().each(function(){
            if($(this).hasClass('group-result'))nb++;
        });
        // for clicked group-result, select options in the right select tag by position
        $(quest+' optgroup:nth-of-type('+(total-nb)+')').children().each(function(){
            $(this).prop('selected','selected');
        });
        // update chosen !
        $(quest).trigger('chosen:updated');
    });
    

    Eu usei bootstrap-select e também estava lutando para encontrar algo para poder clicar no optgroup e selecionar todos os seus itens - Este link realmente funcionou para mim, espero que ajude: https://stackoverflow.com/questions/41821115 / select-deselect-optgroup-based-on-option-select-in-select-picker-boostrap

    Esta página foi útil?
    0 / 5 - 0 avaliações

    Questões relacionadas

    blankhang picture blankhang  ·  7Comentários

    vpode picture vpode  ·  5Comentários

    asvetlenko picture asvetlenko  ·  3Comentários

    SFPink picture SFPink  ·  4Comentários

    alexfrancavilla picture alexfrancavilla  ·  9Comentários