First of all, give thanks for reading my question and try to help me and apologize for my English.
I would like to have a space between search content that contains and input with datalist, but I don't know why I can't create that space.
Can someone help me, please??
Here is my code:
render() {
const { value } = this.state;
return (
<div className="search search__content">
<div className="inner-addon left-addon">
<i className="icon-search search-icon"></i>
<input onChange={this.handleSearch} type="text" placeholder="Search..." value={value} list="list_languages" autoComplete="on" />
<datalist id="list_languages">
<option>HTML</option>
<option>CSS</option>
<option>JavaScript</option>
<option>Java</option>
<option>Ruby</option>
<option>PHP</option>
<option>Go</option>
<option>Erlang</option>
<option>Python</option>
<option>C</option>
<option>C#</option>
<option>C++</option>
<option>HTML</option>
</datalist>
</div>
</div>
);
}
And here is my CSS:
.search {
height: 200px;
padding: 10px;
position: absolute;
z-index: 999;
top: 0;
right: 0px;
&__content {
top: 200px;
left: 320px;
width: 500px;
height: 50px;
background-color: #fff;
border-radius: 34px;
box-shadow: 0px 0px 12px rgba(0,0,0,0.3);
input {
width: 450px;
height: 30px;
background: transparent;
border: 0;
display: block;
padding: 10px 32px 10px 20px;
font-size: 14px;
color: #000;
border-radius: 34px;
border: none;
outline: none;
}
datalist {
// why doesn't work?
top: 50px;
margin-top: 50px;
}
input::-webkit-calendar-picker-indicator {
display: none;
}
.input-field input.placeholder {
color: #ccc;
font-size: 14px;
}
.search-icon {
// color: #576a8b;
color: #000;
font-size: 20px;
}
.search-icon:hover {
cursor: pointer;
color: gray;
}
.inner-addon {
position: relative;
left: 10px;
}
.inner-addon i {
position: absolute;
}
.left-addon i { left: 0px;}
.left-addon input { padding-left: 30px; }
}
}
Thanks a lot!! Finally I use padding to move text up but move input down and leave a little space between text and options.
JAVASCRIPT CODE:
render() {
const { value, options } = this.state;
return (
<div className="search search__content">
<div className="inner-addon left-addon">
<input onChange={this.handleSearch} onKeyDown={this.handlePressEnter} type="text" placeholder={PLACEHOLDER} value={value} list="list_languages" autoComplete="on" />
<div className="datalist">
<datalist id="list_languages">
{ options && options.length > 0 && options.map( (option, index) => {
return (
<option value={option.nombre} key={index} />
);
})}
</datalist>
</div>
</div>
</div>
);
}
CSS:
.search {
height: 200px;
position: absolute;
z-index: 999;
top: 0;
right: 0px;
&__content {
top: 200px;
left: 320px;
width: 430px;
height: 50px;
background-color: #fff;
border-radius: 34px;
box-shadow: 0px 0px 12px rgba(0,0,0,0.3);
input {
width: 380px;
height: 50px;
background: transparent;
border: 0;
display: block;
padding: 0px 32px 10px 10px;
font-size: 14px;
color: #000;
border-radius: 34px;
border: none;
outline: none;
}
input::-webkit-calendar-picker-indicator {
display: none;
}
.input-field input.placeholder {
color: #ccc;
font-size: 14px;
}
.inner-addon {
position: relative;
top: 5px;
left: 22px;
}
// .search-icon {
// // color: #576a8b;
// color: #000;
// font-size: 20px;
// }
// .search-icon:hover {
// cursor: pointer;
// color: gray;
// }
// .inner-addon i {
// position: absolute;
// }
// .left-addon i { left: 0px;}
// .left-addon input { padding-left: 30px; }
}
}
the datalist element has very little flexibility in styling. You cannot style datalist just like select elements.
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Styling_HTML_forms#The_ugly
Some elements simply can't be styled using CSS. These include: all
advanced user interface widgets, such as range, color, or date
controls; and all the dropdown widgets, including <select>, <option>,
<optgroup> and <datalist> elements. The file picker widget is also
known not to be stylable at all. The new and
elements also fall in this category.
Browsers define their own styles for these elements.
if you need more options you can use libs like react-select
Related
I am trying to float the labels onfocusing input in angular.
I did wrote code to perform the action of a class to be applied on focusing the input, & then focus out to check empty value or values present, to remove the applied class.
forms.component.html
<div class="forms-field-box">
<div class="forms-field-inp-box">
<input id="forms_field_inp_fn" class="forms-field-inp" type="text" (focus)=inpAnim();>
<label for="forms_field_inp_fn" id="forms_input" class="forms-field-inp-lbl">
FirstName
</label>
</div>
</div>
<div class="forms-field-box">
<div class="forms-field-inp-box">
<input id="forms_field_inp_ln" class="forms-field-inp" type="text" (focus)=inpAnim();>
<label for="forms_field_inp_ln" id="forms_input" class="forms-field-inp-lbl">
LastName
</label>
</div>
</div>
<div class="forms-field-box">
<div class="forms-field-inp-box">
<input id="forms_field_inp_p" class="forms-field-inp" type="text" (focus)=inpAnim();>
<label for="forms_field_inp_p" id="forms_input" class="forms-field-inp-lbl">
Password
</label>
</div>
</div>
<div class="forms-login-btn">
Login
</div>
forms.component.scss
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
.forms-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60%;
background-color: #ffffff;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5);
min-height: 120px;
padding: 20px;
border-radius: 5px;
}
.forms-field-box {
background-color: #ffffff;
margin-bottom: 15px;
}
.forms-field-inp-box {
width: 97%;
position: relative;
}
.forms-field-inp {
width: 100%;
height: 35px;
border-radius: 5px;
border: 1px solid #e4e4e4;
outline: none;
padding: 6px;
}
.forms-field-inp:hover {
border: 1px solid #cccccc;
}
.forms-field-inp:focus {
border: 1px solid #0089ff;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.forms-field-inp-lbl {
position: absolute;
top: 8px;
left: 10px;
font-size: 14px;
font-weight: 600;
background-color: #ffffff;
padding: 2px 6px;
user-select:none;
color: #cccccc;
}
.forms-field-inp-lbl-anim ~ .forms-field-inp-lbl {
top: -9px;
}
.forms-login-btn {
width: 20%;
height: 35px;
text-align: center;
font-size: 18px;
padding: 5px;
background-color: blue;
border: 1px solid blue;
border-radius: 5px;
margin: 10px auto;
cursor: pointer;
box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
}
forms.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-forms',
templateUrl: './forms.component.html',
styleUrls: ['./forms.component.scss']
})
export class FormsComponent implements OnInit {
constructor() {
}
ngOnInit(): void {
}
inpAnim(){
let forms_input_ele:any = document.querySelector(".forms-field-inp-box input");
forms_input_ele.addEventListener("focusin", () => {
console.log("focussed in");
forms_input_ele.classList.add("forms-field-inp-lbl-anim");
} );
forms_input_ele.addEventListener("focusout", () => {
let forms_inp_val = forms_input_ele.value;
if(forms_inp_val == ""){
forms_input_ele.classList.remove("forms-field-inp-lbl-anim");
console.log("focussed out");
console.log(forms_inp_val);
}
});
}
}
Please Help me to solve this.
input focused & label floated
input has value & label stays
Problem: But, the first input only works, other inputs not working if focused & nothing happens.,
Next input is focused, but label not floating
This can be easily applied by css, but need to make this small code to work correctly
So I'm currently working on a personal project. And came across with a problem.
I want my border color of this div to green when the user clicks the radio button inside that div. Like this:
Here
But my current version looks like this:
Here
Here is my CSS and HTML
.backProjectCard2 {
padding-right: 10px;
}
.backProjectCard {
border: 2px solid #ececec;
border-radius: 10px;
margin: 0 0 20px;
padding-top: 24px;
position: relative;
right: 5px;
width: 580px;
}
/*For Input and .checkmark*/
.backProjectCard input {
position: relative;
height: 20px;
width: 20px;
left: 20px;
}
.input {
position: absolute;
opacity: 0;
cursor: pointer;
}
.backProject input:checked~.checkmark {
background-color: #fff;
}
.checkmark {
position: absolute;
top: 27px;
left: 20px;
height: 18px;
width: 18px;
background-color: #fff;
border-radius: 50%;
border: solid #e0e0e0 1.7px;
z-index: -1;
}
.backProject input:checked~.checkmark:after {
display: block;
}
.backProject .checkmark:after {
top: 2px;
left: 3px;
width: 10px;
height: 10px;
border-radius: 50%;
background: hsl(176, 50%, 47%);
}
.checkmark:after {
z-index: 1;
content: "";
position: absolute;
display: none;
}
<div class="backProjectCard backProjectCard2">
<input onclick="radioCheck();" type="radio" class="input">
<span class="checkmark"></span>
<h4 id="card-h">Bamboo Stand</h4>
<h3>Pledge $25 or more</h3>
<p id="left">left</p>
<h2 id="card2-num">101</h2>
<p>You get an ergonomic stand made of natural baamboo. You've helped us launch our promotional campaign, and you'll be added to a special Backer member list.</p>
<hr>
<div class="pledgeSection">
<p>Enter your pledge</p>
<button class="btn-1 card2Btn">Continue</button>
<button class="btn-2">
<p>$</p>
<input value="25" class="input-price input-price2" type="number">
</button>
</div>
JS (Only for clicking the radio button twice):
function radioCheck() {
timesClicked++
if (timesClicked > 1) {
$("input").prop("checked", false)
timesClicked = 0;
}
}
function colorchange() {
var x = document.getElementById('checker');
var y = document.getElementById('radiobox');
if (x.checked === true) {
y.style.borderColor = "green";
} else {
y.style.borderColor = "silver";
}
}
#radiobox {
width: 300px;
height: 200px;
border: 5px solid;
border-color: silver;
}
<div id="radiobox">
<input type="radio" onclick="colorchange();" id="checker"></input>
</div>
To keep it simple, I'll just use a short example and you can just apply it to your own example.
This is how you can do that
function radioCheck(){
// Get the checkbox
var checkBox = document.getElementById("myInputCheck");
// Get the div with border
var divBorder = document.getElementsByClassName("backProjectCard")[0]
// If the checkbox is checked, display the border
if (checkBox.checked == true){
divBorder.classList.remove("backProjectCard"); //remove "backProjectCard"
divBorder.classList.add("newBorder"); //add the new border with new color
} else {
divBorder.classList.remove("newBorder");
divBorder.classList.add("backProjectCard");
}
}
.backProjectCard2 {
padding-right: 10px;
}
.backProjectCard {
border: 2px solid #ececec;
border-radius: 10px;
margin: 0 0 20px;
padding-top: 24px;
position: relative;
right: 5px;
width: 580px;
}
/*For Input and .checkmark*/
.backProjectCard input {
position: relative;
height: 20px;
width: 20px;
left: 20px;
}
.input {
position: absolute;
opacity: 1;
cursor: pointer;
}
.checkmark {
position: absolute;
top: 27px;
left: 20px;
height: 18px;
width: 18px;
background-color: #fff;
border-radius: 50%;
border: solid #e0e0e0 1.7px;
z-index: -1;
}
.newBorder{
border: 2px solid #177972 !important;
border-radius: 10px;
margin: 0 0 20px;
padding-top: 24px;
position: relative;
right: 5px;
width: 580px;
}
<div class="backProjectCard backProjectCard2">
<input onclick="radioCheck();" type="radio" id="myInputCheck">
<h4 >Bamboo Stand</h4>
<h3>Pledge $25 or more</h3>
<p >left</p>
<h2 >101</h2>
<p>You get an ergonomic stand made of natural baamboo. You've helped us launch our promotional campaign, and you'll be added to a special Backer member list.</p>
I am trying to figure out how to make a 10px halo over the -slider-thumb attribute of my range input slider. I am using React, CSS and HTML and have found this difficult to do because of the overflow:hidden property. This property must stay, as basically none of the code works without it(This was part of a solution to editing the slider base css). I have tried using ::after and ::before with no avail. So I'm wondering what I'm doing wrong, or if this is even possible as I haven't found any documentation on it. Code and Codepen provided below. Thanks for any help/advice!
HTML:
<div id="root"></div>
CSS:
input[type='range'] {
-webkit-appearance: none;
background-color: #ddd;
height: 10px;
overflow: hidden;
width: 300px;
border-radius: 5px;
outline: none;
}
input[type='range']::-webkit-slider-runnable-track {
-webkit-appearance: none;
height: 10px;
}
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
--slider-thumb-background-color: #000;
background: var(--slider-thumb-background-color);
border-radius: 50%;
--box-shadow-color: orange;
box-shadow: -205px 0 0 200px var(--box-shadow-color);
cursor: pointer;
height: 10px;
width: 10px;
--border-color: orange;
border: 3px solid var(--border-color);
}
input[type='range']::-webkit-slider-thumb:hover::after {
content: '';
height: 10px;
width: 10px;
border-radius: 5px;
color: yellow;
}
input[type='range']::-webkit-slider-thumb:hover {
--slider-thumb-background-color: grey;
--box-shadow-color: red;
--border-color: red;
}
input[type='range']::-webkit-slider-thumb:active {
--slider-thumb-background-color: white;
--box-shadow-color: blue;
--border-color: blue;
}
input[type='range']::-webkit-slider-thumb:focus {
--slider-thumb-background-color: white;
--box-shadow-color: yellow;
--border-color: yellow;
}
input[type='range']::-webkit-slider-thumb:hover:after {
border: 10px solid rgb(111, 111, 0.4);
overflow: auto;
postion: fixed;
}
input[type='range']::-moz-range-thumb {
background: #333;
border-radius: 50%;
box-shadow: -1005px 0 0 1000px red;
cursor: pointer;
height: 10px;
width: 10px;
border: 0;
}
JS(Babel)
class VolumeSlider extends React.Component {
constructor() {
super();
this.state = {
value: 120.5
};
}
onUpdate(e) {
this.setState({
value: e.target.value
});
}
render() {
return (
<div>
<div className="mb1">
<input
className="c-input--range"
list="tickmarks"
max={1200}
onChange={(e) => this.onUpdate(e)}
step={0.1}
type="range"
value={this.state.value}
/>
<div>
<label className="c-label">{this.state.value}c</label>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<div>
<VolumeSlider />
</div>,
document.getElementById("root")
);
https://codepen.io/kcandle/pen/KKMrZKo
Look at this pen hope this is what you're looking for, explanation:
i've added the after with position absolute made the input relative position made the after 1px X 1px, made inset then translated X axis from 0 to whatever value i want.
input[type='range']::after{
content: "";
position: absolute;
top: 0px;
left: 0px;
border-radius: 50%;
visibility: hidden;
width: 1px;
height: 1px;
box-shadow: 0 0 10px 5px #fff, inset 0 0 10px 5px #fff;
}
input[type='range']:hover::after{
visibility: visible;
animation: wave 2s forwards;
}#keyframes wave {
0% {
transform:translateX(0);
}
100% {
transform:translateX(500px);
}
}
https://codepen.io/headsick/pen/xxOMXqw
I would like to add inline CSS to the left and right messages that are generated, for example the left text is red and the right text is blue. (I know it's best to style in the CSS, but I'm testing something else). So I will have this HTML:
<ul class="messages">
<li class="message left appeared">
<div class="text_wrapper">
<p class="text" style="color:red;">blabla</p>
</div>
</li>
<li class="message right appeared">
<div class="text_wrapper">
<p class="text" style="color:blue;">blabla</p>
</div>
</li>
</ul>
Please see the code as reference for the functionality. Many thanks for your help.
(function() {
var Message;
Message = function({
text: text1,
message_side: message_side1
}) {
this.text = text1;
this.message_side = message_side1;
this.draw = () => {
var $message;
$message = $($('.message_template').clone().html());
$message.addClass(this.message_side).find('.text').html(this.text);
$('.messages').append($message);
return setTimeout(function() {
return $message.addClass('appeared');
}, 0);
};
return this;
};
$(function() {
var getMessageText, message_side, sendMessage;
message_side = 'right';
getMessageText = function() {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function(text) {
var $messages, message;
if (text.trim() === '') {
return;
}
$('.message_input').val('');
$messages = $('.messages');
message_side = message_side === 'left' ? 'right' : 'left';
message = new Message({text, message_side});
message.draw();
return $messages.animate({
scrollTop: $messages.prop('scrollHeight')
}, 300);
};
$('.send_message').click(function(e) {
return sendMessage(getMessageText());
});
$('.message_input').keyup(function(e) {
if (e.which === 13) { // enter key
return sendMessage(getMessageText());
}
});
});
}).call(this);
* {
box-sizing: border-box;
}
.chat_window {
position: absolute;
width: calc(100% - 20px);
max-width: 600px;
height: 440px;
background-color: #fff;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
border: 1px solid #ddd;
overflow: hidden;
}
.messages {
position: relative;
list-style: none;
padding: 20px 10px 0 10px;
margin: 0;
height: 347px;
overflow: scroll;
}
.messages .message {
clear: both;
overflow: hidden;
margin-bottom: 20px;
transition: all 0.5s linear;
opacity: 0;
}
.messages .message.left .text_wrapper {
background-color: #ddd;
margin-left: 20px;
}
.messages .message.left .text_wrapper::after, .messages .message.left .text_wrapper::before {
right: 100%;
border-right-color: #ddd;
}
.messages .message.left .text,
.messages .message.right .text {
color: #000;
margin: 0;
}
.messages .message.right .text_wrapper {
background-color: #ddd;
margin-right: 20px;
float: right;
}
.messages .message.right .text_wrapper::after, .messages .message.right .text_wrapper::before {
left: 100%;
border-left-color: #ddd;
}
.messages .message.appeared {
opacity: 1;
}
.messages .message .text_wrapper {
display: inline-block;
padding: 20px;
width: calc(100% - 85px);
min-width: 100px;
position: relative;
}
.messages .message .text_wrapper::after, .messages .message .text_wrapper:before {
top: 18px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.messages .message .text_wrapper::after {
border-width: 13px;
margin-top: 0px;
}
.messages .message .text_wrapper::before {
border-width: 15px;
margin-top: -2px;
}
.messages .message .text_wrapper .text {
font-size: 18px;
font-weight: 300;
}
.bottom_wrapper {
position: relative;
width: 100%;
background-color: #fff;
padding: 20px 20px;
position: absolute;
bottom: 0;
}
.bottom_wrapper .message_input_wrapper {
display: inline-block;
height: 50px;
border: 1px solid #bcbdc0;
width: calc(100% - 160px);
position: relative;
padding: 0 20px;
}
.bottom_wrapper .message_input_wrapper .message_input {
border: none;
height: 100%;
box-sizing: border-box;
width: calc(100% - 40px);
position: absolute;
outline-width: 0;
color: gray;
}
.bottom_wrapper .send_message {
width: 140px;
height: 50px;
display: inline-block;
background-color: #ddd;
border: 2px solid #ddd;
color: #000;
cursor: pointer;
transition: all 0.2s linear;
text-align: center;
float: right;
}
.bottom_wrapper .send_message:hover {
color: #000;
background-color: #fff;
}
.bottom_wrapper .send_message .text {
font-size: 18px;
font-weight: 300;
display: inline-block;
line-height: 48px;
}
.message_template {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat_window">
<ul class="messages"></ul>
<div class="bottom_wrapper clearfix">
<div class="message_input_wrapper">
<input class="message_input" placeholder="Type here..." />
</div>
<div class="send_message">
<div class="icon"></div>
<div class="text">
Send
</div>
</div>
</div>
</div>
<div class="message_template">
<li class="message">
<div class="text_wrapper">
<p class="text"></p>
</div>
</li>
</div>
You can also add:
$(".left").css("color", "yellow");
$(".right").css("color", "blue");
$("li.message.left > div.text_wrapper > p").css('color', 'red');
$("li.message.right > div.text_wrapper > p").css('color', 'blue');
Using jQuery you can add inline style to an element
$(".left").attr("style","whatever");
$(".right").attr("style","whatever");
You can use the classList of every HTML component. Simply, select the DOM element with class left (or right) and use the add method to assign whatever class:
var elementLeft = $('.left')
elementLeft.classList.add('yourClass')
You can also use the methods remove to remove any class, or toggle to toggle some class..
elementLeft.classList.remove('yourClass')
elementLeft.classList.toggle('yourClass')
The Element.classList contains more examples. This solution works without jQuery or others javascript library, but use the standard API.
Maybe some of you can help me solve this problem.
I have this code and I made like an extension for the product that will show product description when click on product. But the on click function isn't working (can't close description).
Thanks!
$('.product').on('click', function(){
$('.product .productExtension').css("display","none");
$(this).children(".productExtension").css("display","block");
});
function close(){
$('.productExtension').css("display","none");
}
.product{
position: relative;
width: 80px; height: 160px;
padding: 20px;
border: solid 1px grey;
text-align: center; font-family: Arial;
}
.product > .productExtension{
position: fixed;
top: 50%; left: 50%; transform: translate(-50%,-50%);
width: 300px; height: 200px;
padding: 20px;
background: red;
text-align: left;
display: none;
}
.product > .productExtension > .closeProductExtension{
position: absolute;
top: -40px; left: 0;
width: 20px; height: 20px;
margin: 10px;
border: none;
background: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product">
<div class="productName">Red Hoodie</div>
<div class="productPrice">14.72$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in red color</div>
<div class="closeProductExtension" onclick="close()">Close</div>
</div>
</div>
Now I know it wasn't fully part of the question, and I took a bit of liberty with the styling, but there is absolutely no need to hide all different productExtension classes upon each close. It would be far lighter to read the properties detailed inside your product div, and render them to a modal.
It does have an overly complex way of closing the modal ( just some liberties at work there, I am sorry for that one :) )
The answer that is currently accepted both details the reason why you cannot use close (could be window.close), I just thought the offer a different perspective when you have more than one product how to transfer the data between a modal and your DOM as you describe it now. I think it has its advantages
window.addEventListener( 'load', function() {
document.querySelectorAll('.product').forEach( product => {
product.addEventListener('click', handleProductClicked, false );
} );
document.querySelectorAll('[data-action]').forEach( action => {
action.addEventListener('click', handleAction );
} );
function handleAction( e ) {
const owner = e.currentTarget;
const action = owner.getAttribute('data-action');
const selector = owner.getAttribute('data-target');
const target = document.querySelector( selector );
if (action === 'hide') {
if ( !target.classList.contains('hidden') ) {
target.classList.add('hidden');
}
}
}
function showModal( title, content, owner ) {
const modal = document.querySelector('#modal');
if ( modal.classList.contains('hidden') ) {
modal.classList.remove( 'hidden' );
}
modal.querySelector('[data-for=title]').innerText = title;
modal.querySelector('[data-for=content]').innerHTML = content;
}
function handleProductClicked( e ) {
const productContainer = e.currentTarget;
const name = productContainer.querySelector('.productName').innerText;
const description = productContainer.querySelector('.productExtension').innerHTML;
showModal( name, description, productContainer );
}
} );
.hidden {
display: none;
visibility: hidden;
}
.productExtension {
display: none;
visibility: hidden;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 200px;
border: solid #a0a0a0 1px;
box-shadow: 5px 3px 5px #777;
background-color: #cfcfcf;
}
.modal > .title {
position: absolute;
left: 0px;
top: 0px;
right: 0px;
height: 20px;
font-size: 0.9em;
background-color: blue;
border-bottom: solid #fff 1px;
}
.modal > .title > .controls {
position: absolute;
right: 0px;
top: 0px;
width: 20px;
height: 18px;
background-color: #efefef;
border: solid #a0a0a0 1px;
text-align: center;
text-transform: small-caps;
}
.controls:hover {
font-weight: bold;
cursor: pointer;
}
.modal > .title > [data-for] {
padding: 3px;
color: #fff;
font-weight: 800;
}
.modal > .content {
position: absolute;
left: 0px;
right: 0px;
top: 21px;
bottom: 0px;
padding: 5px;
border: inset #666 1px;
}
.product {
position: relative;
width: 80px;
height: 160px;
padding: 20px;
border: solid 1px grey;
text-align: center;
font-family: Arial;
}
<div class="modal hidden" id="modal">
<div class="title">
<span data-for="title"></span>
<div class="controls">
<span data-action="hide" data-target="#modal">X</span>
</div>
</div>
<div class="content" data-for="content">
</div>
</div>
<div class="product">
<div class="productName">Red Hoodie</div>
<div class="productPrice">14.72$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in red color</div>
</div>
</div>
<div class="product">
<div class="productName">Blue Hoodie</div>
<div class="productPrice">14.75$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in blue color</div>
</div>
</div>
This is happening because both functions trigger. The first trigger because you are clicking on an item that is inside the DIV “product” and the second because you’ve passed the function to the onClick. You should take out the “productExtension” div from “product” to make it works.
As mentioned in other comments, you have two click handler in the parent and child. The parent div is intercepting all click events. Try this for your requirement.
$(".product").on("click", function(e) {
$(".product .productExtension").css("display", "none");
$(this)
.children(".productExtension")
.css("display", "block");
if (e.target.classList.contains('closeProductExtension')) {
$(".productExtension").css("display", "none");
}
});
You have several problems. The first is that you trigger the open event as well. To solve this you can use stop propagation. The second is that you are using the method name "close" which is already used in JS.
$('.product').on('click', function() {
$('.product .productExtension').css("display", "none");
$(this).children(".productExtension").css("display", "block");
});
function closeE(event) {
event.stopPropagation();
$('.productExtension').css("display", "none");
}
.product {
position: relative;
width: 80px;
height: 160px;
padding: 20px;
border: solid 1px grey;
text-align: center;
font-family: Arial;
}
.product>.productExtension {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 200px;
padding: 20px;
background: red;
text-align: left;
display: none;
}
.product>.productExtension>.closeProductExtension {
position: absolute;
top: -40px;
left: 0;
width: 20px;
height: 20px;
margin: 10px;
border: 1px solid black;
background: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product">
<div class="productName">Red Hoodie</div>
<div class="productPrice">14.72$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in red color</div>
<div class="closeProductExtension" onclick="closeE(event)">Close</div>
</div>
</div>