12

Is there anyway to convert the @HTML.Checkboxfor into toggle html button? I have refer the toggle button style from https://www.w3schools.com/howto/howto_css_switch.asp

Currently its working by using :

@Html.CheckBoxFor(model => model.IsEnabled, new { @checked = "checked", @Name = "DelegateChkBox" })

Changed to:

    <td class="slider-td">
         <label class="switch">
            <input name="DelegateChkBox" id="IsEnabled" type="checkbox" value="true" data-val-required="The IsEnabled field is required." data-val="true" data-bind="checked: IsEnabled">
          <div class="slider round"></div>
          </label>
   </td>

The toggle button only works and postback to controller if it's CHECKED: enter image description here

else it won't postback to controller by default UNCHECKED :

enter image description here

Any help will be appreciated! Thanks!

4
  • 1
    Possibly not related, but you have a property named IsEnabled but then you change the name attribute to DelegateChkBox which will never bind to your model (you should never change the name attribute). And you never set the checked attribute - that is done correctly by the CheckBoxFor() method based on the value of IsEnabled. Commented Mar 23, 2017 at 3:49
  • 3
    And unchecked checkboxes do not submit a value, which is why the CheckBoxFor() method generates 2 inputs - a <input type="checkbox" .. value="true" /> and a <input type="hidden" value="false" /> Commented Mar 23, 2017 at 3:51
  • 1
    And you can use @Html.CheckBox() rather than manually creating your html - you just need to modify the css selectors Commented Mar 23, 2017 at 3:57
  • Try Switchery plugin Commented Mar 23, 2017 at 4:00

2 Answers 2

18

Based from some experiments and findings, I found that you need to include hidden field generated by the helper (Html.CheckBoxFor) as shown by styling below:

<style type="text/css">
.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch input {display:none;}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  transition: .4s;
}

/* include generated hidden field here */
input[type="checkbox"]:checked + input[type="hidden"] + .slider,
input[type="checkbox"]:checked + .slider {
  background-color: #2196F3;
}

/* include generated hidden field here */
input[type="checkbox"]:focus + input[type="hidden"] + .slider,
input[type="checkbox"]:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}

/* include generated hidden field here */
input[type="checkbox"]:checked + input[type="hidden"] + .slider:before,
input[type="checkbox"]:checked + .slider:before {
  transform: translateX(26px);
}

/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}
</style>

View usage example (just change <input type="checkbox" /> to @Html.CheckBoxFor):

<label class="switch">
    @Html.CheckBoxFor(model => model.IsEnabled)
    <div class="slider round">
    </div>
</label>

To ensure the checkbox is being checked in client-side before doing postback, you can use jQuery code below:

// change event may modified to other events
$("#IsEnabled").change(function () {

    // check if checkbox is being checked
    // taken from /a/23007488 by Alexandru Chichinete
    if ($("#IsEnabled").is(":checked"))
    {
        // enable form submit
    }
});

Demo example: .NET Fiddle

References:

Styling checkboxes in MVC 4

How can I apply a CSS style to Html.CheckBoxFor in MVC 5

@Html.checkboxfor - Get checkbox value using id

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

4 Comments

All thats needed is to change the + (adjacent) selector to a ~ (siblings) selector in the 3 relevant classes (and no javascript is required)
AFAIK, adjacent selectors just a bare minimum here (of course siblings selectors also work too), and the JS part only used if OP wants to submit form based on checked value.
thanks alot @tetsuya yamamoto for this solution! you rocks!
Superb! @TetsuyaYamamoto
4

This is very simple, I have implemented in my project. You just need to keep the value of checkbox in a HiddenFor.

@Html.HiddenFor(model => model.IsEnabled, new{@id = "DelegateChkBox"})

Then display your Toggle button in the page. For example,

 <td class="slider-td">
   <label class="switch">
    <input name="DelegateChkBox" id="IsEnabled" type="checkbox" value="true" 
      data-val-required="The IsEnabled field is required." data-val="true" 
      data-bind="checked: IsEnabled">
    <div class="slider round"></div>
   </label>
 </td>

So now when user check/uncheck the checkbox, call a jquery method and assign the value to @Html.HiddenFor(..). That's it.

$('#IsEnabled').change(function(){
  if($(this).val()==true)
   {
    $('#DelegateChkBox').val(true);
   }
  else
   {
    $('#DelegateChkBox').val(false);
   }
})

Please check once this if ($("this").is(":checked")) instead if($(this).val()==true) and assign the value accordingly. Little busy, could not check my code :)

That's it. Now when you post back your page, you already set value to your IsEnabled field.

In Get method you have to do like the same. You just need to check the value of your HiddenFor() and take that value and assign to your HTML Toggle button in pageload event of js.

$(function() {
 if($('#DelegateChkBox').val()== true)
  {
   $('#IsEnabled').prop("disabled", false);
  }
 else
  {
   $('#IsEnabled').prop("disabled", true);
  }
});

That's it. Please change the HTML accordingly.

3 Comments

thanks for the reply, i do tried with included HiddenFor() but the slider won't work ( can't slide to left or right ) . That's the thing i'm struggling after added HiddenFor(). Anyway i will keep trying, thanks alot!
@Edward.K That's why I mentioned "Please change the HTML accordingly". I didn't check your HTML Toggle button. U just need to check ur Toggle button and follow my steps. This is very easy way. Let me know after it work.
Thanks guys for your contribution, problem solved by using tetsuya yamamoto solution.

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.