presence of className preventing onClick handler being called - javascript

I have a simple React component:
class FilterCheckBox extends React.Component {
clickCheckBox(e) {
console.log('clicked on checkbox');
}
render(){
return (
<div>
<a className="filter-checkbox" onClick={this.clickCheckBox.bind(this)}>
<span>{this.props.area.key}</span>
<span>{this.props.area.doc_count}</span>
</a>
</div>
)
}
}
With the className specified as above, the onClick handler is never called. However if I remove the className declaration, the onClick works fine.
The styles added by the class are:
.filter-checkbox,
.filter-checkbox:link,
.filter-checkbox:visited,
.filter-checkbox:focus {
-moz-transition: color 0.5s ease;
-o-transition: color 0.5s ease;
-webkit-transition: color 0.5s ease;
transition: color 0.5s ease;
color: #546e7a;
text-transform: uppercase;
text-decoration: none;
font: normal normal 700 0.875em/1.2em "Oxygen", sans-serif;
/*14px*/
outline: none;
position: relative;
display: block;
margin-bottom: 10px;
}
/* line 330, ../scss/partials/_reusables.scss */
.filter-checkbox:before,
.filter-checkbox:link:before,
.filter-checkbox:visited:before,
.filter-checkbox:focus:before {
-moz-transition: all 0.8s ease;
-o-transition: all 0.8s ease;
-webkit-transition: all 0.8s ease;
transition: all 0.8s ease;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
content: '';
background: #ffffff;
border: 1px solid #cfd8dc;
color: #007cba;
clear: none;
cursor: pointer;
display: inline-block;
height: 15px;
line-height: 0;
width: 15px;
outline: none;
vertical-align: middle;
margin: -3px 10px 0 0;
}
/* line 347, ../scss/partials/_reusables.scss */
.filter-checkbox:after,
.filter-checkbox:link:after,
.filter-checkbox:visited:after,
.filter-checkbox:focus:after {
display: none;
content: '\f00c';
color: #ffffff;
font: normal normal 400 11px/11px FontAwesome;
position: absolute;
top: 2px;
left: 2px;
}
/* line 356, ../scss/partials/_reusables.scss */
.filter-checkbox:hover,
.filter-checkbox:link:hover,
.filter-checkbox:visited:hover,
.filter-checkbox:focus:hover {
color: #50d583;
text-decoration: none;
}
/* line 361, ../scss/partials/_reusables.scss */
.filter-checkbox.active:before,
.filter-checkbox:link.active:before,
.filter-checkbox:visited.active:before,
.filter-checkbox:focus.active:before {
border: 1px solid #50d583;
background: #50d583;
}
/* line 365, ../scss/partials/_reusables.scss */
.filter-checkbox.active:after,
.filter-checkbox:link.active:after,
.filter-checkbox:visited.active:after,
.filter-checkbox:focus.active:after {
display: block;
}
I can't see anything here that would stop the event from being propagated so there must be something I just don't understand properly..?

It turned out that this was caused by another script that was capturing the click event using jquery to target that specific class name.
Found through a process of elimination - first eliminating all scripts and restoring until the problem came back. Then inspecting the problem script until I found the offending line.
Thanks for your responses.

Related

How to switch pictures by pressing the button?

I am learning how to create websites. I want to build a simple theme switcher with HTML/CSS/JavaScript. I've done the theme switching part, but I want to change the picture in the button when I press it.
Here is my moon picture: (https://www.svgrepo.com/svg/6390/moon) and here is my sun picture: (https://www.svgrepo.com/svg/304624/sun-light-theme).
Here is my code:
const btn = document.querySelector('.btn_theme');
btn.addEventListener('click', function() {
document.body.classList.toggle('dark_theme');
});
body {
background-color: white;
color: black;
font-family: "Trebuchet MS", Helvetica, sans-serif;
font-size: 16pt;
font-weight: normal;
}
body.dark_theme {
background-color: #2F3136;
color: white;
font-size: 16pt;
font-weight: normal;
font-family: "Trebuchet MS", Helvetica, sans-serif;
}
.container {
width: 100px;
height: 55px;
background-color: #2F3136;
color: white;
text-align: center;
border-radius: 10px;
position: absolute;
display: flex;
align-items: center;
}
.btn_theme {
text-align: center;
width: 90px;
height: 45px;
background-color: white;
margin: 0;
padding: 0;
border: 0;
left: 5px;
border-radius: 8px;
position: relative;
transition: all .15s linear;
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
align-items: center;
}
button:hover {
background-color: #2f3647;
transition: all 0.15s linear;
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
}
<p>text</p>
<div class="container">
<button class="btn_theme" id="btn_theme"><img src="../imgs/солнце.svg" /></button>
</div>
There are a couple ways to accomplish this.
One way is to just get rid of the img tag and change the button's background image.
const btn = document.querySelector('.btn_theme');
btn.addEventListener('click', function() {
document.body.classList.toggle('dark_theme');
});
.btn_theme {
background: url('https://www.svgrepo.com/show/304624/sun-light-theme.svg');
text-align: center;
width: 40px;
height: 40px;
background-color: white;
margin: 0;
padding: 0;
border: 0;
left: 5px;
border-radius: 8px;
position: relative;
transition: all .15s linear;
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
align-items: center;
}
button:hover {
background-color: #2f3647;
transition: all 0.15s linear;
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
}
.dark_theme {
background: #ffaaff
}
.dark_theme .btn_theme {
background: url('https://www.svgrepo.com/show/6390/moon.svg');
}
<button class="btn_theme" id="btn_theme"></button>
Another solution is to use a data-attribute to store the current state and change the img tag's src value.
const btn = document.querySelector('.btn_theme');
const icon = btn.querySelector('img');
btn.addEventListener('click', function() {
document.body.classList.toggle('dark_theme');
if (icon.dataset.theme == "light") {
icon.dataset.theme = "dark";
icon.src = "https://www.svgrepo.com/show/6390/moon.svg";
} else {
icon.dataset.theme = "light";
icon.src = "https://www.svgrepo.com/show/304624/sun-light-theme.svg";
}
});
.btn_theme {
text-align: center;
width: 40px;
height: 40px;
background-color: white;
margin: 0;
padding: 0;
border: 0;
left: 5px;
border-radius: 8px;
position: relative;
transition: all .15s linear;
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
align-items: center;
}
button:hover {
background-color: #2f3647;
transition: all 0.15s linear;
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
}
.dark_theme {
background: #ffaaff
}
<button class="btn_theme" id="btn_theme"><img class="icon" data-theme="light" src="https://www.svgrepo.com/show/304624/sun-light-theme.svg"></button>
You need to update the src attribute of your image using setAttribute().
You could use modular arithmetic to switch between pictures. This would work for however many pictures you want to have. It is however not required for a two images as you could just use a boolean. Nevertheless here how you could do it using modulo operation.
// All the pictures we want to switch between
const pics = [
"https://dummyimage.com/50x50/000/fff",
"https://dummyimage.com/50x50/dddddd/000",
// "https://dummyimage.com/50x50/d420d4/000" // comment this out for a third pic
]
let curPicIdx = 0;
window.addEventListener("DOMContentLoaded", e => {
// when the page has loaded set the first picture
const button = document.getElementById("mybutton");
const img = document.getElementById("myimage");
img.setAttribute("src", pics[curPicIdx])
// whenever we click on the button change the picture to the next one
button.addEventListener("click", e => {
// calculate the index of the next picture using modular arithmetic
curPicIdx = (curPicIdx + 1) % pics.length;
console.log(`Setting pic ${curPicIdx}`);
// set the next picture using the calculated index
img.setAttribute("src", pics[curPicIdx]);
})
})
<button id="mybutton"><img id="myimage"/>
If you want to have three pictures, just add another URL within the array and it will switch between all three pictures.
In general there are a lot of ways to embed images into buttons. You might wanna have a look at this thread.

Slide button text

Could someone tell me why isn't my text "Add Product" appearing inside of the button when the user hovers on the button?
Adding
display: flex
for the body seems to fix the issue but I don't wanna set the display of my body to flex. Is there some other way I could make it work?
.button {
background: #f6bc00 no-repeat -12px center;
border: 1px solid #f6bc00;
border-radius: 4px;
color: #fff;
display: inline;
font-size: 9px;
font-weight: 700;
overflow: hidden;
padding: 5px 8px 3px 8px;
text-decoration: none;
line-height: 8px;
text-transform: uppercase;
transition: padding .2s ease, background-position .2s ease, transform .5s ease;;
}
.button:span {
margin: 0;
padding: 0;
}
.button:hover {
transform: scale(1, 1);
padding-left: 88px;
padding-right: 5px;
background-position: 5px center;
}
.button span:nth-child(1) {
position: absolute;
left: -70px;
transition: left .2s ease;
}
.button:hover span:nth-child(1) {
bottom: 3px;
left: 20px;
}
/* PRESENTATION */
body {
background-color: black;
}
.button:nth-child(1) {
margin-right: 1em;
}
<a class="button" href="#" download="">
<span>Add Product</span>
<span>Add</span></a>
one way to do it is to hide the add product text.
i changed this..
.button span:nth-child(1) {
position: absolute;
left: -70px;
transition: left .2s ease;
}
to this..
.button span:nth-child(1) {
display:none;
transition: left .2s ease;
}
then on hover display inline
.button:hover span:nth-child(1) {
display:inline;
bottom: 3px;
}
checkout the codepen.
https://codepen.io/cartoonzzy/pen/PoGYowZ

jQuery - .css() not working?

Exclaimer, this is mostly snippet code, cause I didn't know how else to explain this. Please don't hate :3
The jQuery code is supposed to set the "max-height" property for "#dd.show". So can someone tell me why this doesn't work:
$("#btn").on("click", function() {
$("#dd").toggleClass("show");
});
var dv = document.getElementById("dd");
var item = dv.getElementsByTagName("A");
$("#dd.show").css("max-height", item[0].offsetHeight * item.length + "px");
body {
margin: 10px;
}
#btn {
background-color: red;
color: black;
border: none;
outline: none;
width: 100px;
height: 100px;
font-size: 20px;
-webkit-transition: all .4s ease;
transition: all .4s ease;
}
#btn:hover {
background-color: black;
color: white;
border-radius: 52.5px;
}
#dd {
opacity: 0;
max-height: 0;
width: 200px;
position: relative;
overflow: hidden;
-webkit-transition: all 1s ease;
transition: all 1s ease;
}
#dd.show {
opacity: 1;
}
#dd.show:hover {
border-radius: 15px;
}
#dd a {
background-color: red;
color: black;
padding: 16px 16px;
text-align: center;
text-decoration: none;
display: block;
font-size: 20px;
-webkit-transition: all .4s ease;
transition: all .4s ease;
}
#dd a:hover {
background-color: black;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">press me</button>
<div id="dd">
press me 1
press me 2
press me 3
press me 4
</div>
This is how it's supposed to look like. The only thing i changed was removing the .css JQuery and added "max-height" manually:
$("#btn").on("click", function() {
$("#dd").toggleClass("show");
});
body {
margin: 10px;
}
#btn {
background-color: red;
color: black;
border: none;
outline: none;
width: 100px;
height: 100px;
font-size: 20px;
-webkit-transition: all .4s ease;
transition: all .4s ease;
}
#btn:hover {
background-color: black;
color: white;
border-radius: 52.5px;
}
#dd {
opacity: 0;
max-height: 0;
width: 200px;
position: relative;
overflow: hidden;
top: 10px;
-webkit-transition: all 1s ease;
transition: all 1s ease;
}
#dd.show {
opacity: 1;
max-height: 225px;
}
#dd.show:hover {
border-radius: 37.5px;
}
#dd a {
background-color: red;
color: black;
padding: 16px 16px;
text-align: center;
text-decoration: none;
display: block;
font-size: 20px;
-webkit-transition: all .4s ease;
transition: all .4s ease;
}
#dd a:hover {
background-color: black;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">press me</button>
<div id="dd">
press me 1
press me 2
press me 3
press me 4
</div>
jQuery works fine, you problem lies here: $("#dd.show"). At the point where you execute that code the selector #dd.show won't find anything as there exists no element like that. (You only add the show class on button click)
You will have to add that css when pressing the button. Also note that $.css adds in-line css. (like <div style="max-height:100px;"></div>)
at the time that this line executes:
$("#dd.show").css("max-height", item[0].offsetHeight * item.length + "px")
you don't know for a fact that the div with id dd also has the show class. Since the show class is dynamically toggled, I'm guessing that this element
<div id="dd">...</div>
doesn't have the show class when your jquery code is running. That means that $("#dd.show") isn't returning anything which explains why your css method isn't working.
This is precisely the kind of thing that you should use plain css for if possible. If you can get the behavior you want by simply specifying
#dd.show {
max-height: 225px;
}
then I'd just do that.
If you want to test this to see if I'm right, then add the following line right before you try to set the max-height property with jQuery.
console.log($("#dd").hasClass('show'));
I found a solution to the sliding problem. I added an IF statement to check if the "show" class is active. If it is then toggle it and set "max-height" to 0px. If no, then toggle it and set "max-height" to the other long value :) Thanks for all the help guys. You helped me towards the finishline :3
Here is the final code for people that might come in later to see the solution :3
$("#btn").on("click", function() {
if(!$("#dd").hasClass("show")) {
$("#dd").toggleClass("show");
$("#dd.show").css("max-height", document.getElementById("dd").getElementsByTagName("A")[0].offsetHeight * document.getElementById("dd").getElementsByTagName("A").length + "px");
} else {
$("#dd").toggleClass("show");
$("#dd").css("max-height", "0px");
}
});
body {
margin: 10px;
}
#btn {
background-color: red;
color: black;
border: none;
outline: none;
width: 100px;
height: 100px;
font-size: 20px;
-webkit-transition: all .4s ease;
transition: all .4s ease;
}
#btn:hover {
background-color: black;
color: white;
border-radius: 52.5px;
}
#dd {
opacity: 0;
max-height: 0;
width: 200px;
position: relative;
overflow: hidden;
-webkit-transition: all 1s ease;
transition: all 1s ease;
}
#dd.show {
opacity: 1;
}
#dd.show:hover {
border-radius: 15px;
}
#dd a {
background-color: red;
color: black;
padding: 16px 16px;
text-align: center;
text-decoration: none;
display: block;
font-size: 20px;
-webkit-transition: all .4s ease;
transition: all .4s ease;
}
#dd a:hover {
background-color: black;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">press me</button>
<div id="dd">
press me 1
press me 2
press me 3
press me 4
</div>

File upload not working, but fine in Codepen

I'm implementing this codepen I found for a file upload function. It works fine on codepen, however when I actually put it into my own html/css/js setup the file does not upload. I get no file name showing after a file has been selected.
Here is the code from codepen:
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div class="file-upload">
<div class="file-select">
<div class="file-select-button" id="fileName">Choose File</div>
<div class="file-select-name" id="noFile">No file chosen...</div>
<input type="file" name="chooseFile" id="chooseFile">
</div>
</div>
CSS
body
{
background-color: black;
}
.file-upload
{
width: 400px;
display: block;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
text-align: center;
}
.file-upload .file-select
{
background: #FFFFFF;
border: 2px solid #dce4ec;
color: #34495e;
cursor: pointer;
display: block;
height: 40px;
line-height: 40px;
overflow: hidden;
position: relative;
text-align: left;
}
.file-upload .file-select .file-select-button
{
background: #dce4ec;
display: inline-block;
height: 40px;
line-height: 40px;
padding: 0 10px;
}
.file-upload .file-select .file-select-name
{
display: inline-block;
line-height: 40px;
padding: 0 10px;
}
.file-upload .file-select:hover
{
border-color: #34495e;
moz-transition: all .2s ease-in-out;
o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
webkit-transition: all .2s ease-in-out;
}
.file-upload .file-select:hover .file-select-button
{
background: #34495e;
color: #FFFFFF;
moz-transition: all .2s ease-in-out;
o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
webkit-transition: all .2s ease-in-out;
}
.file-upload.active .file-select
{
border-color: #3fa46a;
moz-transition: all .2s ease-in-out;
o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
webkit-transition: all .2s ease-in-out;
}
.file-upload.active .file-select .file-select-button
{
background: #3fa46a;
color: #FFFFFF;
moz-transition: all .2s ease-in-out;
o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
webkit-transition: all .2s ease-in-out;
}
.file-upload .file-select input[type=file]
{
cursor: pointer;
filter: alpha(opacity=0);
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 100;
}
.file-upload .file-select.file-select-disabled
{
opacity: 0.65;
}
.file-upload .file-select.file-select-disabled:hover
{
background: #FFFFFF;
border: 2px solid #dce4ec;
color: #34495e;
cursor: default;
cursor: pointer;
display: block;
height: 40px;
line-height: 40px;
margin-top: 5px;
overflow: hidden;
position: relative;
text-align: left;
}
.file-upload .file-select.file-select-disabled:hover .file-select-button
{
background: #dce4ec;
color: #666666;
display: inline-block;
height: 40px;
line-height: 40px;
padding: 0 10px;
}
.file-upload .file-select.file-select-disabled:hover .file-select-name
{
display: inline-block;
line-height: 40px;
padding: 0 10px;
}
JS
$('#chooseFile').bind('change', function () {
var filename = $("#chooseFile").val();
if (/^\s*$/.test(filename)) {
$(".file-upload").removeClass('active');
$("#noFile").text("No file chosen...");
}
else {
$(".file-upload").addClass('active');
$("#noFile").text(filename.replace("C:\\fakepath\\", ""));
}
});
I've pasted the exact same code into my html and tried linking the javascript in both head and body. Also tried putting jquery cdn in both head and body. No success.
Any help would be much appreciated. Thanks.
******UPDATE******
Thanks for the suggestions guys. I actually tried the it with the CSS turned off and it works fine, which tells me it's nothing to do with the JS. So follow up question, what is it about this CSS that's stopping it from displaying the uploaded file?
You can open up the JavaScript tools in your browser and set a breakpoint on this line:
if (/^\s*$/.test(filename)) {
Then when the code runs you can see what value 'filename' has and figure out why the regular expression fails, and what it should be. The regexp you have there looks like it is checking for "a string that starts and ends with 0 or more spaces", so maybe you'll need to check for "filename.length == 0" or "filename === undefined".
You can debug the code in your destination website, but also within Codepen. It's a little tricky but can inspect your code running inside the pen to get a value for comparison.
If you still need help, please write back with the value of "filename" from your debugger sessions.
Debugging JS in Chrome tutorial.
Maybe it don't works in your html site, because the javascript will be executed too early. Wrap your js code into:
$(document).ready(function() {
// Put code here
});
This worked for me
$(document).ready(function () {
$("#chooseFile").change(function () {
//your code here
});
});

JavaScript: css toggle switch to dark mode

I have created a toggle switch using css.
I want #box1 to turn from a white background with black type to a black with white text and the toggle to turn to on.
I'm stuck trying to figure out the JavaScript. The button doesn't switch and the box doesn't turn back to white.
$('#myonoffswitch').change(function(){
console.log('here');
if ($(this).click())
{
$('#box1').addClass('dark-mode');
}
else
{
$('#box1').removeClass('dark-mode');
}
});
How can toggle the dark-mode class.
Fiddle
You can just use the toggleClass method. Demo
$('#myonoffswitch').change(function(){
$('#box1').toggleClass('dark-mode');
});
$(this).click() returns an instance of jQuery, which is a truthy value in JavaScript, this is why addClass was called in the first place
$('#myonoffswitch').change(function() {
$('#box1').toggleClass('dark-mode');
});
.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: #FFFFFF;
color: #000000;
}
.onoffswitch-inner:after {
content: "OFF";
padding-right: 10px;
background-color: #FFFFFF;
color: #000000;
text-align: right;
}
.onoffswitch-switch {
display: block;
width: 18px;
margin: 6px;
background: #000000;
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;
background-color: #FFFFFF;
}
#box1 {
color: black;
background-color: white;
border: 1px solid;
width: 100px;
height: 100px;
}
#box1.dark-mode {
color: #fff;
background-color: #000;
width: 100px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="onoffswitch">
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch">
<label class="onoffswitch-label" for="myonoffswitch">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
<br>
<div id="box1">This is text.</div>

Categories

Resources