custom checkbox with hidden input - javascript

I am making a custom checkbox so I can have both my own UI design, and still have the input[type="checkbox"] in the page for purpose of toggling css classes with it and being able to submit a form and it being taken into the form.
I am aware that if the input has display: none; it will not be passed into the form, so I will hide it since I actually don't use it visualy.
Question: what should I take into account when hidding it?
I'm thinking about giving it position: absolute; and then a negative margin so it will not show up. With the label tag I can still trigger it. But should I use opacity or visibility instead?

As you can see, using opacity:0;, users will still be able to click it. click near the actual label on the snippet below:
.chk { opacity:0; }
.chk + label {
background-color:red;
height: 22px;
width: 22px;
display:inline-block;
padding: 0 0 0 0px;
cursor:pointer;
}
.chk:checked + label { background-color:blue; }
<input type='checkbox' id='mychk' class='chk' /><label for='mychk' ></label>
Now, using a negative margin will make the label disappear too:
.chk { margin:-100px; }
.chk + label {
background-color:red;
height: 22px;
width: 22px;
display:inline-block;
padding: 0 0 0 0px;
cursor:pointer;
}
.chk:checked + label { background-color:blue; }
<input type='checkbox' id='mychk' class='chk' /><label for='mychk' ></label>
Finally: visibility:hidden does the trick:
.chk { visibility:hidden; }
.chk + label {
background-color:red;
height: 22px;
width: 22px;
display:inline-block;
padding: 0 0 0 0px;
cursor:pointer;
}
.chk:checked + label { background-color:blue; }
<input type='checkbox' id='mychk' class='chk' /><label for='mychk' ></label>
Conclusion:
use visibility:hidden to hide the <input>. This will make it invisible still with inline display in your page, without effecting the label using it.

Use this code
input[type="checkbox"] {
height: 16px;
opacity: 0;
position: absolute;
width: 16px;
}
input[type="checkbox"] + label::before {
border: 1px solid #ccc;
border-radius: 4px;
content: "";
height: 16px;
left: 8px;
position: absolute;
top: 10px;
width: 16px;
}
input[type="checkbox"]:checked + label:before {
border: 1px solid #434452;
background:#434452;
}
label {
color: #434452;
font-size: 18px;
font-weight: normal;
line-height: 100%;
padding-left: 22px;
cursor:pointer
}
<input type='checkbox' id='chk' class='chk' /><label for='chk' >check</label>

Related

Copy text to clipboard with JS

I am a JS beginner and I have the following problem: I want that as soon as someone clicks on the URL icon inside the accordion the respective link is copied to the clipboard. Unfortunately (always) only the first link is copied to the clipboard, even if one clicks on the other two URL icons only the first link is copied. Although in the clipboard should be link 2 (from the value field) when i click on URL icon 2 (and the same for number 3 of course). I hope I have described the problem clearly enough.
Where is the error and what do I need to change on the JS code to make it work? Thanks a lot for the help in advance!
```
<!DOCTYPE html>
<html>
<head>
<title>My example Website</title>
<style>
body {
font-size: 21px;
font-family: Tahoma, Geneva, sans-serif;
max-width: 550px;
margin: 0 auto;
background-color: black;
}
input {
display: none;
}
label {
display: block;
padding: 8px 22px;
margin: 0 0 1px 0;
cursor: pointer;
background: #181818;
border: 1px solid white;
border-radius: 5px;
color: #FFF;
position: relative;
}
label:hover {
background: white;
border: 1px solid white;
color:black;
}
label::after {
content: '+';
font-size: 22px;
font-weight: bold;
position: absolute;
right: 10px;
top: 2px;
}
input:checked + label::after {
content: '-';
right: 14px;
top: 3px;
}
.content {
background: #DBEECD;
background: -webkit-linear-gradient(bottom right, #DBEECD, #EBD1CD);
background: -moz-linear-gradient(bottom right, #DBEECD, #EBD1CD);
background: linear-gradient(to top left, #DBEECD, #EBD1CD);
padding: 10px 25px 10px 25px;
border: 1px solid #A7A7A7;
margin: 0 0 1px 0;
border-radius: 1px;
}
input + label + .content {
display: none;
}
input:checked + label + .content {
display: block;
}
.whitepaper {
cursor: pointer;
text-align: center;
background-color: white;
border: 2px solid black;
border-radius: 3px;
float: left;
margin: 5px 5px 5px 0;
height: 40px;
width: 30px;
}
.blackframe {
text-align: center;
background-color: black;
cursor: pointer;
font-family: Tahoma, Geneva, sans-serif;
font-size:12px;
font-weight:bold;
margin: 12px 0 12px 0;
color: white;
width: 30px;
}
.whitepaper:hover {
cursor: pointer;
text-align: center;
background-color: black;
border: 2px solid white;
border-radius: 3px;
float: left;
margin: 5px 5px 5px 0;
height: 40px;
width: 30px;
}
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: #555;
color: #fff;
text-align: center;
padding: 5px 0;
border-radius: 6px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
/* Fade in tooltip */
opacity: 0;
transition: opacity 0.3s;
}
/* Tooltip arrow */
.tooltip .tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
</style>
</head>
<body>
<input type="checkbox" id="title1" name="contentbox" />
<label for="title1">Content 1</label>
<div class="content">
<div class="tooltip"><div class="whitepaper" onclick="myFunction()"><div class="blackframe"><span class="tooltiptext">Copy link 1 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title1" id="myInput"></div>
</div>
<input type="checkbox" id="title2" name="contentbox" />
<label for="title2">Content 2</label>
<div class="content">
<div class="tooltip"><div class="whitepaper" onclick="myFunction()"><div class="blackframe"><span class="tooltiptext">Copy link 2 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title2" id="myInput"></div>
</div>
<input type="checkbox" id="title3" name="contentbox" />
<label for="title3">Content 3</label>
<div class="content">
<div class="tooltip"><div class="whitepaper" onclick="myFunction()"><div class="blackframe"><span class="tooltiptext">Copy link 3 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title3" id="myInput"></div>
</div>
<script>
function myFunction() {
/* Get the text field */
var copyText = document.getElementById("myInput");
/* Select the text field */
copyText.select();
copyText.setSelectionRange(0, 99999); /* For mobile devices */
/* Copy the text inside the text field */
navigator.clipboard.writeText(copyText.value);
/* Alert the copied text */
alert("Copied: " + copyText.value);
}
</script>
</body>
</html>
```
Replace function myFunction like this:
function myFunction(event) {
var target = event.target;
var copyText = target.nextElementSibling;
navigator.clipboard.writeText(copyText.value);
alert("Copied: " + copyText.value);
}
then update all onclick attributes like this
onclick="myFunction(event)"
I found a few issues with your code
You didn't change the id number on the inputs so they all would alert to the same URL which made it difficult to tell which is being clicked on.
You are doing a query selection on an id that appears multiple times. This means it is not being fired on the clicked element.
My approach includes taking advantage of the clicked element by passing it in your click handler.
<div class="tooltip">
<div class="whitepaper" onclick="myFunction(event)">
<div class="blackframe"><span class="tooltiptext">Copy link 3 to clipboard</span>URL</div>
</div><input type="text" value="https://mywebsite.com/#title3" id="myInput">
</div>
This lets me pass that event to the function call which will give us access to the current target node.
function myFunction(event) {
/* Get the text field */
var copyText = event.target.parentNode.nextSibling.nextSibling.value
/* Copy the text inside the text field */
navigator.clipboard.writeText(copyText);
/* Alert the copied text */
alert("Copied: " + copyText);
}
In the above case, I had to do some weird traversing because your input is outside the scope of the clicked element. I removed the code related to mobile stuff because that wasn't relevant to this issue (feel free to put that back in).
here's the codepen with my example.

Radio button with custom image

I've used this example for checkboxes but then later I realized I need one for the radio buttons.
Can someone please customize this example for radio buttons?
Change checkbox check image to custom image
html
<input type="radio" class="input_class_checkbox" name="role"> Coach
<input type="radio" class="input_class_checkbox" name="role"> Athlete
jquery
$('.input_class_checkbox').each(function(){
$(this).hide().after('<div class="class_checkbox" />');
});
$('.class_checkbox').on('click',function(){
$(this).toggleClass('checked').prev().prop('checked',$(this).is('.checked'))
});
Fiddle:
http://jsfiddle.net/cn6kn/
or is there a one stop solution to use custom images both for radio button and checkboxes. I searched a few but all of them are offering their own skins.
From the example I customized to included background-images as follows but it's not working for the radio buttons, all radio buttons remain checked irrespective I click the other one.
.class_checkbox {
width: 36px;
height: 36px;
background: url("../images/checkbox.png");
}
.class_checkbox.checked {
background: url("../images/checkbox-checked.png");
}
Use Pseudo-elements in this case i am using ::before (:before)
Update: since firefox doesn't support pseudo-elements on inputs yet, use the adjacent sibling selectors
:root{padding: 40px}
[name=radio]{
display: none
}
[for^=radio]{
position: relative;
margin: 64px
}
[for^=radio]:before{
content: '';
position: absolute;
left: -15px;
top: -15px;
width: 32px;
height: 32px;
background: red
}
[type=radio]:checked + [for^=radio]:before{
background: green
}
<input id=radio-1 type=radio name=radio />
<label for=radio-1></label>
<input id=radio-2 type=radio name=radio />
<label for=radio-2></label>
<input id=radio-3 type=radio name=radio />
<label for=radio-3></label>
Or the General sibling selectors
:root{padding: 40px}
[name=radio]{
display: none
}
[for^=radio]{
position: relative;
margin: 64px
}
[for^=radio]:before{
content: '';
position: absolute;
left: -15px;
top: -15px;
width: 32px;
height: 32px;
background: red
}
[id=radio-1]:checked ~ [for=radio-1]:before,
[id=radio-2]:checked ~ [for=radio-2]:before,
[id=radio-3]:checked ~ [for=radio-3]:before{
background: green
}
<input id=radio-1 type=radio name=radio />
<input id=radio-2 type=radio name=radio />
<input id=radio-3 type=radio name=radio />
<label for=radio-1></label>
<label for=radio-2></label>
<label for=radio-3></label>
The basic
[type=radio]{
position: relative;
margin: 40px
}
[type=radio]:before{
content: '';
position: absolute;
left: -15px;
top: -15px;
width: 32px;
height: 32px;
background: red
}
[type=radio]:checked:before{
background: green
}
<input type=radio />
multiple inputs
[type=radio]{
position: relative;
margin: 40px
}
[type=radio]:before{
content: '';
position: absolute;
left: -15px;
top: -15px;
width: 32px;
height: 32px;
background: red
}
[type=radio]:checked:before{
background: green
}
<input type=radio name=radio />
<input type=radio name=radio />
<input type=radio name=radio />
oh sorry, i misunderstood the first time, how about something like this? http://jsfiddle.net/swm53ran/126/
pretty much whats happening is that the old radio button css is getting hid, and then your css will take over, but still maintains the functionality of a radio button.
label {
display: inline-block;
cursor: pointer;
position: relative;
padding-left: 25px;
margin-right: 15px;
font-size: 13px;
}
input[type=radio] {
display: none;
}
label:before {
content: "";
display: inline-block;
width: 16px;
height: 16px;
margin-right: 10px;
position: absolute;
left: 0;
bottombottom: 1px;
background-color: #aaa;
box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
}
.radio label:before {
border-radius: 8px;
}
input[type=radio]:checked + label:before {
content: "\2022";
color: red;
font-size: 30px;
text-align: center;
line-height: 18px;
}

dialog body center pains

I have a dialog box im going to turn into a manual entry dialog for a select box. I am having issues getting the text/input box to align vertically in the center. here is the URL if you want to view. Just select anything in the select box and you will see, I have made it taller for testing only. Below is my dialog code. http://moconsultant.net and below that is my css the CSS is also used for a dialog alert system I built MO
$('.selectBox').change(function(){
myDialogBox=" <div title='Im a Manual Entry Box' class='dialogDiv'> Manual Entry:<input type='text' name='dialogName' id='dialogName' maxlength='40' class='dialogInput' ></div>"
$(myDialogBox).dialog({
autoOpen: true,
width: 'auto',
height: '500',
modal: true,
fluid: true, //new option
buttons:[
{
text: 'Retun',
'class': 'return',
click: function() {
$(this).dialog( 'close' );
myField.focus();myField.select();
}
}
],
close: function() {
}
});
});
}
/*mo alert*/
.ui-dialog .ui-dialog-titlebar
{
background-color: #0D3257;
color: #ffffff;
text-align: center;
}
.ui-dialog
{
border: 3px solid #0D3257;
}
.ui-dialog .ui-dialog-title
{
margin: .1em 16px .1em 0;
text-align: center;
float:none !important;
}
.ui-dialog .ui-dialog-content {
border: none;
background-color: #B0C4DE;
color: #00549E;
padding: 0;
vertical-align:text-middle;
}
.ui-button.continue{
color:green;
font-family: Arial;
font-size: 12px;
font-weight: bold;
background-color:#F1F3F7;
height:28px;
Width:150px;
padding-bottom: 5px;
border-style:outset;
border-color:#9BB7D9;
filter:progid:DXImageTransform.Microsoft.Gradient
(GradientType=0,StartColorStr='#F1F3F7',EndColorStr='#E2EEFD');
}
.ui-button.continue:hover {
color:blue;
}
.ui-dialog .ui-dialog-buttonpane {
text-align: center;
}
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
float: none;
}
.ui-button.return{
color:green;
font-family: Arial;
font-size: 12px;
font-weight: bold;
background:#B0C4DE;
text-align:center;
height:28px;
width:150px;
outline: none;
border:0px;
filter:progid:DXImageTransform.Microsoft.Gradient
(GradientType=0,StartColorStr='#F1F3F7',EndColorStr='#E2EEFD');
}
.ui-button.return:hover {
color:blue;
}
.ui-widget-header {
background:#0D3257;
border:0px;
}
.dialogDiv{
text-align:center;
padding-top: 22px; /* you can use a padding to vertically center*/
}
.dialogInput{
height: 15px;
}
Here you have a demo on jsfiddle.net.
Set a CSS pseudo element to your wrapping div container, the div with the id="ui-id-7", for example. The CSS pseudo element gets a display: inline-block;, a height: 100%; and a vertical-align: middle;. DonĀ“t forget the content: '';. Now wrap your content to be aligned in another div container and set this one to display: inline-block; and vertical-align: middle;.
By the way, I would recommend to use a label element for the input label. So users are able to click on the label to set the focus to the input field. Works for all kind of input types.
HTML code:
<div class="dialogDiv ui-dialog-content ui-widget-content vertical-align-outer" id="ui-id-7" style="display: block; width: auto; min-height: 0px; max-height: none; height: 386px;">
<div class="vertical-align-inner">
<label for="dialogName">Manual Entry:</label>
<input type="text" name="dialogName" id="dialogName" maxlength="40" class="dialogInput"/>
</div>
</div>
CSS code:
.vertical-align-outer:before {
content: ' ';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.vertical-align-inner {
display: inline-block;
vertical-align: middle;
}

Have I hit a limit here by using hashtags?

I'm trying to avoid the use of javascript for things that can be achieved with CSS only (I don't want to go into why too much here, just want to focus on the problem I'm having). As a result, I've developed a modal feature to my site that opens using hashtags and targets (similar to this: http://codepen.io/maccadb7/pen/nbHEg).
That's fine; works how I'd want it to. The problem now is that I want to put a CSS-only tab control inside the modal div. The only methods I've seen this involve the use of hashtags and targets (just as my modal did, and already has). I can't have multiple hashtags in the URL - so am I left with no choice but to use javascript now?
Another way to do this, relatively positioned box holding absolutely positioned tabs and inline radio inputs and + in the selector to choose the visible one
<div class="tabbox">
<label for="tab1">A</label>
<input id="tab1" type="radio" name="tab" class="tabchoice" />
<div class="tabcontent">hello</div>
<label for="tab2">B</label>
<input id="tab2" type="radio" name="tab" class="tabchoice" />
<div class="tabcontent">world</div>
</div>
.tabbox {
position: relative;
}
.tabcontent {
position: absolute;
top: 20px;
left: 0;
display: none;
}
.tabchoice:checked + .tabcontent {
display:block;
}
DEMO
You might need to do a bit more work for overflows etc, in production code
You can use radio buttons and a lot of css to create a non javascript tab control
<div id="content">
<label class="what-tab" for="what-tab">What is </label>
<label class="example-tab" for="example-tab">Examples</label>
<input type="radio" name="tab" id="example-tab"/>
<input type="radio" name="tab" id="what-tab" checked=""/>
<div id="group">
<div id="what">What</div>
<div id="example">Example</div>
</div>
</div>
#content label{
width: 150px;
height: 25px;
display: block;
float: left;
text-align: center;
line-height: 25px;
}
#content label:hover{
color: white;
}
[name=tab]{
position: absolute;
visibility: hidden;
}
.what-tab{
background-color: green;
}
.example-tab
{
background-color: blue;
}
#group{
clear: left;
position: relative;
height: 525px;
}
#group > div{
position: absolute;
height: 500px;
width: 100%;
opacity: 0;
padding: 10px;
overflow: auto;
z-index: 1;
}
#what{
border: solid 1px blue;
}
#example{
border: solid 1px green;
}
#example > label{
background-color: green;
}
#example > div{
font-size: 18px;
padding: 5px;
display:none;
clear:both;
}
#example-tab:checked ~ #group #example{
opacity: 1;
z-index: 2;
}
#what-tab:checked ~ #group #what{
opacity: 1;
z-index: 2;
}
input[name="eg-tab"]{
display:none;
}
input + div{
clear:both;
}
http://jsfiddle.net/FPD58/2/

Custom checkbox with hidden inputs not selecting properly. Javascript needs adjusting

I am using custom checkboxes with the input hidden wrapped in a span; I have written a script to add the class for checked, but it doesn't actually mark the inputs as checked. What am I doing wrong here?
UPDATE: So the checkbox checks now! Hooray. A new problem is that hiding the visibility on the checkbox, also hides the new class when checked on the area of the checkbox... if the label is clicked, then the checkbox shows as checked, but if the checkbox image itself is clicked, nothing changes...
HTML
<fieldset>
<label class="sublabel" title="Insights & Planning" for="checkbox-insights-and-planning">Insights & Planning</label>
<span class="open-checkbox">
<input id="checkbox-insights-and-planning" class="key-areas-checkbox" name="key-areas-of-interest" type="checkbox" />
</span>
</fieldset>
CSS
.open-checkbox {
background-position: -4px -48px;
background-image: url(../images/adcolor-sprite.png);
background-repeat: no-repeat;
cursor: pointer;
display: block;
float: right;
height: 25px;
margin-top: 10px;
width: 25px;
}
.checked {
background-position: -4px -12px;
background-image: url(../images/adcolor-sprite.png);
background-repeat: no-repeat;
cursor: pointer;
display: block;
float: right;
height: 25px;
margin-top: 10px;
width: 25px;
}
input[type=checkbox] {
visibility: hidden;
}
#key-areas-inputs label.sublabel {
display: block;
float: left;
height: 44px;
padding: 0 0 0 10px;
width: 300px;
}
#key-areas-inputs input.key-areas-checkbox {
float: right;
display: block;
clear: none;
height: 22px;
width: 22px;
margin-top: 18px;
margin-right: 4px;
margin-bottom: 0px;
margin-left: 0px;
}
#key-areas-label {
font-family: "Futura W01 Bold", Arial, Helvetica, sans-serif;
font-size: 16px;
color: #df007c;
display: block;
clear: left;
float: left;
width: 348px;
margin-top: 50px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
padding-top: 0px;
padding-right: 30px;
padding-bottom: 0px;
padding-left: 0px;
text-align: right;
}
JS
// check checked boxes on load
$(".key-areas-checkbox:checked").each(function(){
$(this).next().addClass('checked');
});
// add class and checked attribute to filter inputs
$('.open-checkbox').click(function () {
console.log('click');
var $this = $(this);
var $input = $this.find('input');
$this.toggleClass('checked', $input.is(':checked'));
return;
if($input.prop('checked')){
$this.removeClass('checked');
} else {
$this.addClass('checked');
}
});
to check the checkbox add:
$input.attr('checked','checked');
to uncheck:
$input.removeAttr('checked');
Your for and ids don't match. Change your id to "checkbox-insights-and-planning" (was missing an 's') and it should work.
Also make sure your image path is correct (we can't test that with your example code as it's a relative path; I just tried it with a background-color and it worked).
I figured out what the issue was. The JS was fine. The fix was to nest the inputs inside of the label and wrap inside of a div. This gave the desired effect.

Categories

Resources