I am trying to build a very simple pyramid construction kit. The user can add a block or remove one.
This works fine using the code below. However, currently I am specifying the next block's width using css (.item1 {200px;}, .item2 {300px;}. The problem is, I don't know how many blocks the user will add eventually and therefore, I cannot specify this in CSS. I would like to calculate the width of each additional block's width based on the previous block's width + 100px (previous width + 100px). Unfortunately, I don't know how to do this...Any help would be appreciated.
simple pyramid pic
$(document).ready(function() {
//Add Block Functionality
$('#add-block .button').click(function() {
var $block = $('<li><div class="item"><input class="input" type="text" placeholder="#" maxlength="2"></div></li>');
$('.pyramid').append($block);
$('ul li div').addClass(function(index) {
return "item" + index;
}) //this is to increase the item to item 1, item2, item3 etc.
});
//Remove Block Functionality
$('#remove-block .button').click(function() {
$('.pyramid li').last().remove();
}
)
});
.item {
margin: 0 auto;
position: relative;
display: flex;
justify-content: center;
}
.item0 {
height: 0px;
width: 0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 60px solid #0488e0;
}
li div.item:not(.item0) {
border-bottom: 60px solid #0488e0;
border-left: 45px solid transparent;
border-right: 45px solid transparent;
margin-top: 10px;
height: 0;
}
.item1 {
width: 200px;
/*plus 100px to create the trapezoid*/
}
.item2 {
width: 300px;
/*plus 100px to create the trapezoid*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="pyramid">
<li>
</li>
</ul>
<section class="buttons">
<div id="add-block">
<span>Add Block</span>
<div class="button">+
</div>
</div>
<div id="remove-block">
<span>Remove Block</span>
<div class="button">-
</div>
</div>
</section>
You can get the last .item width then append your desire number var lastwidth = $('.pyramid li:last-child .item').width();
$(document).ready(function() {
//Add Block Functionality
$('#add-block .button').click(function() {
var lastwidth = $('.pyramid li:last-child .item').width();
if(lastwidth == null){
var plus = 0;
} else {
var plus = lastwidth + 100;
}
var $block = $('<li><div class="item" style="width:' + plus + 'px"><input class="input" type="text" placeholder="#" maxlength="2"></div></li>');
$('.pyramid').append($block);
//$('ul li div').addClass(function(index) {
//return "item" + index;
//}) //this is to increase the item to item 1, item2, item3 etc.
});
//Remove Block Functionality
$('#remove-block .button').click(function() {
$('.pyramid li').last().remove();
}
)
});
.item {
margin: 0 auto;
position: relative;
display: flex;
justify-content: center;
}
.item0 {
height: 0px;
width: 0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 60px solid #0488e0;
}
li div.item:not(.item0) {
border-bottom: 60px solid #0488e0;
border-left: 45px solid transparent;
border-right: 45px solid transparent;
margin-top: 10px;
height: 0;
}
.item1 {
width: 200px;
/*plus 100px to create the trapezoid*/
}
.item2 {
width: 300px;
/*plus 100px to create the trapezoid*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="pyramid">
<li>
</li>
</ul>
<section class="buttons">
<div id="add-block">
<span>Add Block</span>
<div class="button">+
</div>
</div>
<div id="remove-block">
<span>Remove Block</span>
<div class="button">-
</div>
</div>
</section>
Related
I have encountered a problem with javascript clicking to change CSS!
I hope that the outer frame and text of the clicked option can be thickened after clicking, but the ones that are not selected should not be thickened! I
have tried several ways of writing, but I still don't know how To complete this requirement, I hope to get everyone's help, thank you.
let plan = document.querySelector('.plan');
let price = document.querySelector('.price');
let item = document.querySelectorAll('.item');
for (var i = 0; i < item.length; i++) {
item[i].addEventListener('click', showplan, false);
}
function showplan(e) {
//Originally intended to increase this way, but it seems that it can't be written like this
// e.target.closesst('li').classList.add('bold')
// e.target.closesst('h2').classList.add('bold')
const planSelected = e.target.closest('li').querySelector('h2');
const priceSelected = e.target.closest('li').querySelector('p');
plan.textContent = planSelected.textContent;
price.textContent = priceSelected.textContent;
}
#charset "UTF-8";
.product_list {
display: flex;
}
.product_list .item {
border: 1px solid #ccc;
border-radius: 6px;
text-align: center;
padding: 20px;
margin: 20px;
}
.product_list .item h2 {
margin-bottom: 16px;
}
.product_list .item:hover {
border: 1px solid #222;
}
.show {
border: 2px solid blue;
padding: 20px;
}
.bold {
border: 3px solid;
font-weight: 900;
}
<ul class="product_list">
<li class="item">
<h2>coke</h2>
<p>$100</p>
</li>
<li class="item">
<h2>beef</h2>
<p>$600</p>
</li>
</ul>
<h2 class="show">Your food of choice is <span class="plan"></span>The total price is<span class="price"></span></h2>
You need to toggle the class, you can do that by removing it from every item and only setting it to the selected one:
item.forEach(el => el.classList.remove('active'))
e.currentTarget.classList.add('active')
Also you have a CSS specificity issue:
when using only .bold, the border would be overriden by .product_list .item
Note, try using currentTarget
const plan = document.querySelector('.plan');
const price = document.querySelector('.price');
const item = document.querySelectorAll('.item');
function showplan(e) {
const target = e.currentTarget;
const closestLi = target.closest('li');
const planSelected = closestLi.querySelector('h2');
const priceSelected = closestLi.querySelector('p');
item.forEach(el => el.classList.remove('active'))
target.classList.add('active')
plan.textContent = planSelected.textContent;
price.textContent = priceSelected.textContent;
}
item.forEach(el => el.addEventListener('click', showplan));
#charset "UTF-8";
.product_list {
display: flex;
}
.product_list .item {
border: 1px solid #ccc;
border-radius: 6px;
text-align: center;
padding: 20px;
margin: 20px;
}
.product_list .item h2 {
margin-bottom: 16px;
}
.product_list .item:hover,
{
border: 1px solid #222;
}
.product_list .active {
border: 3px solid red;
font-weight: 900;
color: red;
}
.show {
border: 2px solid blue;
padding: 20px;
}
<ul class="product_list">
<li class="item">
<h2>coke</h2>
<p>$100</p>
</li>
<li class="item">
<h2>beef</h2>
<p>$600</p>
</li>
</ul>
<h2 class="show">Your food of choice is <span class="plan"></span>The total price is<span class="price"></span></h2>
How to add CSS after click through javascript and remove it if not clicked?
Suppose we have a class"item",we want change "h1"
add class:
e.currentTarget.classList.add('item')
remove class:
e.currentTarget.classList.remove('item')
toggle class:
e.currentTarget.classList.toggle('item')
toggle means:
(If h1 has this class,remove,if not,add)
With jQuery, two :radios and their corresponding labels:
var $plan = $('.plan');
var $price = $('.price');
var $item = $('.item');
$('.item').on('click', showplan);
function showplan(e) {
const plan = $(this).find('h2').text();
const price = $(this).find('p').text();
$plan.text(plan);
$price.text(price);
}
#charset "UTF-8";
.product_list {
display: flex;
}
.product_list .item {
border: 1px solid #ccc;
border-radius: 6px;
text-align: center;
padding: 20px;
margin: 20px;
cursor: pointer;
}
.product_list input {
display: none;
}
.product_list .item h2 {
margin-bottom: 16px;
}
.product_list .item:hover {
border: 1px solid #222;
}
.show {
border: 2px solid blue;
padding: 20px;
}
.product_list input:checked + label {
outline: 2px solid black; /* Prevent jumping. */
border: 1px solid black;
font-weight: 900;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product_list">
<input type="radio" name="product" id="coke">
<label class="item" for="coke">
<h2>coke</h2>
<p>$100</p>
</label>
<input type="radio" name="product" id="beef">
<label class="item" for="beef">
<h2>beef</h2>
<p>$600</p>
</label>
</div>
<h2 class="show">Your food of choice is <span class="plan">?</span>. The total price is <span class="price">?</span>.</h2>
I am confused. I want two products to be selected. These products will be open by clicking the button. The selection will be made on the screen that opens. And the selected product will replace the button clicked.
I can show the products by clicking the button. I even got the result I wanted as text with jquery. But I used <select> <option> for this. There will be no drop-down list and only one will be selected. The selected image will replace the clicked area. I couldn't :(
$(document).ready(function() {
$(".showbutton, .showbutton img").click(function(event) {
var buttonName = $(this).closest('div').attr('id');
var buttonNo = buttonName.slice(4);
var boxName = "#box" + buttonNo;
$(boxName).fadeIn(300);
});
$(".closebtn").click(function() {
$(".box").fadeOut(200);
});
$(".box").click(function() {
$(".box").fadeOut(200);
});
$(".innerbox").click(function() {
event.preventDefault();
event.stopPropagation();
});
});
div.showbutton {}
div.showbutton:hover {}
.box {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.innerbox {
overflow: scroll;
width: 80%;
height: 80%;
margin: 5% auto;
background-color: white;
border: 3px solid gray;
padding: 10px;
box-shadow: -10px -10px 25px #ccc;
}
#box1 {
position: fixed;
display: none;
width: 400px;
height: 400px;
top: 0;
left: 0;
}
#box2 {
position: fixed;
display: none;
width: 400px;
height: 400px;
top: 0;
left: 0;
}
.closebutton {
width: 20%;
float: right;
cursor: pointer;
}
.closebtn {
text-align: right;
font-size: 20px;
font-weight: bold;
}
.clear {
clear: both;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="builder" action="" method="POST">
<div class="showbutton" id="link1">
click for first items
</div>
<div id="box1" class="box">
<div class="innerbox">
<div class="closebutton">
<div class="closebtn">X</div>
</div>
- item1.png - item2.png - item3.png
</div>
</div>
<div class="showbutton" id="link1">
click for second items
</div>
<div id="box1" class="box">
<div class="innerbox">
<div class="closebutton">
<div class="closebtn">X</div>
</div>
- item1.png - item2.png - item3.png
</div>
</div>
JSFIDDLE example of my codes: https://jsfiddle.net/j5fqhat6/
You can add data attribute to your kutu div this will help us to identify from where click event has been occurred .So, whenever your gosterButonu is been clicked you can use this data-id to add selected images text to your gosterButonu div.
Demo Code :
$(document).ready(function() {
$(".gosterButonu, .gosterButonu img").click(function(event) {
var butonAdi = $(this).attr('id');
console.log(butonAdi)
//if on click of button you want to remove active class
// $("div[data-id="+butonAdi+"]").find("li").removeClass("active")
$("div[data-id=" + butonAdi + "]").fadeIn(300);
});
$(".kapatButonu").click(function() {
var data_id = $(this).closest(".kutu").data("id");
$("#" + data_id).text($(this).closest(".icKutu").find("li.active").text())
$(".kutu").fadeOut(200);
});
$(".kutu").click(function() {
$(".kutu").fadeOut(200);
});
$(".icKutu").click(function() {
event.preventDefault();
event.stopPropagation();
});
//on click of li
$(".images li").click(function() {
//remove active class from other lis
$(this).closest(".images").find("li").not(this).removeClass("active")
//add active class to li which is clicked
$(this).addClass("active");
})
});
div.gosterButonu {}
div.gosterButonu:hover {}
.kutu {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.icKutu {
overflow: scroll;
width: 80%;
height: 80%;
margin: 5% auto;
background-color: white;
border: 3px solid gray;
padding: 10px;
box-shadow: -10px -10px 25px #ccc;
}
#kutu1 {
position: fixed;
display: none;
width: 400px;
height: 400px;
top: 0;
left: 0;
}
#kutu2 {
position: fixed;
display: none;
width: 400px;
height: 400px;
top: 0;
left: 0;
}
.kapatButonuCerceve {
width: 20%;
float: right;
cursor: pointer;
}
.kapatButonu {
text-align: right;
font-size: 20px;
font-weight: bold;
}
.clear {
clear: both;
}
ul li {
list-style-type: none
}
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="builder" action="" method="POST">
<div class="gosterButonu" id="link1">
clickfor first items
</div>
<!--added data-id which matched with the div above-->
<div id="kutu1" data-id="link1" class="kutu">
<div class="icKutu">
<div class="kapatButonuCerceve">
<div class="kapatButonu">X</div>
</div>
<div class="clear"></div>
<!--added ul li-->
<ul class="images">
<li>- item1.png</li>
<li> - item2.png </li>
<li>- item3.png</li>
</ul>
</div>
</div>
<div class="gosterButonu" id="link2">
click for second items
</div>
<!--added data-id which matched with the div above-->
<div id="kutu2" data-id="link2" class="kutu">
<div class="icKutu">
<div class="kapatButonuCerceve">
<div class="kapatButonu">X</div>
</div>
<div class="clear"></div>
<ul class="images">
<li>- item1.png</li>
<li> - item2.png </li>
<li>- item3.png</li>
</ul>
</div>
</div>
I am working on my jquery script to remove the link by replace the text when I click on a button. I have got a problem with the cursor because when I click at the end of the text, it will move the cursor to the start of the text, example: when I click the cursor next to 2!, it will move the cursor at the start before the Video.
When I try this:
if (target.prop("nodeName") == "A") {
unlink(target);
$('#text_editor').focus().val(selected_text);
}
$(function() {
function unlink(link) {
var txt = link.text();
var sp = $("<span>").html(txt);
link.replaceWith(sp);
}
function getObjectFromCursor() {
var obj, sel = window.getSelection() ? window.getSelection() : document.selection;
var range = sel.getRangeAt(0);
obj = $(range.startContainer.parentElement);
return obj;
}
$("#toolbar").on("click", "#toolbar_unlink", function() {
var target = getObjectFromCursor();
if (target.prop("nodeName") == "A") {
unlink(target);
selected_text = window.getSelection().getRangeAt(0).endContainer.wholeText;
$('#text_editor').focus().val(selected_text);
}
})
});
.toolbar_button_unlink_icon {
background-image: url(https://cdn.iconscout.com/icon/premium/png-256-thumb/unlink-1507684-1280083.png);
background-position: center;
background-repeat: no-repeat;
background-size: 20px;
opacity: 0.55;
}
.toolbar_button {
display: inline-block;
height: 26px;
width: 28px;
padding: 4px 6px;
outline: 0;
cursor: default;
float: left;
border: 0;
background-color: #f8f8f8;
position: relative;
}
.toolbar_button:hover {
background-color: #e5e5e5;
border: 1px solid #bcbcbc;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="toolbar" class="toolbar_top" role="toolbar" style="height: 100px; user-select: none;">
<button id="toolbar_unlink" class="toolbar_button toolbar_button_unlink_icon" command="+unlink" data-toggle="tooltip" data-placement="bottom" title="Remove link (CTRL+SHIFT+F9)" style="user-select: none; position: relative; margin-left: 3px; margin-top: 13px; outline: none; z-index: 0;" button="" type="button"></button>
</div>
<div id="text_editor" class="editor_message" hidefocus="false" aria-label="Message Body" g_editable="true" role="textbox" aria-hidden="true" aria-multiline="true" contenteditable="true" tabindex="1" style="direction: ltr; height: 500px; width: 100%; padding-left: 25px; padding-top: 18px; font-size: 16px; border-bottom: 1px solid #d1d1d1; border-right: 1px solid #d1d1d1; border-left: 1px solid #d1d1d1; overflow-y: auto;" itacorner="6,7:1,1,0,0">
<div>Video Here 1!</div>
<div>Video Here 2!<br></div>
<div>Video Here 3!</div>
<div></div>
</div>
Here is the fiddle: https://jsfiddle.net/bL71nasw/
What I want to achieve is when I click on the text "Video Here 1!", "Video Here 2!", "Video Here 3!" or whatever it is and when I click on a button to remove the hyperlink to replace with a text, I want to move the cursor next to the text 2!, 3! or whatever it is.
Can you please show me example how I can move the cursor next to the text 1!, 2!, 3! or whatever it is in the contenteditable?
Thank you.
I have two divs side by side within a parent div - the left div will contain text, while the right div will contain an image, and on button click, the right div can expand, or reduce back to its original width.
<style>
.parent{
width: 100%;
border: 1px solid blue;
padding: 2px;
float: left;
}
.left{
width: 60%;
float: left;
border: 1px solid red;
}
.right{
width: 38%;
border: 1px solid orange;
float: right;
}
</style>
<input type="submit" class="toggle_div" id="button1" value="Expand"/><br>
<div class="parent">
<div class="left">Left Content</div>
<div class="right">Right Content</div>
</div>
javascript to expand/reduce the div:
$("#button1").click(function(){
var inputValue=$("#button1").attr('value');
if(inputValue=="Expand")
{
$(".right").animate({width:"60%"});
$("#button1").attr('value','Reduce');
}
else if(inputValue=="Reduce")
{
$(".right").animate({width:"38%"});
$("#button1").attr('value','Expand');
}
});
Right now, when I increase the width of the right div, it slides underneath the left div. But what I want is for the left div to reduce in size accordingly, and take on the remaining width available within the parent, with left and right div remaining side by side.
JSFiddle
My css is weak, and I'm guessing this is something I can do in css, without having to use javascript to resize the left div too. Suggestions appreciated as always.
Your left div just wasn't being updated with the correct size so your container was more than 100%. I've fixed it here:
$("#button1").click(function(){
var inputValue=$("#button1").attr('value');
if(inputValue=="Expand")
{
$(".right").animate({width:"60%"});
$(".left").animate({width:"38%"});
$("#button1").attr('value','Reduce');
}
else if(inputValue=="Reduce")
{
$(".right").animate({width:"38%"});
$(".left").animate({width:"60%"});
$("#button1").attr('value','Expand');
}
});
.parent{
width: 100%;
border: 1px solid blue;
padding: 2px;
float: left;
}
.left{
width: 60%;
float: left;
border: 1px solid red;
}
.right{
width: 38%;
border: 1px solid orange;
float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="submit" class="toggle_div" id="button1" value="Expand"/><br>
<div class="parent">
<div class="left">Left Content</div>
<div class="right">Right Content</div>
</div>
not really good myself, but maybe something like http://jsfiddle.net/fd9pos8m/ ? not smooth though
<div style="padding:2px; width:500px; background: #FFFFFF ">
<div class="left" style="float:left; width:50%; background: #ff0000 ">Left Content</div>
<div class="right" style="margin-left:52%; width:38%; background: #000000 ">Right</div>
<div style="clear:both"></div>
<input type="button" id="button1" value="expand">
</div>
<script>
$('#button1').click(function(){
var val = $(this).val();
if(val == 'expand') {
$('.right').animate({width:'60%'});
$(this).val('reduce');
} else {
$('.right').animate({width:'38%'});
$(this).val('expand');
}
});
</script>
Here try this does this work? http://jsfiddle.net/CFNUJ/917/ the #right-bg { is staying to the #left-bg
the first is using just css
How about using css flexbox? You don't have to worry about that .left or .right jumps down when there's no enough space for them, it just handles that situation for you.
Do remember to check the browser support for flexbox though.
I only tweaked the css:
.parent{
width: 100%;
border: 1px solid blue;
padding: 2px;
display: flex;
}
.left{
width: 60%;
border: 1px solid red;
}
.right{
width: 38%;
border: 1px solid orange;
}
jsfiddle
http://jsfiddle.net/sen3t6vk/74/
I am trying to build a slide show from scratch. I want to use only javascript, no jquery.
As of now, when I click on the 'prev' button, it only moves 50px to left just once. How do I make it move 50px every time on click of 'prev' button.
Javascript Code :-
function prev() {
document.getElementById('slide').style.left = document.getElementById('slide').style.left - 50;
}
function nxt() {
document.getElementById('slide').style.left = document.getElementById('slide').style.left + 50;
}
HTML :-
<div class="slideshow-wrapper">
<h1>Slide Show</h1>
<div class="slideshow-outside-container">
<div class="slideshow-inner-container" id="slide">
<ul>
<li class="slide slide1"></li>
<li class="slide slide2"></li>
<li class="slide slide3"></li>
<li class="slide slide4"></li>
<li class="slide slide5"></li>
<li class="slide slide1"></li>
<li class="slide slide2"></li>
<li class="slide slide3"></li>
<li class="slide slide4"></li>
<li class="slide slide5"></li>
</ul>
</div>
</div>
<div class="slideshow-controls-wrapper">
<button onclick="prev()" class="prev">Prev</button>
<button onclick="nxt()" class="nxt">Next</button>
</div>
</div>
CSS:-
body{
font-family: 'tahoma', sans-serif;
font-size: 14px;
color: #999999;
background-color: #cccccc;
}
ul{
margin: 0;
padding: 0;
list-style-type: none;
}
ul li{
padding: 0;
display: block;
}
.slideshow-wrapper{
position: relative;
width: 100%;
text-align: center;
}
.slideshow-outside-container h1{
margin-bottom: 30px;
}
.slideshow-outside-container{
position: relative;
display: block;
margin: 0 auto;
padding: 10px;
width: 80%;
height: 150px;
background-color: #ffffff;
overflow: hidden;
}
.slideshow-inner-container{
position: absolute;
top: 12px;
left: 0;
width: 1920px;
height: 140px;
border: 1px solid #000000;
}
.slide{
float: left;
width: 150px;
height: 140px;
margin-right: 20px;
background-color: #eeeeee;
}
.slide1{
background-color: green;
}
.slide2{
background-color: yellow;
}
.slide3{
background-color: red;
}
.slide4{
background-color: blue;
}
.slide5{
background-color: orange;
}
.slideshow-controls-wrapper button{
display: inline-block;
cursor: pointer;
padding: 20px;
}
Your first problem is that the slide element does not have a current value for left, so even parsing it will return NaN and not work. You can parseInt the current value (50px parses to 50), but default it to 0 using ||, then +/- 50.
When you set the value you also need to say which units it is in, in your case 'px'.
You could cache the value in a variable as some people have suggested, but I don't really see the need. Parsing it each time is quick enough, ensures the function does what it is meant to each time and you don't run the risk of the stored value getting out of sync.
function prev() {
var val = (parseInt(document.getElementById('slide').style.left, 10) || 0) - 50;
document.getElementById('slide').style.left = val + 'px';
}
function nxt() {
var val = (parseInt(document.getElementById('slide').style.left, 10) || 0) + 50;
document.getElementById('slide').style.left = val + 'px';
}
Fiddle here
try this
function prev(){
var val=parseint(document.getElementById('slide').style.left) - 50;
document.getElementById('slide').style.left = val+"px";
}
EDIT
This answer have some limitation..