Estoy buscando una manera de cambiar las opciones en un formulario de rieles. Seleccione el campo a través de JavaScript en función de la opción seleccionada para otro campo de selección.
La forma en que intentaba hacer esto antes era usando dos campos separados con el mismo objeto y diferentes conjuntos de opciones, así:
<%= form_with(model: my_model) do |form| %> <div class="form-floating" id="input"> <%= form.select :input, ['a', 'b'], { }, class: "form-control" %> <%= form.label :input %> </div> <div class="form-floating" id="output1"> <%= form.select :output, ['c', 'd'], { }, class: "form-control" %> <%= form.label :output %> </div> <div class="form-floating" id="output2"> <%= form.select :output, ['e', 'f'], { }, class: "form-control" %> <%= form.label :output %> </div> <script> function onChange() { var selected = $('#input option:selected').text() if (selected == 'a') { $('#output1').show() $('#output2').hide() } if (selected == 'b') { $('#output1').hide() $('#output2').show() } } $('#input').change(onChange) $(window).on("turbolinks:load", onChange) </script> <%= form.submit class: "btn" %> <% end %>El problema con este método es que el campo :output se crea dos veces y solo se envía el último (con id="output2"), por lo que ahora estoy buscando una forma de cambiar las opciones de selección en el método onChange() para un solo formulario de salida. Seleccione el campo.
Cualquier ayuda con este problema o una solución alternativa sería muy apreciada, saludos.
Resuelto el problema, publicándolo aquí para cualquier otra persona que tenga este problema. Básicamente, abandoné el asistente de forma de rieles a favor de construir la cadena html usando etiquetas, algo como esto:
function replaceHTML() { var newHTML = '<select class="form-control" name="output" id="output">' var selection = $('#input option:selected').text() var options = selection == 'a' ? ['c', 'd'] : ['e', 'f'] for (let i = 0; i < options.length; i++) { newHTML += '<option value=' + options[i] + '>' + options[i] + '</option>' } newHTML += '</select><label for="output">Output</label>' $('#output').html(newHTML) }Respuesta corta: Use $('#output-')prop('disabled', true); en lugar de .hide() .
Respuesta larga:
De acuerdo con los documentos de JQuery , .hide() en realidad no deshabilita la entrada, solo la oculta con CSS. Lo mismo con .show() parece . Así que necesitas usar un método diferente para esto. Más sobre esto en un segundo.
En segundo lugar, la razón por la que solo se envía el segundo cuadro de selección, output2 , es probablemente porque ambos están configurados para ser <%= form.select :output %> . De acuerdo con los documentos de Rails , bajo el capó, Rails está configurando ambas entradas de esta manera:
<select name="output"></select> Dado que tiene dos cuadros de selección con el mismo atributo de name , se sobrescriben entre sí. Esto se debe nuevamente a que está usando .hide() y .show() , por lo que en realidad no están deshabilitados.
Creo que esto funcionaría en tu escenario. Intenta usar $("output").prop('disabled', true); al igual que:
function onChange() { var selected = $('#input option:selected').text() if (selected == 'a') { $('#output1').show() $('#output2').prop('disabled', true); } if (selected == 'b') { $('#output1').prop('disabled', true); $('#output2').show() } } Si usa la versión de JQuery < 1.5, puede usar $("input").attr('disabled','disabled'); de acuerdo con esta respuesta de desbordamiento de pila .