1

Problem:

I have a set of custom checkboxes, presented as sliding on/off-buttons. These buttons toggle visibility of other elements. Up until now, I've used regular checkboxes, with an onclick-function, which performs a check on all settings, and updates the visibility of the elements. It worked perfectly, but after making the sliding buttons, and moving the onclick function to the corresponding checkbox labels, my visibility updates is one click delayed. The visibility update is performed before the checkbox is actually checked.

Question: how can I change the order sequence of execution, so that my visibility update executes after the checkbox is toggled?

Additional Info: Early on in my development I used a checkbox onchange-listener, but it didn't work out. In my full scale system, I also have buttons implemented, for checking and unchecking all of the checkboxes at once, and an onchange-listener would iterate through my visibility update 18 times. Once for each checkbox. It took too much time. Also, I want to avoid getting rid of the animation of the buttons, in addition to avoid using waits.

I've reproduced the error in this jsfiddle: http://jsfiddle.net/9n81ff1b/24/

I apologize for the double up javascript functions. I had trouble getting my js to work in jsfiddle, and this was the quick and dirty solution. I do not have double up functions in my actual project:

HTML:

<div class="onoffswitch"> 
<input type="checkbox" name="categorycheckbox" value="A" class="onoffswitch-checkbox" id="c1"> 
    <label class="onoffswitch-label" for="c1" onclick="updateSection()"> 
        <div class="onoffswitch-inner"> 
            <div class="onoffswitch-active"><div class="onoffswitch-switch"></div></div> 
            <div class="onoffswitch-inactive"><div class="onoffswitch-switch"></div></div> 
        </div>                                           
    </label>    
    </div>
    <div class="onoffswitch"> 
<input type="checkbox" name="categorycheckbox"  value="B" class="onoffswitch-checkbox" id="c2"> 
    <label class="onoffswitch-label" for="c2" onclick="updateSection()"> 
        <div class="onoffswitch-inner"> 
            <div class="onoffswitch-active"><div class="onoffswitch-switch"></div></div> 
            <div class="onoffswitch-inactive"><div class="onoffswitch-switch"></div></div> 
        </div>                                           
    </label>
        </div>

<div class="onoffswitch"> 
<input type="checkbox" name="categorycheckbox" value="C" class="onoffswitch-checkbox" id="c3"> 
    <label class="onoffswitch-label" for="c3" onclick="updateSection()"> 
        <div class="onoffswitch-inner"> 
            <div class="onoffswitch-active"><div class="onoffswitch-switch"></div></div> 
            <div class="onoffswitch-inactive"><div class="onoffswitch-switch"></div></div> 
        </div>                                           
    </label>    
    </div>

    <div class="colorbox A"> 1</div> 
    <div class="colorbox B"> 2</div> 
    <div class="colorbox C"> 3</div>

JS: (without double up functions)

$(document).ready(function(){
    updateSection();
});

function updateSection(){
    console.log("updatingSection");
    categories = [];
    $('input[name=categorycheckbox]').each(function() {
        if (this.checked) {
            categories.push(this.value);
        }
    });


    $('.colorbox').each(function(index, element) {
        var visible = true;
        var currentElement = element;
        if (!hasClassOfArray(currentElement, categories)){
            visible = false;
            };  

        $(currentElement).toggle(visible);
    });
}


function hasClassOfArray(element, classes) {
        for (var i = 0, j = classes.length; i < j; i++) {
            if (hasClass(element, classes[i])) {
                return true;
            }
        }
        return false;
    }
function hasClass(element, cls) {
        return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
    }

CSS:

.onoffswitch {
    position: relative; width: 90px;
    -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
    display: none;
}
.onoffswitch-label {
    display: block; overflow: hidden; cursor: pointer;
    border: 2px solid #999999; border-radius: 20px;
}
.onoffswitch-inner {
    display: block; width: 200%; margin-left: -100%;
    -moz-transition: margin 0.3s ease-in 0s; -webkit-transition: margin 0.3s ease-in 0s;
    -o-transition: margin 0.3s ease-in 0s; transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
    display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
    font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
    -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
.onoffswitch-inner:before {
    content: "ON";
    padding-left: 10px;
    background-color: #34C134; color: #FFFFFF;
}
.onoffswitch-inner:after {
    content: "OFF";
    padding-right: 10px;
    background-color: #E3E3E3; color: #999999;
    text-align: right;
}
.onoffswitch-switch {
    display: block; width: 18px; margin: 6px;
    background: #FFFFFF;
    border: 2px solid #999999; border-radius: 20px;
    position: absolute; top: 0; bottom: 0; right: 56px;
    -moz-transition: all 0.3s ease-in 0s; -webkit-transition: all 0.3s ease-in 0s;
    -o-transition: all 0.3s ease-in 0s; transition: all 0.3s ease-in 0s; 
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
    margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
    right: 0px; 
}

.colorbox{
    height: 64px;
    width: 64px;
}

.A{
    background: yellow;
}

.B{
    background: green;
}

.C{
    background: red;
}
3
  • Before the checkbox is triggered rest of the code is executed and hence for the first time it gets no values pushed in categories. You can use setTimeout for this.Something like this Commented Mar 16, 2015 at 14:16
  • I can see that it is working now, but what did you actually change? I can't seem to find it. Commented Mar 16, 2015 at 14:49
  • See line 10, I have added a setTimeout Commented Mar 16, 2015 at 14:59

2 Answers 2

1

Merely transferring the onclick attribute to the checkboxes themselves, instead of their labels, solved the problem.

Sign up to request clarification or add additional context in comments.

1 Comment

I have the same ussue, but the thing is I have hide the <input> element and customized the <lable>, is there any way to do the same thing without input element.
0

instead of using label's onclick event, use input element's onchange event

<input type="checkbox" name="categorycheckbox" value="A" class="onoffswitch-checkbox" id="c1" onchange="updateSection()">

http://jsfiddle.net/9n81ff1b/27/

because once you click on the label, your script runs before the input has actually changed. using input elements onchange event can fix that problem

1 Comment

My question clearly states that the onchange isn't an option for my setup.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.