Подтвердить что ты не робот

Инициализация динамически созданной группы кнопок btn-переключателей

Я занимаюсь написанием некоторых вспомогательных функций для моих коллег-разработчиков, которые не слишком знакомы с Bootstrap, - который берет базовый html и создает для них макеты начальной загрузки.

В этом случае я пытаюсь сделать правильный горизонтальный список переключателей.

Пример:

    <fieldset data-type="horizontal" data-bootstrap="radiogroup">
        <label>
            <input type="radio" name="g1" value="default" data-bind="checked: true"/>Recent
        </label>
        <label>
            <input type="radio" name="g1" value="order" data-bind="checked: false"/>By Number
        </label>
        <label>
            <input type="radio" name="g1" value="advanced" data-bind="checked: false"/>Advanced
        </label>
    </fieldset>

Я запускаю некоторый JQuery внутри файла typescript, связанного с этой страницей, и код читает:

    function layoutUnwrappedBootstrapControls() {
        $("*[data-bootstrap='radiogroup']")
            .each((index, element) => {
                var listOfRadioButtons = $(element).find('label').clone();
                $(element).children().remove();
                $(element)
                    .append("<div class='btn-group col-lg-12 col-md-12 col-sm-12 col-xs-12 clearfix' data-toggle='buttons'></div>");
                $(element)
                    .children(":first")
                    .append(listOfRadioButtons)
                    .find("label")
                    .addClass("btn btn-primary")
                    .css("width", (100 / listOfRadioButtons.length) + '%');
                $(element).children(":first").button().button('refresh'); //< the issue   
            });
    }

Что производит:

<div class="btn-group col-lg-12 col-md-12 col-sm-12 col-xs-12 clearfix" data-toggle="buttons">
    <label class="btn btn-primary" style="width: 33.3333%;">
        <input type="radio" name="g1" value="default" data-bind="checked: true" data-mini="true" data-theme="h" id="tz15" checked="checked">Recent
    </label>
    <label class="btn btn-primary" style="width: 33.3333%;">
        <input type="radio" name="g1" value="order" data-bind="checked: false" data-mini="true" data-theme="h" id="tz16">By Number
    </label>
    <label class="btn btn-primary" style="width: 33.3333%;">
        <input type="radio" name="g1" value="advanced" data-bind="checked: false" data-mini="true" data-theme="h" id="tz17">Advanced
    </label>
</div>

На странице это кажется прекрасным. Тем не менее, проблема, я имею в виду часть data-toggle='buttons' - она ​​говорит мне, что bootstrap запускает некоторый код, чтобы инициализировать список переключателей - и, похоже, он не играет хорошо с динамически созданными кнопочными группами.

Моя попытка повторной инициализации группы кнопок не работает. Кнопки радио по-прежнему остаются статическими - не заменяются "активными" на метке и "проверяются" на входе.

Часть спойлера: я не могу воспроизвести свою проблему на JSFiddle, используя идентичный код! он работает так, как ожидалось, на JSFiddle: JSFiddle

Как заставить повторную инициализацию динамически созданной группы кнопок?

4b9b3361

Ответ 1

Проблема заключалась в том, что, как упоминал @knetsi в комментариях по этому вопросу, когда у вас нет загрузочного файла bootstrap.js, вы не получите сообщение об ошибке в консоли, чтобы указать, что выпуск был. Когда, как и на моем сайте, вы работаете как с JQuery UI/JQuery Mobile/JQuery, так и с Bootstrap JS, Bootstrap нужно загружать последним - поскольку это приведет к конфликту с другими библиотеками при попытке обновить кнопку

Ответ 2

Если вы снова вызовете документ, тогда предыдущие события, связанные с использованием bootstrap.js, будут отключаться, что не очень хорошо, поэтому вы можете либо изменить последовательность выполнения вашего script (означает, что перед загрузкой boot.rap) сам документ готов, пока вы не закончите свой script. Вы можете получить ссылку на jquery.holdready here https://api.jquery.com/jquery.holdready/

Ответ 3

Если ваш код выполняется после того, как bootstrap уже сделал это, он не будет работать...

Вам нужно сделать свой код исполненным перед загрузкой...

Итак, вам нужно либо,

  • Добавьте сценарии перед загрузкой, если вы используете событие, готовое к документу.
  • Передвиньте свои скрипты сразу после html (в нижнем колонтитуле) без использования документа, готового к событию.

Ответ 4

Следующие работали для меня (локально и в скрипке).

Помимо включения document.ready в тег script внутри тела (упомянутый в предыдущих ответах), похоже, что у вашего нокаутного связывания есть проблема. Я изменил checked: true / checked: false на checked: statusMsg и добавил statusMsg: ko.observable("default"). Нокаут проверяет радиокассету, когда значение наблюдаемых равно некоторым радио входам nodeValue. Из документации:

Для переключателей KO задает элемент для проверки, если  и только если значение параметра равно значению переключателя node s атрибут или значение, указанное параметром checkedValue.

Проверенная документация по привязке к нокауту

Я запустил значения checked для полей после нажатия и отработал.

Мой код и скрипка ниже:

<body>
<fieldset data-type="horizontal" data-bootstrap="radiogroup">
  <label>
    <input type="radio" name="g1" value="default" data-bind="checked: statusMsg"/>Recent
  </label>
  <label>
    <input type="radio" name="g1" value="order" data-bind="checked: statusMsg"/>By Number
  </label>
  <label>
    <input type="radio" name="g1" value="advanced" data-bind="checked: statusMsg"/>Advanced
  </label>
</fieldset>
<script>
$(document).ready(function() {
    $("*[data-bootstrap='radiogroup']")
        .each((index, element) => {
            var listOfRadioButtons = $(element).find('label').clone();
            $(element).children().remove();
            $(element)
                .append("<div class='btn-group col-lg-12 col-md-12 col-sm-12 col-xs-12 clearfix' data-toggle='buttons'></div>");
            $(element)
                .children(":first")
                .append(listOfRadioButtons)
                .find("label")
                .addClass("btn btn-primary")
                .css("width", (100 / listOfRadioButtons.length) + '%');
        });
    var viewModel = {
        statusMsg: ko.observable("default")
    }
    ko.applyBindings(viewModel);
});
</script>
</body>

Рабочая скрипка здесь