Como fazer um dropdown readonly usando jquery?

91

Estou usando a instrução a seguir para torná-la somente leitura, mas não está funcionando.

$('#cf_1268591').attr("readonly", "readonly"); 

Eu não quero desativá-lo, quero torná-lo somente leitura.

Karim Ali
fonte
4
Qual seria a diferença entre um menu suspenso somente leitura e um menu suspenso padrão?
Leo
Este é realmente um problema do jQuery? Ou talvez a lista suspensa simplesmente não funcione com o atributo somente leitura?
Ilia G
Kanishka Panamaldeniya já lhe deu a resposta correta (deve torná-la uma resposta em vez de um comentário).
qbantek
2
O menu suspenso nem sempre é somente leitura. Somente leitura significa que você pode ver seu valor, mas não pode alterá-lo.
Suncat2000

Respostas:

182
$('#cf_1268591').attr("disabled", true); 

drop down é sempre somente leitura. o que você pode fazer é desativá-lo

se você trabalha com um formulário, os campos desabilitados não são enviados, então use um campo oculto para armazenar o valor da lista suspensa desabilitada

Kanishka Panamaldeniya
fonte
26
Desativar uma lista suspensa não envia. Vou tentar sua solução.
Karim Ali
3
Um problema em desabilitar uma seleção (lista suspensa) é que o foco é perdido em alguns navegadores (por exemplo, IE9). Isso pode ser um problema se o elemento select estiver sendo desabilitado enquanto uma chamada ajax é processada, por exemplo, quando a posição do usuário no formulário é perdida.
Chris
1
Obrigado por sua sugestão. Só uma pergunta; como eu armazenaria o valor suspenso em um campo oculto? Você teria algum código de exemplo para isso?
kramer65 de
2
Outra "solução alternativa" seria habilitar esses campos antes do envio do formulário. Ou no meu caso onde enviei os dados no formato JSON (habilitar, obter dados, desabilitar novamente): var disabled = $ (yourform) .find (': input: disabled'). RemoveAttr ('disabled'); var data = getFormJSONData ($ (yourform)); disabled.attr ('desativado', 'desativado');
KDT
4
Você deveria estar usando prop()agora.
alex
144

Tive o mesmo problema, minha solução foi desabilitar todas as opções não selecionadas. Muito fácil com jQuery:

$('option:not(:selected)').attr('disabled', true);

Editar => Se você tiver vários menus suspensos na mesma página, desative todas as opções não selecionadas em select-ID conforme abaixo.

$('#select_field_id option:not(:selected)').attr('disabled', true);
Bertrand D.
fonte
24
Boa ideia! Para usar as melhores práticas com as versões atuais do jQuery, eu usaria o método prop para definir o valor desativado. ie$('option:not(:selected)').prop('disabled', true);
Chris O'Connell
Esta é uma solução muito inteligente!
Jacques
1
SIM! boa ideia.
Eric
1
Esta deve ser a resposta n ° 1.
Erwan Clügairtz de
22

Experimente este .. sem desabilitar o valor selecionado ..

$('#cf_1268591 option:not(:selected)').prop('disabled', true);

Funciona para mim..

Prabhagaran
fonte
Na mesma linha de sua resposta, removi as outras opções $ ('# cf_1268591 opção: not (: selected)'). Remove ();
Seth Winters
20

Isso é o que você está procurando:

$('#cf_1268591').attr("style", "pointer-events: none;");

Funciona como um encanto.

Mainak Chakraborty
fonte
1
Ótima resposta, mas cuidado, pois isso ainda permite selecionar para. Você também precisa definir otabindex="-1"
uesports135
Grande Homem, eu preciso disso, como desativado não mapeado para o modelo obrigado pela sua resposta.
sina_Islam,
13

Definir um elemento com disablednão enviará os dados, mas os selectelementos não readonly.

Você pode simular um readonlyem selectusar CSS para estilizar e JS para evitar a mudança com guia:

select[readonly] {
  background: #eee;
  pointer-events: none;
  touch-action: none;
}

Em seguida, use-o como:

var readonly_select = $('select');
$(readonly_select).attr('readonly', true).attr('data-original-value', $(readonly_select).val()).on('change', function(i) {
    $(i.target).val($(this).attr('data-original-value'));
});

Resultado:

Lucas Bustamante
fonte
2
Abordagem muito legal, mas o usuário ainda pode usar TAB no teclado para selecionar um valor.
Ricardo Martins
1
@RicardoMartins obrigado, atualizou a resposta para evitar mudança com TAB
Lucas Bustamante
12

Eu desativaria o campo. Então, quando o formulário for enviado, faça com que ele não seja desativado. Na minha opinião, isso é mais fácil do que lidar com campos ocultos.

//disable the field
$("#myFieldID").prop( "disabled", true );           

//right before the form submits, we re-enable the fields, to make them submit.
$( "#myFormID" ).submit(function( event ) {
    $("#myFieldID").prop( "disabled", false );
});     
NL3294
fonte
8

Jquery simples para remover opções não selecionadas.

$('#your_dropdown_id option:not(:selected)').remove();
abhi chavda
fonte
Também minha solução. Melhor do que torná-los deficientes.
Gianluca Demarinis
6

Para simplificar as coisas, aqui está um plugin jQuery que faz isso sem complicações: https://github.com/haggen/readonly

Arthur Corenzan
fonte
Ótimo (pequeno) trecho de código, obrigado. Ele desativa os menus suspensos para que não possam ser alterados, mas ainda permite que seus valores sejam enviados. Muito útil.
Alex Hopkins
3

Esta linha faz seleções com o readonlyatributo somente leitura:

$('select[readonly=readonly] option:not(:selected)').prop('disabled', true);
Admirhodzic
fonte
2

Este código armazenará primeiro a seleção original em cada menu suspenso. Então, se o usuário alterar a seleção, ele redefinirá o menu suspenso para sua seleção original.

http://jsfiddle.net/4aHcD/22/

//store the original selection
$("select :selected").each(function(){
    $(this).parent().data("default", this);
});

//change the selction back to the original
$("select").change(function(e) {
    $($(this).data("default")).prop("selected", true);
});
Homer
fonte
2

A opção mais fácil para mim foi selecionar como somente leitura e adicionar:

onmousedown="return false" onkeydown="return false"

Você não precisa escrever nenhuma lógica extra. Sem entradas ocultas ou desativado e reativado no envio do formulário.

Awais Tariq
fonte
1

É um artigo antigo, mas quero alertar as pessoas que irão encontrá-lo. Tenha cuidado com o atributo desativado com elemento obtido por nome. Estranho, mas parece não funcionar muito.

isso não funciona:

<script language="JavaScript">
function onChangeFullpageCheckbox() {    
$('name=img_size').attr("disabled",$("#fullpage").attr("checked"));
</script>

Este trabalho:

<script language="JavaScript">
function onChangeFullpageCheckbox() {    
$('#img_size').attr("disabled",$("#fullpage").attr("checked"));
</script>

Sim, eu sei que é melhor eu usar prop e não attr, mas pelo menos agora prop não funcionará por causa da versão antiga do jquery, e agora não posso atualizá-lo, não pergunte por quê ... a diferença de html é apenas adicionada id:. ..

<select name="img_size" class="dropDown" id="img_size">
<option value="200">200px
</option><option value="300">300px
</option><option value="400">400px
</option><option value="500">500px
</option><option value="600" selected="">600px
</option><option value="800">800px
</option><option value="900">900px
</option><option value="1024">1024px
</option></select>

<input type="checkbox" name="fullpage" id="fullpage" onChange="onChangeFullpageCheckbox()" />

...

Não encontrei erros no script, e na versão com nome não houve erros no console. Mas é claro que pode ser meu erro no código

Visto em: Chrome 26 no Win 7 Pro

Desculpe pela gramática ruim.

Andrej
fonte
1

Descobri que a melhor maneira de fazer isso é usar CSS para remover eventos de ponteiro e modificar a opacidade no menu suspenso (tente 0,5). Isso dá a impressão ao usuário de que está desabilitado normalmente, mas ainda publica dados.

Concedido, isso tem alguns problemas de compatibilidade com versões anteriores, mas na minha opinião é uma opção melhor do que contornar o problema irritante de desabilitar / somente leitura.

user3427526
fonte
Você pode explicar o CSS necessário para fazer isso?
Cocowalla
1

Você também pode desativá-lo e, no momento em que fizer a chamada de envio, ativá-lo. Acho que é a maneira mais fácil :)

Hictus
fonte
1

Funciona muito bem

$('#cf_1268591 option:not(:selected)').prop('disabled', true);

Com isso eu posso ver as opções, mas não consigo selecioná-las

Ricardo Mendes
fonte
0

Não existe uma lista suspensa somente leitura. O que você pode fazer é redefini-lo para o primeiro valor manualmente após cada alteração.

$("select").change(function(event) {
    $(this).val($(this).find("option").first().val());
});

http://jsfiddle.net/4aHcD/

Alex Turpin
fonte
3
não é bom se a opção atualmente selecionada não for a primeira na lista como neste exemplo: jsfiddle.net/4aHcD/19
Homer
@Homer, o código se destina a redefini-lo após qualquer alteração e funciona nesse sentido. Se você quiser que ele seja executado inicialmente em vez de alterar o valor inicial sozinho por algum motivo, você sempre pode chamar o evento de mudança em seu elemento depois de declarar o evento, usando $("select").change(), assim, jsfiddle.net/4aHcD/20
Alex Turpin
2
quando a página é carregada pela primeira vez, se o terceiro item for selecionado e o usuário tentar alterá-lo para o segundo item, seu código altera a seleção para o primeiro item. Eu não acho que não deveria fazer isso. Aqui está um exemplo do que eu acho que o OP queria, um menu suspenso que não mudará seu valor selecionado com base na interação do usuário: jsfiddle.net/4aHcD/22
Homer
O que eu preciso e o que o OP estava solicitando era uma maneira de torná- lo somente leitura. Isso significa que você pode ver o valor ou valores selecionados, mas não pode alterá-los. Isso significa que a exibição imita a aparência do controle editável sem ser capaz de editá-lo.
Suncat2000
0

Tente fazer uma string vazia ao "pressionar a tecla"

O Html é:

<input id="cf_1268591" style="width:60px;line-height:16px;border:1px solid #ccc">

O Jquery é:

$("#cf_1268591").combobox({
  url:"your url",
  valueField:"id",
  textField:"text",
  panelWidth: "350",
  panelHeight: "200",
});

// faça após a ativação com string vazia

var tb = $("#cf_1268591").combobox("textbox");
  tb.bind("keyup",function(e){
  this.value = "";
});
Hendro
fonte
0

Talvez você possa tentar desta forma

function myFunction()
{
   $("select[id^=myID]").attr("disabled", true);
   var txtSelect = $("select[id^=myID] option[selected]").text();
}

Isso define o primeiro valor do menu suspenso como o padrão e parece somente leitura

Monicalh
fonte
0

suporte a html5:

`
     $("#cCity").attr("disabled", "disabled"); 
     $("#cCity").addClass('not-allow');

`

Atul Kumar
fonte
0

Aqui está uma ligeira variação nas outras respostas que sugerem o uso de desativado. Como o atributo "disabled" pode ter qualquer valor e ainda assim ser desativado, você pode defini-lo como somente leitura, como disabled = "somente leitura". Isso desabilitará o controle, como de costume, e também permitirá que você facilmente estilize-o de forma diferente dos controles desabilitados regulares, com CSS como:

select[disabled=readonly] {
    .... styles you like for read-only
}

Se você deseja que os dados sejam incluídos no envio, use os campos ocultos ou habilite antes de enviar, conforme detalhado nas outras respostas.

DaveInMaine
fonte
0

Como @Kanishka disse, se desativarmos um elemento do formulário, ele não será enviado. Eu criei um snippet para este problema. Quando o elemento de seleção está desativado, ele cria um campo de entrada oculto e armazena o valor. Quando está ativado, ele exclui os campos de entrada ocultos criados.

Mais informações

jQuery(document).ready(function($) {
  var $dropDown = $('#my-select'),
    name = $dropDown.prop('name'),
    $form = $dropDown.parent('form');

  $dropDown.data('original-name', name); //store the name in the data attribute 

  $('#toggle').on('click', function(event) {
    if ($dropDown.is('.disabled')) {
      //enable it 
      $form.find('input[type="hidden"][name=' + name + ']').remove(); // remove the hidden fields if any
      $dropDown.removeClass('disabled') //remove disable class 
        .prop({
          name: name,
          disabled: false
        }); //restore the name and enable 
    } else {
      //disable it 
      var $hiddenInput = $('<input/>', {
        type: 'hidden',
        name: name,
        value: $dropDown.val()
      });
      $form.append($hiddenInput); //append the hidden field with same name and value from the dropdown field 
      $dropDown.addClass('disabled') //disable class
        .prop({
          'name': name + "_1",
          disabled: true
        }); //change name and disbale 
    }
  });
});
/*Optional*/

select.disabled {
  color: graytext;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form action="#" name="my-form">
  <select id="my-select" name="alpha">
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
  </select>
</form>
<br/>
<button id="toggle">toggle enable/disable</button>

Amiya
fonte