Relacionados con: Bootstrap Grupo De Botones De Radio

HTML:

<div class="btn-group" data-toggle="buttons">
    <label class="btn btn-primary">
        <input type="radio" name="options" id="option1" value="1" data-bind="checked: optionsValue"> Option 1
    </label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="option2" value="2" data-bind="checked: optionsValue"> Option 2
    </label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="option3" value="3" data-bind="checked: optionsValue"> Option 3
    </label>
</div>
<br />
<span data-bind="text: optionsValue"></span>

Javascript:

var ViewModel = function() {
    this.optionsValue = ko.observable()
};

ko.applyBindings(new ViewModel());

JsFiddle:


Tengo el código de arriba que estoy tratando de conseguir trabajo como esperaba. El problema es que cuando data-toggle="buttons" se agrega a la btn-group div (como en el Bootstrap 3 ejemplo) el knock-out de enlace deja de funcionar. Si dejo la data-toggle de los botones del grupo, a continuación, el enlace funciona como se espera, pero el botón de grupo se ve horrible. Sé que esto no funciona en Bootstrap 2, ya que en realidad no uso la radio de entrada para su radio estilo. ¿Cómo es que se niega ahora a trabajar, incluso a pesar de que hacer?

  • El Bootstrap toogle botones todavía no jugar bonito con KO por lo que necesita un enlace personalizado controlador de algo como esto: jsfiddle.net/hd89y
  • Tenga en cuenta que el Botón de Radio de los grupos a través de este código no funcionó correctamente en Bootstrap 2.x (a pesar de que también mostró el Botón de Radio dentro del «botón» a menos que escondió a sí mismo). Esto es debido a que el Bootstrap 2.x código no intenta interceptar los clics – prefiere uso real button elementos para simular este comportamiento de la misma.
InformationsquelleAutor Kittoes0124 | 2013-11-19

6 Comentarios

  1. 49

    La bootstrap botones y la knockout checked unión todavía no están jugando bien:

    • knockout utiliza el click evento dentro de la checked la unión a tigger la inferior observables para cambiar
    • bootstrap se suscribe en el evento click para hacer la alternancia pero las llamadas e.preventDefault() así KO no ser notificado sobre el clic.

    Una posible solución es crear un enlace personalizado controlador de donde usted se suscribe en la change evento (esto es despedido por bootstrap en toogle) y el conjunto de sus características observables de valor allí:

    ko.bindingHandlers.bsChecked = {
        init: function (element, valueAccessor, allBindingsAccessor,
        viewModel, bindingContext) {
            var value = valueAccessor();
            var newValueAccessor = function () {
                return {
                    change: function () {
                        value(element.value);
                    }
                }
            };
            ko.bindingHandlers.event.init(element, newValueAccessor,
            allBindingsAccessor, viewModel, bindingContext);
        },
        update: function (element, valueAccessor, allBindingsAccessor,
        viewModel, bindingContext) {
            if ($(element).val() == ko.unwrap(valueAccessor())) {
                 setTimeout(function () {
                    $(element).closest('.btn').button('toggle');
                 }, 1); 
            }
        }
    }

    Y utilizar en su vista con:

    <label class="btn btn-primary">
        <input type="radio" name="options" id="option1" value="1" 
               data-bind="bsChecked: optionsValue"> Option 1
    </label>

    Original demo usando Bootstrap 3.0.2 JSFiddle.

    Actualizado demo usando Bootstrap 3.2.0 JSFiddle.

    • Soy curioso en cuanto a por qué el correo.preventDefault() la llamada está allí en el primer lugar…
    • usted debe preguntar a autor acerca de…
    • lol, lo siento hombre. Sólo me preguntaba si no como alguna razón obvia detrás de él como soy bastante nuevo en esto de javascript cosa. Su respuesta funcionado muy bien es una pena que algo así como que es necesario.
    • Tengo curiosidad por cómo sería de conseguir que esto funcione en una única casilla de verificación además de los botones de radio.
    • Excelente post!!! Aquí está una adaptación para la casilla de verificación botón de grupo: jsfiddle.net/MEA33/1
    • Gracias. Estoy utilizando este código, en la que se trabajo, excepto en un verdadero IE 8 browser (navegador se bloquea). He creado una pregunta aquí: stackoverflow.com/questions/21536447/… cualquier ayuda se agradece
    • He visto tu pregunta y ya era capaz de reproducir el problema en IE8 pero no tengo idea de por qué es crahes. Así que usted necesitará algunos de los más avanzados bedugging técnicas para encontrar exactamente qué es lo que hace que el IE accidente.
    • Arggg.. muerte a IE!
    • Se rompe de nuevo con bootstrap 3.1.1, hacer clic en no mostrar el botón de alternar, pero cambiando el valor de vm obras – jsfiddle.net/a4bc2/2
    • interesante. No estoy seguro de que no lo ha cambiado, pero como una solución rápida a un setTimeout en el controlador de actualización soluciona el problema: jsfiddle.net/9PF9q
    • problema similar aquí. De datos está bien, pero el BS & KO tanto cambiar el valor. La adición de && !$(elemento).prop(‘checked’)) condición para actualizar fijo para mí
    • Este parece ser roto de nuevo en 3.2.0, alguien puede aconsejar cómo solucionarlo? jsfiddle.net/a4bc2/5
    • con algunos modificaiton (un setTimeout) está trabajando de nuevo: jsfiddle.net/22osabd0
    • todas las ideas para 4.0 bootstrap?

  2. 15

    No puedo tomar el crédito para esto ya que una vez en mis compañeros de trabajo se acercó a ella, pero funciona realmente bien.

    <div class="btn-group" data-toggle="buttons">
        <label data-bind="css: { active: !HideInLeaderboards() }, 
                          click: function () { HideInLeaderboards(false); },
                          clickBubble: false" 
                          class="btn btn-default">
            Show Name
        </label>
        <label data-bind="css: { active: HideInLeaderboards() },
                          click: function () { HideInLeaderboards(true); },
                          clickBubble: false" class="btn btn-default">
            Hide Name
        </label>
    </div>
    • Gracias, esto funciona muy bien para múltiples vinculados alterna el uso de la misma observable!
  3. 1

    cambiar el controlador de @nemesv propone este: y funcionó en mi app muy bien.

    ko.bindingHandlers.bsChecked = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = valueAccessor();
            var newValueAccessor = function () {
                return {
                    change: function () {
                        value(element.value);
                    }
                }
            };
            if ($(element).val() == ko.unwrap(valueAccessor())) {
                $(element).closest('.btn').button('toggle');
            }
            ko.bindingHandlers.event.init(element, newValueAccessor, allBindingsAccessor, viewModel, bindingContext);
        }
    }
  4. 1

    Knockstrap parece ser un enlace entre Bootstrap y octavos de final, y parece que se mantiene muy bien hasta la fecha. Sobre los botones de la radio en específico, que utilizar este código:

    //Knockout checked binding doesn't work with Bootstrap radio-buttons
    ko.bindingHandlers.radio = {
        init: function (element, valueAccessor) {
    
            if (!ko.isObservable(valueAccessor())) {
                throw new Error('radio binding should be used only with observable values');
            }
    
            $(element).on('change', 'input:radio', function (e) {
                //we need to handle change event after bootsrap will handle its event
                //to prevent incorrect changing of radio button styles
                setTimeout(function() {
                    var radio = $(e.target),
                        value = valueAccessor(),
                        newValue = radio.val();
    
                    value(newValue);
                }, 0);
            });
        },
    
        update: function (element, valueAccessor) {
            var $radioButton = $(element).find('input[value="' + ko.unwrap(valueAccessor()) + '"]'),
                $radioButtonWrapper;
    
            if ($radioButton.length) {
                $radioButtonWrapper = $radioButton.parent();
    
                $radioButtonWrapper.siblings().removeClass('active');
                $radioButtonWrapper.addClass('active');
    
                $radioButton.prop('checked', true);
            } else {
                $radioButtonWrapper = $(element).find('.active');
                $radioButtonWrapper.removeClass('active');
                $radioButtonWrapper.find('input').prop('checked', false);
            }
        }
    };
  5. 1

    Hay un enfoque mucho más fácil encontrar aquí.

    Podemos no utilizar el data-toggle atributo y tratar de lograr el mismo comportamiento usando octavos de final del enlace de datos.

    Es casi tan simple como el html nativo radios.

    JS:

    var ViewModel = function() {
      this.optionsValue = ko.observable("1");
    };
    
    ko.applyBindings(new ViewModel());

    CSS:

    input[type="radio"] {
      /* Make native radio act the same as bootstrap's radio. */
      display: none;
    }

    HTML:

    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <div class="btn-group">
      <label class="btn btn-primary" data-bind="css: {active: optionsValue() == '1'}">
        <input type="radio" name="options" id="option1" value="1" data-bind="checked: optionsValue">Option 1
      </label>
      <label class="btn btn-primary" data-bind="css: {active: optionsValue() == '2'}">
        <input type="radio" name="options" id="option2" value="2" data-bind="checked: optionsValue">Option 2
      </label>
      <label class="btn btn-primary" data-bind="css: {active: optionsValue() == '3'}">
        <input type="radio" name="options" id="option3" value="3" data-bind="checked: optionsValue">Option 3
      </label>
    </div>
    <br/>
    <span data-bind="text: optionsValue"></span>

  6. 0

    Hay una solución simple aquí que me sorprende que no se ha mencionado todavía.

    1) Retire el data-toggle="buttons" de la btn-group

    Ahora knock-out debe ser de trabajo

    2) Bootstrap se aplica css personalizado para estas entradas para ocultarlos, que perdimos por la extracción de los datos de alternancia, por lo que aplicar la siguiente regla css para la radio entradas:

    position: absolute;
    clip: rect(0,0,0,0);
    pointer-events: none;

    3) Última cosa que necesitamos es para la opción seleccionada, el botón para que la clase activa. Agregue lo siguiente a la etiqueta botones:

    data-bind="css: {active: optionsValue() == valueOfThisInput}"

Dejar respuesta

Please enter your comment!
Please enter your name here