2

I have downloaded a theme with a preconstructed switch component that replaces the normal checkbox functionality. This switch fits in nicely with the UI and I'm desperately trying to make it work but I'm unable to get the 'checked' status of the underlying checkbox to change on a click/touch event.

This is the html structure:

<div class="switch has-switch" data-off-label="<i class='fa fa-times'></i>" data-on-label="<i class='fa fa-check'></i>">
  <div class="switch-off switch-animate">
    <input checked type="checkbox">                                                           
    <span class="switch-left"><i class="fa fa-check"></i></span>
    <label>&nbsp;</label>
    <span class="switch-right"><i class="fa fa-times"></i></span>
  </div>
</div>

The switch functionality works perfectly fine, but I'm unable to get it to toggle the 'checked' value of the checkbox input attribute.

I've tried a few solutions. The last one I've tried is this (Note this was a test to see whether I could at least get it to uncheck when clicked):

$(function () {
  $('.switch').click(function() {
    console.log(this);
    var CheckboxInput = $(this).find('input[type="checkbox"]');
    if ($(CheckboxInput).is(':checked')) {
      CheckboxInput.prop('checked', false);
    }
    }
  });
});

My javascript knowledge is not great (more of a rails guy). Could anybody please help me find what I'm doing incorrectly?

3 Answers 3

1

THE SOLN:

$(function() {
  $('.switch').click(function() {
    var checkBoxes = $(this).find('input');
    checkBoxes.prop("checked", !checkBoxes.prop("checked"));
  });
});
<script src="https://code.jquery.com/jquery.min.js"></script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">

<div class="switch has-switch" data-off-label="<i class='fa fa-times'></i>" data-on-label="<i class='fa fa-check'></i>">
  <div class="switch-off switch-animate">
    <input checked type="checkbox">
    <span class="switch-left"><i class="fa fa-check">LEFT</i></span>
    <label>&nbsp;</label>
    <span class="switch-right"><i class="fa fa-times"></i>RIGHT</span>
  </div>
</div>

A SIMPLE SOLN W/O JAVASCRIPT:

.switch {
  position: relative;
  display: block;
  vertical-align: top;
  width: 100px;
  height: 30px;
  padding: 3px;
  margin: 0 10px 10px 0;
  background: linear-gradient(to bottom, #eeeeee, #FFFFFF 25px);
  background-image: -webkit-linear-gradient(top, #eeeeee, #FFFFFF 25px);
  border-radius: 18px;
  box-shadow: inset 0 -1px white, inset 0 1px 1px rgba(0, 0, 0, 0.05);
  cursor: pointer;
}
.switch-input {
  position: absolute;
  top: 0;
  left: 200px;
  opacity: 50;
}
.switch-label {
  position: relative;
  display: block;
  height: inherit;
  font-size: 10px;
  text-transform: uppercase;
  background: #eceeef;
  border-radius: inherit;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.15);
}
.switch-label:before,
.switch-label:after {
  position: absolute;
  top: 50%;
  margin-top: -.5em;
  line-height: 1;
  -webkit-transition: inherit;
  -moz-transition: inherit;
  -o-transition: inherit;
  transition: inherit;
}
.switch-label:before {
  content: attr(data-off);
  right: 11px;
  color: #aaaaaa;
  text-shadow: 0 1px rgba(255, 255, 255, 0.5);
}
.switch-label:after {
  content: attr(data-on);
  left: 11px;
  color: #FFFFFF;
  text-shadow: 0 1px rgba(0, 0, 0, 0.2);
  opacity: 0;
}
.switch-input:checked ~ .switch-label {
  background: #E1B42B;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15), inset 0 0 3px rgba(0, 0, 0, 0.2);
}
.switch-input:checked ~ .switch-label:before {
  opacity: 0;
}
.switch-input:checked ~ .switch-label:after {
  opacity: 1;
}
.switch-handle {
  position: absolute;
  top: 4px;
  left: 4px;
  width: 28px;
  height: 28px;
  background: linear-gradient(to bottom, #FFFFFF 40%, #f0f0f0);
  background-image: -webkit-linear-gradient(top, #FFFFFF 40%, #f0f0f0);
  border-radius: 100%;
  box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
}
.switch-handle:before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -6px 0 0 -6px;
  width: 12px;
  height: 12px;
  background: linear-gradient(to bottom, #eeeeee, #FFFFFF);
  background-image: -webkit-linear-gradient(top, #eeeeee, #FFFFFF);
  border-radius: 6px;
  box-shadow: inset 0 1px rgba(0, 0, 0, 0.02);
}
.switch-input:checked ~ .switch-handle {
  left: 74px;
  box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.2);
}
.switch-label,
.switch-handle {
  transition: All 0.3s ease;
  -webkit-transition: All 0.3s ease;
  -moz-transition: All 0.3s ease;
  -o-transition: All 0.3s ease;
}
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<label class="switch">
  <input class="switch-input" type="checkbox" />
  <span class="switch-label" data-on="ONL" data-off="Off"></span> 
  <span class="switch-handle"></span> 
</label>

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

6 Comments

Thanks for this @iceman. This uses the 'name' attribute of an entity though? I am looking for something that adds this functionality on a component level. That way it will work whenever I use this css/html component. Is there a way that your solution would work with an input type rather? More specifically a checkbox input in the HTML structure given in the question.
sure what exactly is the attribute or condition you want to bind to? i'll edit accordingly.
@Herm cud u create a fiddle or snippet working example so, i can integrate the soln into it, will be easier for both of us.
I want it to have the toggling functionality with any checkbox input placed inside of the html structure indicated in my original question. Thus using the .switch class and looking for a child element with type 'checkbox' and toggling said element's checked status.
no it didn't. Wow I'm amazed by your helpfulness. If you right click on the snippet and inspect the element you'll see that it does not toggle the input's attribute value. I really appreciate your thorough help!!!!!
|
1

Replace this line

if ($(CheckboxInput).is(':checked')) {
  CheckboxInput.prop('checked', false);
}

to

CheckboxInput.prop('checked', !$(CheckboxInput).is(':checked'));

Working Fiddle: https://jsfiddle.net/codeandcloud/xnq16htu/

Update: Same has been filed as a bug and the team has deemed it invalid bug report with the note,

That is correct behavior. The user's click does not remove the attribute from the HTML. It only changes the property. If you want to know the dynamic state, use .prop("checked") instead.

Link: https://bugs.jquery.com/ticket/10730

Test: Using Vanilla JavaScript

var container = document.getElementById("container"),
    elm = document.getElementById("test-check");
elm.addEventListener("click", function() {
    console.log("CheckBox Markup: ", container.innerHTML);
    console.log("CheckBox Status: ", elm.checked);
});
<div id="container">
    <input id="test-check" type="checkbox" checked />
</div>

2 Comments

Thanks for the speedy reply @naveen. It still does not toggle the input's checked status
this does not seem to toggle the 'checked' attribute in the html. If you use firebug or chrome dev console on your fiddle you'd be able to see what I mean. It does check and uncheck the input on the ui,, but the attribute in the code is not added/removed
0

you just need to replace property 'true' by 'checked' i.e CheckboxInput.prop('checked','checked');

        <div class="switch has-switch" data-off-label="<i class='fa fa-times'></i>" data-on-label="<i class='fa fa-check'></i>">
  <div class="switch-off switch-animate">
    <input type="checkbox" checked>                                                           
    <span class="switch-left"><i class="fa fa-check"></i></span>
    <label>&nbsp;</label>
    <span class="switch-right"><i class="fa fa-times"></i></span>
  </div>
</div>



$(function () {
  $('.switch').click(function() {
    console.log(this);
    var CheckboxInput = $(this).find('input[type="checkbox"]');
    if ($(CheckboxInput).is(':checked')) {
      CheckboxInput.prop('checked','checked');
    }
  });
});

3 Comments

Thanks for the answer @DPT. But this does not solve the toggling of attributes using JS. It will set the html value to true initially though.
hey @Herm ,can you just check it again. i have edited it and its working fine.
@DPT...thanks for the update. I have updated the negative vote. Still not working though

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.