Флажок автоматического стиля с темой пользовательского интерфейса jQuery

(нуб jQuery здесь)

Я пытаюсь написать скрипт, который, когда я пишу <input type='checkbox'/>, автоматически преобразует его в кнопку пользовательского интерфейса jQuery и выглядит как флажок. Пока пример кода...

var newCheckboxID = 0;
$( "input:checkbox" ).attr('id', "cbx-" + nextCheckboxID++); // how to do that?
$( "input:checkbox" ).after("<label style='width:16px; height:16px; vertical-align:middle;'></label>");
$( "input:checkbox" ).next().attr("for", $(this).attr('id') ); // doesn't work for sure
$( "input:checkbox" ).button();
$( "input:checkbox" ).button( "option", "text", false );
$( "input:checkbox" ).attr("onclick", "$(this).button( 'option', 'icons', {primary:((this.checked)?'ui-icon-check':null),secondary:null} )");
        

Извините, если это слишком очевидно, но я потерял больше часа на этом...

ИЗМЕНИТЬ

В итоге сделал по старинке (ибо не рабочие части). Любые комментарии для того, чтобы сделать его более компактным и более jQuery, будут оценены... Пример кода

// ---- set ids
var checkboxID = 0;
//$( "input:checkbox" ).attr('id', "cbx-" + nextCheckboxID++); // how to do that?
var cboxes = document.getElementsByTagName('input');           // <-- do this instead
for(var i=0; i<cboxes.length; i++){
    if( cboxes[i].getAttribute('type')!='checkbox' ) continue;
    cboxes[i].setAttribute('id', 'cbx-'+checkboxID++);}

// ---- add labels
$( "input:checkbox" ).after("<label style='width:16px; height:16px; vertical-align:middle;'></label>");
//$( "input:checkbox" ).next().attr("for", $(this).attr('id') ); // doesn't work this
for(var i=0; i<cboxes.length; i++){                              // <-- do this instead
    if( cboxes[i].getAttribute('type')!='checkbox' ) continue;
    cboxes[i].nextSibling.setAttribute('for', cboxes[i].getAttribute('id') );}

// ---- create
$( "input:checkbox" ).button();
$( "input:checkbox" ).button( "option", "text", false );
$( "input:checkbox" ).attr("onclick", "$(this).button( 'option', 'icons', {primary:((this.checked)?'ui-icon-check':null),secondary:null} )");

person ApollonDigital    schedule 25.08.2012    source источник


Ответы (1)


Рабочие примеры:

В дальнейшем я должен отметить 2 основных изменения. Я добавил CSS, чтобы сделать то, что вы пытались сделать с метками в «коде» (там, где это действительно не место).

Кроме того, я изменил HTML для «простоты использования jQuery». Тем не менее, я все же отметил в комментариях, как вы можете легко изменить его обратно.

HTML

<center>
    <button>Create New CheckBox</button>
</center>
<hr />
<div id="CheckBoxes">
    <input class="inp-checkbox" />
    <input class="inp-checkbox" />
    <input class="inp-checkbox" />
    <input class="inp-checkbox" />
</div>​

CSS

.inp-checkbox+label {
    width:16px; 
    height:16px; 
    vertical-align:middle;
}​

JavaScript/jQuery

// keep in mind, and i will explain, some of these "moving-parts" or not needed, but are added to show you the "ease" of jquery and help you see the solution

//  This global function is designed simply to allow the creation of new checkboxes as you specified, however, if you won't be making check boxes at end user time, then i suggest simply moving it to within the .each statement found later on.
//  Also, this could easily be written as a jQuery plugin so that you could make a "chainable" one-line call to change checkboxes to this but let's get to the nitty gritty first
function createCheckBox(ele, i) {
    //  First I simply create the new ID here, of course you can do this inline, but this gives us a bottleneck for possible errors
    var newID = "cbx-"+i;
    //  below we use the param "ele" wich will be a jQuery Element object like $("#eleID")
    //  This gives us the "chainability" we want so we don't need to waste time writing more lines to recall our element
    //  You will also notice, the first thing i do is asign the "attribute" ID
    ele.attr({ "id": newID  })
        //  Here we see "chainability at work, by not closing the last line, we can move right on to the next bit of code to apply to our element
        //  In this case, I'm changing a "property", keep in mind this is kinda new to jQuery,
        //  In older versions, you would have used .attr but now jQuery distinguishes between "attributes" and "properties" on elements (note we are using "edge", aka. the latest jQuery version
        .prop({ "type": "checkbox" })
        //  .after allows us to add an element after, but maintain our chainability so that we can continue to work on the input
        // here of course, I create a NEW label and then immidiatly add its "for" attribute to relate to our input ID
        .after($("<label />").attr({ for: newID  }))
        //  I should note, by changing your CSS and/or changing input to <button>, you can ELIMINATE the previous step all together
        // Now that the new label is added, lets set our input to be a button,
        .button({ text: false }) // of course, icon only
        //  finally, let's add that click function and move on!
        //  again, notice jQuery's chainability allows us no need to recall our element
        .click(function(e) {
            //  FYI, there are about a dozen ways to achieve this, but for now, I'll stick with your example as it's not far from correct
            var toConsole = $(this).button("option", {
                icons: {
                    primary: $(this)[0].checked ? "ui-icon-check" : ""
                }
            });
            console.log(toConsole, toConsole[0].checked);
        });
    //  Finally, for sake of consoling this new button creation and showing you how it works, I'll return our ORIGINAL (yet now changed) element
    return ele;
}

$(function() {
    //  This .each call upon the inputs containing the class I asiged them in the html,
    //  Allows an easy way to edit each input and maintain a counter variable
    //  Thus the "i" parameter
    //  You could also use your ORIGINAL HTML, just change $(".inp-checkbox") to $("input:[type='checkbox']") or even $("input:checkbox")
    $(".inp-checkbox").each(function(i) {
        // as previously noted, we asign this function to a variable in order to get the return and console log it for your future vision!
        var newCheckBox = createCheckBox($(this), i);
        console.log(newCheckBox);
    });

    //  This next button added is simply to show how you can add new buttons at end-time
    //  ENJOY!!!
    $("button").button().on("click", function(e) {
        var checkBoxCount = $("#CheckBoxes .inp-checkbox").length;
        var newCheckBox = $("<input />").addClass("inp-checkbox").appendTo($("#CheckBoxes"));
        createCheckBox(newCheckBox , checkBoxCount);
        console.log(newCheckBox);
    });
});​

Обновление: Первоначальная цель здесь заключалась в том, чтобы просто ответить на вопрос, который заключался в создании флажка в стиле пользовательского интерфейса jQuery и демонстрации того, как jQuery можно использовать несколькими способами. Однако в более позднем комментарии задавался вопрос, как включить в него метку традиционного стиля. Хотя для этого есть миллиард вариантов, я просто возьму из вышеперечисленного и дополню.

Первый вариант, который я выбрал, довольно прост. Используя jsFiddle (without comments with UI theme switcher!), я внес следующие изменения:

JavaScript/jQuery

// First I add a new variable.
// It will simply be for a new "wrapper" element, in which to ensure our button is encased. 
// Giving this element a new class gives easy access for later CSS or Event Triggering of sub elements (like the checkbox)
var newID = "cbx-"+i,
    wrapper = $('<div />', { 'class': 'ui-checkbox-wrapper' }).appendTo('#CheckBoxes');
//  Then I added a line to our ele series of methods.
//  This line simply append our element (checkbox) to our new wrapper
// Take Note at how I added this method at start rather than at end.
// Had I not done this, then the label would not have been wrapped!
ele.appendTo(wrapper)   //  <-- new line!
    .attr({ "id": newID  })

Затем я просто добавил следующий CSS:

#CheckBoxes .ui-button .ui-button-text {
    background: #A9A9A9;
    display: inline;
    font-size: 16px;
    left: 19px;
    padding: 0;
    position: relative;
    text-indent: 0;
    top: -4px;
}

Результаты!

person SpYk3HH    schedule 25.08.2012
comment
на самом деле это не проблема, на самом деле это заняло всего несколько минут, большая часть моего времени была потрачена на игру: P, говоря об этом, я добавил еще одну ссылку, где я показываю больше использования jQuery и играю с таймером, наслаждайтесь проверкой и удачи в будущих начинаниях! - person SpYk3HH; 25.08.2012
comment
@ApollonDigital, кстати, добро пожаловать в StackOverflow, вам здесь понравится! - person SpYk3HH; 25.08.2012
comment
@SpYk3HH - отличный фрагмент кода, единственное, чего не хватает, - это этот код в виде плагина (так было бы проще создать флажок $("input:checkbox").checkbox(); или что-то столь же простое) или даже интеграция с jqueryUI :) Спасибо, что поделились! - person Misiu; 22.04.2013
comment
Я сделал небольшое улучшение вашей первой скрипки, которое может кому-то пригодиться. Я обнаружил, что при проверке этих стилизованных флажков (которые, кстати, потрясающие) проверенное значение исходного флажка (см.: отправлено с формой) не изменилось. Вот новая скрипка с моими изменениями: jsfiddle.net/Mansfield/qFbnd/2 - person Mansfield; 24.05.2013
comment
Я исправил этот скрипт, он не работал должным образом, если флажок уже был установлен во время создания. -› jsfiddle.net/tx48S - person Jean.R; 13.11.2013
comment
Это здорово и заслуживает более 12 баллов, спасибо. - person Vael Victus; 04.06.2014
comment
Ожидаемое поведение состоит в том, чтобы иметь возможность щелкнуть по ЭТИКЕТКЕ и установить/снять флажок. Этот скрипт просто добавляет пустую метку. Конечно, вы можете добавить тест в тег ‹input›, но он не будет кликабельным. - person Elia Iliashenko; 04.05.2015
comment
@HelgaIliashenko Неправда. Он отлично работает для меня. Я даже сделал альтернативную версию, добавив текст к меткам, и как вы можете видеть здесь работает нормально. Не могли бы вы объяснить, чего вы пытаетесь достичь, и, возможно, мы сможем решить вашу проблему - person SpYk3HH; 04.05.2015
comment
Я пробовал ваш код. Вот что получилось: Снимок экрана Верно для Opera и Chrome. - person Elia Iliashenko; 04.05.2015
comment
@HelgaIliashenko Хм, да. В чем проблема? Я использую его в Chrome, и да, быстрый пример с текстом в метке должен выглядеть так. Я не вижу проблемы? - person SpYk3HH; 04.05.2015
comment
@HelgaIliashenko Я не уверен в вашем намерении, но весь смысл этого ответа заключался в том, чтобы помочь OP лучше понять jQuery и как его использовать для создания настраиваемого флажка, который можно было бы создавать динамически и по-прежнему использовать одно и то же событие, и он делает все это. Может быть, вам стоит задать вопрос? - person SpYk3HH; 04.05.2015
comment
@HelgaIliashenko И к вашему сведению, я почти исключительно использую Chrome, однако у меня есть все остальные браузеры на моем компьютере для тестирования, и все мои скрипки работают должным образом во всех из них, включая Safari и даже Opera. - person SpYk3HH; 04.05.2015
comment
@ SpYk3HH Проблема в том, что если бы я увидел это на веб-сайте как пользователь, я бы немедленно оставил его. 1. Ярлык находится не справа, а прямо над флажком. 2. Ширина элемента не увеличивается автоматически в соответствии с длиной этикетки. Таким образом, флажки далеко не удобны для пользователя. - person Elia Iliashenko; 04.05.2015
comment
@ SpY3HH 3. Метка исчезает, когда вы устанавливаете флажок. Так что надо дублировать. - person Elia Iliashenko; 04.05.2015
comment
Тогда вы совершенно неправильно понимаете вопрос и ответ. И вы все еще совершенно не правы насчет настройки. Ты не имеешь для меня никакого смысла, извини - person SpYk3HH; 04.05.2015
comment
@ SpYk3HH, не могли бы вы быть так любезны и объяснить, где именно я не прав? Эта настройка не работает, потому что кнопка без поясняющего текста не имеет смысла. - person Elia Iliashenko; 04.05.2015
comment
@HelgaIliashenko оооооо! Теперь я вижу вашу проблему! Вы потерялись в семантике. Это будет css. Я немного занят, но если вы дадите мне 24 часа, я найду время, чтобы сделать для вас скрипку, которая вам поможет. Может быть, даже добавить это к этому ответу, хотя на самом деле это не проблема. Дай мне немного времени, и я подключу тебя - person SpYk3HH; 04.05.2015
comment
@SpYk3HH на самом деле, я нашел решение, которое работает для меня: (jsfiddle.net/b4jpmkw6/4) Ваше решение может быть лучше, потому что я вижу, как метки меняют цвет при наведении в вашей настройке. - person Elia Iliashenko; 04.05.2015
comment
@HelgaIliashenko Прости, что так долго. Я был очень занят. В любом случае. То, что вы теряете, больше связано с CSS. Большая часть этого ответа была посвящена простому использованию jQuery и показывала, как сделать с его помощью графический флажок. Если вы заметили, даже в вопросе ОП он никогда не ссылается на текстовую метку, которую нужно использовать. Большинство из них использовали бы этот тип флажка в таблице, поэтому метка была бы своего рода заголовком. Но если вам нужен такой флажок с работающей меткой, у вас есть пара вариантов. Перепроверьте ответ здесь через несколько минут - person SpYk3HH; 12.05.2015
comment
Спасибо, SpYk3HH, это похоже на отличное решение! - person Elia Iliashenko; 19.05.2015