Trying to write gradient creator javascript and jquery - javascript

Edit: I finally come up with a bit different, but working version. Leaving link here for anyone who may need it in the future: https://jsfiddle.net/qmgob1d5/27/
I'm trying to make a gradient creator, that runs across 16 boxes. (which color values later going to be sent trough POST for server)
I got it working, to a point, Where I can select first and last color and make gradient. However, i couldn't figure out for the life of me, how to add more gradient points. eg: change color of any box and calculate gradient values between 3..4..5..etc points. like on this site: http://www.colorzilla.com/gradient-editor/
Here is fiddle set up with code: https://jsfiddle.net/qmgob1d5/11/
//Fill the gradient array with gray color.
var PaletteColors = Array.apply(null, Array(16)).map(function () { return {red:128, green:128, blue:128}; });
var ActiveBox = 0;
MakeGradient(); //run gradient maker at start
//Remove marker
$('.ColorPreview').contextmenu(function() {
$('#' + $(this).attr('id') ).css('border-bottom','0px');
return false
});
//Add marker and snap sliders to rgb values.
$('.ColorPreview').on('click',function() {
ActiveBox = $(this).attr('id');
ActiveBox = Number(ActiveBox.split('_')[1]);
$('#Color_' + ActiveBox).css('border-bottom','6px solid');
$('#red').val( PaletteColors[ActiveBox].red );
$('#green').val( PaletteColors[ActiveBox].green );
$('#blue').val( PaletteColors[ActiveBox].blue );
});
//Read values from sldier write them to PaletteColors array.
$('.Paletteslider').on('change mousemove',function() {
var red = ($('#red').val());
var green = ($('#green').val());
var blue = ($('#blue').val());
PaletteColors[ActiveBox].red = Number(red);
PaletteColors[ActiveBox].green = Number(green);
PaletteColors[ActiveBox].blue = Number(blue);
MakeGradient();
});
//Draw gradient based on PaletteColors array.
function MakeGradient() {
var FirstColor = PaletteColors[0];
var SecondColor = PaletteColors[15];
var end = 15;
var Count = 1/end;
for (i = 0; i <= end; i++ ) {
var Step = Count * i;
var CurrentRed = SecondColor.red * Step + FirstColor.red * (1 - Step);
var CurrentGreen = SecondColor.green * Step + FirstColor.green * (1 - Step);
var CurrentBlue = SecondColor.blue * Step + FirstColor.blue * (1 - Step);
PaletteColors[i].red = CurrentRed; PaletteColors[i].green = CurrentGreen; PaletteColors[i].blue = CurrentBlue;
$('#Color_' + i ).css('background-color','rgb('+ Math.round(CurrentRed) +','+ Math.round(CurrentGreen) + ',' + Math.round(CurrentBlue) +')');
}
}
any help or direction is welcome!

You can add the functionality you seek by adding trackers to the items in the PaletteColors array (id and edited properties), modifying the functionality of makeGradient, and adding a corresponding modification of edited to the Paletteslider event.
In order for additional markers to be added, you find a way to assess which colors have been modified or are the first/last colors in PaletteColors. I chose to filter an array on conditions if edited is true or the element is the first/last in array. From there, you can assign the values of FirstColor and SecondColor to the first and second color of PaletteColors, respectively.
To change the value of the FirstColor and SecondColor: inside the for loop, check if the id isn't the first or last element and if the SecondColor id equals i, and change the values of FirstColor/SecondColor if so. When assigning the colors to the various elements and creating the gradient, you can check whether i is equal to the FirstColor or SecondColor id property. If it is, use the current color of FirstColor or SecondColor gradient to allow it to show up, otherwise apply your transitional formula. See code snippet below for full working example.
//Fill the gradient array with gray color.
var PaletteColors = Array.apply(null, Array(16)).map(function(item, i) {
return { id: i, color: { red: 128, green: 128, blue: 128 }, edited: false }; });
var ActiveBox = 0;
MakeGradient(); //run gradient maker at start
//Remove marker
$('.ColorPreview').contextmenu(function() {
$('#' + $(this).attr('id')).css('border-bottom', '0px');
return false
});
//Add marker and snap sliders to rgb values.
$('.ColorPreview').on('click', function() {
ActiveBox = Number($(this).data('col'));
$('#Color_' + ActiveBox).css('border-bottom', '6px solid');
$('#red').val(PaletteColors[ActiveBox].color.red);
$('#green').val(PaletteColors[ActiveBox].color.green);
$('#blue').val(PaletteColors[ActiveBox].color.blue);
var a = PaletteColors.filter(function(col, i) {
return col.edited || i === 0 || i === 15;
}).map(function(item, i) {
item.count = i;
return item;
});
});
//Read values from sldier write them to PaletteColors array.
$('.Paletteslider').on('change mousemove', function() {
var red = Number($('#red').val());
var green = Number($('#green').val());
var blue = Number($('#blue').val());
if (!PaletteColors[ActiveBox].edited) {
PaletteColors[ActiveBox].edited = true;
}
PaletteColors[ActiveBox].color.red = red;
PaletteColors[ActiveBox].color.green = green;
PaletteColors[ActiveBox].color.blue = blue;
MakeGradient();
});
//Draw gradient based on PaletteColors array.
function MakeGradient() {
var colors = PaletteColors.filter(function(col, i) {
return col.edited || i === 0 || i === 15;
}).map(function(item, i) {
item.count = i;
return item;
});
var FirstColor = colors[0];
var SecondColor = colors[1];
var end = 15;
var Count = 1 / end;
for (i = 0; i <= end; i++) {
if (colors.length > 2 && i !== 0 && i !== 15 && SecondColor.id === i) {
FirstColor = SecondColor;
SecondColor = colors[SecondColor.count + 1];
}
var Step = Count * i;
var Current = {};
var str;
var match = FirstColor.id === i || SecondColor.id === i ? FirstColor.id === i ? 1 : 2 : false;
if (match) {
Current = match === 1 ? FirstColor.color : SecondColor.color;
} else {
Current.red = Math.round(SecondColor.color.red * Step + FirstColor.color.red * (1 - Step));
Current.green = Math.round(SecondColor.color.green * Step + FirstColor.color.green * (1 - Step));
Current.blue = Math.round(SecondColor.color.blue * Step + FirstColor.color.blue * (1 - Step));
}
PaletteColors[i].color.red = Current.red > 255 ? 255 : Current.red;
PaletteColors[i].color.green = Current.green > 255 ? 255 : Current.green;
PaletteColors[i].color.blue = Current.blue > 255 ? 255 : Current.blue;
str = 'rgb(' + [Current.red, Current.blue, Current.green].join(',') + ')';
$('#Color_' + i).css('background-color', str);
}
}
body, html{
background: #222222;
font-family: 'Lato', sans-serif;
color:white;
}
.ColorPreview {
background: rgb(0,0,0);
float: left;
height: 5em;
width: 6.25%;
border-bottom: 0px solid;
border-color: lightgrey;
}
#Color_0 {border-bottom: 0px solid;}
#Color_1 {border-bottom: 0px solid;}
#Color_2 {border-bottom: 0px solid;}
#Color_3 {border-bottom: 0px solid;}
#Color_4 {border-bottom: 0px solid;}
#Color_5 {border-bottom: 0px solid;}
#Color_6 {border-bottom: 0px solid;}
#Color_7 {border-bottom: 0px solid;}
#Color_8 {border-bottom: 0px solid;}
#Color_9 {border-bottom: 0px solid;}
#Color_10 {border-bottom: 0px solid;}
#Color_11 {border-bottom: 0px solid;}
#Color_12 {border-bottom: 0px solid;}
#Color_13 {border-bottom: 0px solid;}
#Color_14 {border-bottom: 0px solid;}
#Color_15 {border-bottom: 0px solid;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="PreviewTable" >
<div class="ColorPreview" id="Color_0" data-col="0">Color0</div>
<div class="ColorPreview" id="Color_1" data-col="1">Color1</div>
<div class="ColorPreview" id="Color_2" data-col="2">Color2</div>
<div class="ColorPreview" id="Color_3" data-col="3">Color3</div>
<div class="ColorPreview" id="Color_4" data-col="4">Color4</div>
<div class="ColorPreview" id="Color_5" data-col="5">Color5</div>
<div class="ColorPreview" id="Color_6" data-col="6">Color6</div>
<div class="ColorPreview" id="Color_7" data-col="7">Color7</div>
<div class="ColorPreview" id="Color_8" data-col="8">Color8</div>
<div class="ColorPreview" id="Color_9" data-col="9">Color9</div>
<div class="ColorPreview" id="Color_10" data-col="10">Color10</div>
<div class="ColorPreview" id="Color_11" data-col="11">Color11</div>
<div class="ColorPreview" id="Color_12" data-col="12">Color12</div>
<div class="ColorPreview" id="Color_13" data-col="13">Color13</div>
<div class="ColorPreview" id="Color_14" data-col="14">Color14</div>
<div class="ColorPreview" id="Color_15" data-col="15">Color15</div>
</div>
<div>
</div>
<div>
<p>
right click to remove marker
</p>
</div>
<div>
<p>red</p>
<span id="spanHueIndex"></span>
<p> <input class="slider Paletteslider" id="red" type="range" step="1" min="0" max="255" value="0" /></p>
<p>green</p>
<span id="spanSaturationIndex"></span>
<p> <input class="slider Paletteslider" id="green" type="range" step="1" min="0" max="255" value="0" /></p>
<p>blue</p>
<span id="spanLightnessIndex"></span>
<p> <input class="slider Paletteslider" id="blue" type="range" step="1" min="0" max="255" value="0" /></p>
</div>

Related

JS splicing array value according to key value

I have this code below that consists of three different array Red Fruits, Green Fruits and Suggested Fruits I am able to splice and push a single array value from Suggested Fruits to Green Fruits by clicking of the value and vice versa. But now i'm trying to do something different which is using my new Multidimensional Array: fruits to splice and push the value of the suggestFruits array to my red and green fruits array depending on the type e.g. type:1 goes to red fruits table and type:2 goes to green fruits table is there any easy way to accomplish this? Any help would be greatly appreciated!
var red = {};
var green = {};
var random = {};
var fruits = [];
var fruits1 = {["fruit"]:"Apple", ["type"]:"1"}
var fruits2 = {["fruit"]:"Tomato", ["type"]:"1"}
var fruits3 = {["fruit"]:"Lime", ["type"]:"2"}
var fruits4 = {["fruit"]:"Guava", ["type"]:"2"}
fruits.push(fruits1,fruits2,fruits3,fruits4);
console.log(fruits);
var suggestFruits = fruits.filter(x => x.fruit).map(x => x.fruit);
console.log(suggestFruits);
var key = "Red Fruits";
red[key] = ['Apple', 'Cherry', 'Strawberry','Pomegranate','Rassberry'];
var key2 = "Green Fruits";
green[key2] = ['Watermelon', 'Durian', 'Avacado','Lime','Honeydew'];
var key3 = "Random Fruits";
random[key3] = suggestFruits;
function redraw() {
var redString = '';
$.each(red[key], function(index) {
redString += ('<div class="pilldiv redpill class">' + red[key][index] + '</div>');
});
$('.redclass').html(redString);
var greenString = '';
$.each(green[key2], function(index) {
greenString += ('<div class="pilldiv greenpill class">' + green[key2][index] + '</div>');
});
$('.greenclass').html(greenString);
var randomString = '';
$.each(random[key3], function(index) {
randomString += ('<div class="pilldiv randompill class">' + random[key3][index] + '</div>');
});
$('.randomclass').html(randomString);
}
function listener() {
$(document).ready(function() {
$(document).on("click", "#randomid div", function() {
data = this.innerHTML;
k1 = Object.keys(random).find(k => random[k].indexOf(data) >= 0)
index = random[k1].indexOf(data);
random[k1].splice(index, 1);
green[key2].push(data);
$(".total_count_Green_Fruits").html(key2 + ': ' + green[key2].length);
var element = $(this).detach();
$('#greenid').append('<div class="new-green-fruit pilldiv class ">' + element.html() + '</div>');
});
});
$('body').on('click', 'div.new-green-fruit', function() {
data2 = this.innerHTML;
console.log(data2);
k2 = Object.keys(green).find(k => green[k].indexOf(data2) >= 0)
index2 = green[k2].indexOf(data2);
green[k2].splice(index2, 1);
random[key3].push(data2);
$(this).detach();
var element2 = $(this).detach();
$('#randomid').append('<div class="pilldiv randompill class" >' + element2.html() + '</div>');
});
}
redraw();
listener();
.pilldiv {
padding: 8px 15px;
text-align: center;
font-size: 15px;
border-radius: 25px;
color: Black;
margin: 2px;
}
.redpill {
background-color: Pink;
cursor:default;
}
.greenpill {
background-color: SpringGreen;
cursor:default;
}
.randompill {
background-color: LightBlue;
cursor:pointer;
}
.class {
font-family: Open Sans;
}
.center {
display: flex;
justify-content: center;
}
.wrappingflexbox {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.top {
margin-bottom: 20px
}
h3{
font-weight: normal;
}
.panel {
display: table;
height: 100%;
width: 60%;
background-color:white;
border: 1px solid black;
margin-left: auto;
margin-right: auto;
}
.new-green-fruit{
background-color: LightBlue;
cursor:pointer;
}
.top{
margin-bottom:30px;
}
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="//#" />
</head>
<body>
<div class="panel">
<div style="float:left;width:calc(50% - 5px);">
<h3 class="class center">Red Fruits</h3>
<div id="redid" class="redclass wrappingflexbox top"></div>
</div>
<div style="float:right;width:calc(50% - 5px)">
<h3 class="class center">Green Fruits</h3>
<div id="greenid" class="greenclass wrappingflexbox top"></div>
</div>
<div style="clear:both">
<h3 class="center class">Suggested Fruits</h3>
<div id="randomid" class="randomclass wrappingflexbox top"></div>
</div>
</div>
</body>
</html>
There's a lot going on in this question, but from what I gathered, you are simply trying to push the names of the fruits that are type === "1" to the red fruits array, and type === "2" to the green fruits array.
Your main issue with splitting the suggestedFruits into the red and green categories is that when you create the suggestedFruits array, you are losing the type information. What you can do, though, is you can look back at the original fruits array to get the info.
Here's how you can accomplish that:
var fruits = [
{fruit:"Apple", type:"1"},
{fruit:"Tomato", type:"1"},
{fruit:"Lime", type:"2"},
{fruit:"Guava", type:"2"},
];
// map so we can know how to map fruit.type into the correct fruitTypes array
var fruitTypeMap = {"1": "Red Fruits", "2": "Green Fruits"}
// one container for all fruit types so we can access dynamically
var fruitTypes = {
"Red Fruits": ['Apple', 'Cherry', 'Strawberry','Pomegranate','Rassberry'],
"Green Fruits": ['Watermelon', 'Durian', 'Avacado','Lime','Honeydew'],
"Random Fruits": fruits.map(fruit => fruit.fruit)
};
// clone element for easily creating fruit-pills
var clonePill = $(".clone");
// initialize the red/green/random pills
Object.keys(fruitTypes).forEach(key => {
fruitTypes[key].forEach(fruit => {
var $newFruit = clonePill.clone();
// remove clone class so it is visible and doesn't get re-cloned
$newFruit.removeClass("clone");
// set the text
$newFruit.text(fruit);
// append to the correct list in DOM
$(`[data-fruits="${key}"]`).append($newFruit);
});
});
// handler for moving a fruits back and forth
function moveFruit (e) {
// get the category from the data-fruits property on the parent container
var fruitCategory = $(this).parent().data("fruits");
var fruitName = $(this).text();
// detach the fruit element from the DOM and keep it in a variable so we can re-insert later
var $fruit = $(this).detach();
if (fruitCategory === "Random Fruits") {
// get the type number from the original fruits array
var fruitType = fruits.find(fruit => fruit.fruit === fruitName).type;
// find the correct array to place the fruit into
var fruitArr = fruitTypes[fruitTypeMap[fruitType]];
// find the index of the array it is currently in
var fruitIndex = fruitTypes["Random Fruits"].indexOf(fruitName);
// splice out of current array and insert into destination array in 1 line
fruitArr.push(fruitTypes["Random Fruits"].splice(fruitIndex, 1)[0]);
// add movable class so we can toggle it back to Random Fruits on click
$fruit.addClass("movable");
// finally, add to the correct list in the DOM
$(`[data-fruits="${fruitTypeMap[fruitType]}"]`).append($fruit);
}
else {
// find the current array
var fruitArr = fruitTypes[fruitCategory];
// find the index of the fruit in the current array
var fruitIndex = fruitArr.indexOf(fruitName);
// splice out of current array and insert into destination array in 1 line
fruitTypes["Random Fruits"].push(fruitArr.splice(fruitIndex, 1)[0]);
// add back to Random Fruits list
$('[data-fruits="Random Fruits"]').append($fruit);
}
}
// handle click on all fruits that we label as .movable in the red/green lists
$(".red-fruits, .green-fruits").on("click", ".movable", moveFruit);
// handle click on all items in Random Fruits list
$(".random-fruits").on("click", ".fruit-pill", moveFruit);
.clone {
display: none;
}
.fruit-pill {
border-radius: 20px;
padding: 10px 15px;
display: inline-block;
}
.movable {
cursor: pointer;
}
.red-fruits > .fruit-pill {
background-color: rgba(255, 0, 0, 0.6);
}
.red-fruits > .movable {
background-color: rgb(255, 150, 150);
}
.green-fruits > .fruit-pill {
background-color: rgba(0, 255, 0, 0.7);
}
.green-fruits > .movable {
background-color: rgb(200, 255, 175);
}
.random-fruits > .fruit-pill {
background-color: rgba(0, 0, 0, 0.2);
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fruits-container">
<div class="red-fruits" data-fruits="Red Fruits">
</div>
<div class="green-fruits" data-fruits="Green Fruits">
</div>
<div class="random-fruits" data-fruits="Random Fruits">
</div>
</div>
<div class="fruit-pill clone"></div>

How to auto format my textbox in license format?

I tried searching on the internet for answer but the closest I can find is in this jfiddle
What I wanted to do is when the page loads, the textbox is automatically filled with this words Furniture/Chair/Square. In addition, the user can input some text next to the words like this Furniture/Chair/Square/_ _ _/_ _ _. The user cannot erase the automatically filled words.
This is a work around with some reference from jwa's post and RegEx:
$(function() {
$('label.prefilled input[type="text"][placeholder]').on('input', function() {
var fmt = this.placeholder.split('');
var len = this.placeholder.match(/_/g).length;
var val = this.value.replace(/[^a-z]/gi, '').split('').slice(0, len);
var res = '',
v, f;
while ((v = val.shift()) && (f = fmt.shift())) {
if ('_' === f) {
res += v;
} else {
res += f + v;
fmt.shift();
}
}
res += fmt.join('');
this.value = res;
}).trigger('input');
});
label.prefilled input[type="text"] {
border: none;
outline: none;
}
label.prefilled {
border: 1px ridge gray;
}
div.card {
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card">
<label class='prefilled'>
Furniture/Chair/Square/<input type="text" placeholder="___/___"/>
</label>
</div>
<div class="card">
<label class='prefilled'>
Electronic/Handheld/<input type="text" placeholder="______/______"/>
</label>
</div>
How do I include numbers?
Use [^a-z0-9] in this line this.value.replace(/[^a-z]/gi, '')
$(function() {
$('label.prefilled input[type="text"][placeholder]').on('input', function() {
var fmt = this.placeholder.split('');
var len = this.placeholder.match(/_/g).length;
var val = this.value.replace(/[^a-z0-9]/gi, '').split('').slice(0, len);
var res = '',
v, f;
while ((v = val.shift()) && (f = fmt.shift())) {
if ('_' === f) {
res += v;
} else {
res += f + v;
fmt.shift();
}
}
res += fmt.join('');
this.value = res;
}).trigger('input');
});
label.prefilled input[type="text"] {
border: none;
outline: none;
}
label.prefilled {
border: 1px ridge gray;
}
div.card {
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card">
<label class='prefilled'>
Furniture/Chair/Square/<input type="text" placeholder="___/___"/>
</label>
</div>
<div class="card">
<label class='prefilled'>
Electronic/Handheld/<input type="text" placeholder="______/______"/>
</label>
</div>
You can do this by assigning a label to the input field you create. For example...
#text-input {
border: none;
outline: none;
}
label{
border:solid 1px black;
padding-right: 2px;
}
<label for="text-input">
furniture chair square
<input type="text" id="text-input" />
</label>
Use RegExp to solve your problem.
You may add some css or addition text to notice the user error input.
function checkStr(str){
//check pattern
result = str.match(/^Furniture\/Chair\/Square([a-zA-Z\/]+)?/)
if(result == null || result[0].length !== str.length){
//revert the input field to default
document.getElementById('userText').value = "Furniture/Chair/Square"
}
}
<input type="text" value="Furniture/Chair/Square" id="userText" oninput="checkStr(value)"></input>
<p id='asd'></p>

How to shift pictures on click using jQuery

I am trying to shift my pictures to the left using jQuery. I am using a while statement to change all pictures. Here is my code:
<script language="javascript">
$(function() {
$("#leftButton").click(function() {
var imglength = $("#content").children("img").length;
var iterations = imglength;
var lastimg = imglength-1;
var nextimg = lastimg-1;
var start = 1;
var text = "";
document.getElementById("Number").innerHTML="The number of pictures is " + imglength;
document.getElementById("Number1").innerHTML="The index of the last image is " + lastimg;
while (start < iterations)
{
var last = $("img:eq('lastimg')").attr("src");
var next = $("img:eq('nextimg')").attr("src");
text += "<br>Iteration: " + imgindex + " and nextimg is:" +nextimg;
$("img:eq('lastimg')").attr('src', next);
start++;
nextimg--;
}
document.getElementById("Number2").innerHTML = text;
})
})
</script>
HTML is here:
Imgae Shift
Left Shift
Pictures
<p id="Number">Number</p>
<p id="Number1">Number</p>
<p id="Number2">Number</p>
<div id="result"></div>
</section>
</section>
<footer>
© Matthew King: 2015, Birmingham, AL 35211
</footer>
</body>
</html>
It might be easier to simply append the first image back to its parent. This should remove it and add it back as the last child. In the demo, each image has a border so you can see what is happening. I am guessing this is what you are after, but if not let me know.
function slideKittens(){
var first = document.querySelector("#kittens > img");
first.parentNode.appendChild(first);
}
setInterval(slideKittens, 1 * 1000);
#kittens img {
border: solid 2px black;
margin: 2px;
padding: 0px;
display: inline-block;
float: left;
}
<div id="kittens" style="overflow: hidden; width:333px; height: 108px">
<img src="http://placekitten.com/100/100" style="border-color: black;" />
<img src="http://placekitten.com/100/100" style="border-color: red;" />
<img src="http://placekitten.com/100/100" style="border-color: green;" />
<img src="http://placekitten.com/100/100" style="border-color: blue;" />
</div>
The problem is that you do not use the variables correctly.
The lines
var last = $("img:eq('lastimg')").attr("src");
var next = $("img:eq('nextimg')").attr("src");
$("img:eq('lastimg')").attr('src', next);
should be
var last = $("img:eq('" + lastimg + "')").attr("src");
var next = $("img:eq('" + nextimg+ "')").attr("src");
$("img:eq('" + lastimg +"')").attr('src', next);

How to check if element is in viewport (div, no window)

Is there any way to check if specified html element is in viewport - no window but specified div? I found only one meaningful solution but I can't make it work for me.
According to this question Check if element is visible in div
I created a example here: http://jsfiddle.net/jm91n80u/
This is my html code:
<body style="overflow:hidden;">
<div id="outer" style="position:absolute;left:150px;top:20px;right:100px;bottom:30px;overflow:hidden;border:1px solid blue;">
<div id="inner" style="position:relative;height:300px;border:1px solid red;width:100px;overflow-y:auto;overflow-x:hidden;">
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">1</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">2</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">3</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;background:yellow;" class="test" id="id1">4</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">5</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">6</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">7</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">8</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">9</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">10</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">11</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">12</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">13</div>
<div style="position:relative;width:100%;height:30px;border:1px solid grey;" class="test">14</div>
</div>
</div>
<div id="result" style="position:absolute;bottom:0px;overflow:hidden;border:1px solid black;height:20px;width:100%;"></div>
</body>
This is a js function
$(document).ready(function () {
$.belowthefold = function (lookIn, elements, settings) {
var fold = $(lookIn).height() + $(lookIn).scrollTop();
return $(elements).filter(function () {
return fold <= $(this).offset().top - settings.threshold;
});
};
$.abovethetop = function (lookIn, elements, settings) {
var top = $(lookIn).scrollTop();
return $(elements).filter(function () {
return top >= $(this).offset().top + $(this).height() - settings.threshold;
});
};
$.rightofscreen = function (lookIn, elements, settings) {
var fold = $(lookIn).width() + $(lookIn).scrollLeft() + $(lookIn).offset().width;
return $(elements).filter(function () {
return fold <= $(this).offset().left - settings.threshold;
});
};
$.leftofscreen = function (lookIn, elements, settings) {
var left = $(lookIn).scrollLeft();
return $(elements).filter(function () {
return left >= $(this).offset().left + $(this).width() - settings.threshold;
});
};
$("#inner").scrollTop(100);
var b = $.belowthefold("#inner", ".test", { threshold: 0 }).toArray();
var t = $.abovethetop("#inner", ".test", { threshold: 0 }).toArray();
var r = $.rightofscreen("#inner", ".test", { threshold: 0 }).toArray();
var l = $.leftofscreen("#inner", ".test", { threshold: 0 }).toArray();
var el = $("#id1")[0];
var bS = "below the fold : ";
for (var i = 0; i < b.length; i++) {
bS += $(b[i]).html() + ",";
}
var tS = "above the top : ";
for (var i = 0; i < t.length; i++) {
tS += $(t[i]).html() + ",";
}
var rS = "right of screen : ";
for (var i = 0; i < r.length; i++) {
rS += $(r[i]).html() + ",";
}
var lS = "left of screen : ";
for (var i = 0; i < l.length; i++) {
lS += $(l[i]).html() + ",";
}
console.log(bS);
console.log(tS);
console.log(rS);
console.log(lS);
});
What I'm trying to do is get all '.test' elements which are currently invisible (or partial invisible in target solution, any switch will be appreciated) in inner container with information about their position. The result of this should be:
below the fold : 13, 14
above the top : 1,2,3,4
right of screen :
left of screen :
But in this particular case those functions doesn't work. I tried use several other solutions, but each one treats viewport as window.
Can you explain what am I doing wrong? Any help will be appreciated.
You should compare div's positions to: viewport size and windows bounds.
Roughly : if(div.top > (window.top + viewport.height )) {/*this is visible*/} else {/*this is not visible*/}
You could even make it more specific (how much area of div ?)
if((div.top **+ 50% of div.height**) > (window.top + viewport.height )) {/*this is visible*/}
This post gives some codes Check if element is between 30% and 60% of the viewport
$(document).ready(function() {
// Get viewport height, gridTop and gridBottom
var windowHeight = $(window).height(),
gridTop = windowHeight * .3,
gridBottom = windowHeight * .6;
$(window).on('scroll', function() {
// On each scroll check if `li` is in interested viewport
$('ul li').each(function() {
var thisTop = $(this).offset().top - $(window).scrollTop(); // Get the `top` of this `li`
// Check if this element is in the interested viewport
if (thisTop >= gridTop && (thisTop + $(this).height()) <= gridBottom) {
$(this).css('background', 'red');
} else {
$(this).css('background', 'gray');
}
});
});
});

jQuery how to auto adjust the number list when 1 of the list is removed?

I want to automatically adjust the number list that was created using .append(). Example, if there are 4 items added on the list which will numbered from 2-4 respectively and if I removed item number 3, the item number 4 will automatically be number 3 and if I add a new item, it will be the last on the list. Here's my code below.
$('#display').click(function() {
$('#show').show();
});
var c = 1;
$('#append').click(function() {
var cnt = $('.cnt').val();
for (var i = 0; i < cnt; i++) {
c++;
$('#inputs').append("<div id='inputs' name='" + c + "'>" + c + ".)<button id='remove' name='" + c + "'>X</button></div>");
}
});
$(document).on('click', '#inputs #remove', function() {
var nm = $(this).attr('name');
$('div[name="' + nm + '"]').remove();
c--;
});
#show {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/igorescobar/jQuery-Mask-Plugin/master/src/jquery.mask.js"></script>
<button id='display'>Display</button>
<div id='show'>
<br>
<input type='text' class='cnt' value='1' placeholder="num of append" />
<button id='append'>+</button>
<br>
<div id='inputs'>
1.)
</div>
</div>
Here is the jsfiddle of the code.
here is your answer
Fiddle Here
$('#display').click(function() {
$('#show').show();
});
var c = 1;
$('#append').click(function() {
var cnt = $('.cnt').val();
for (var i = 0; i < cnt; i++) {
c++;
$('#inputs').append("<div class='inputs' name='" + c + "'><span class='number'>" +c + "</span>.)<button class='remove' name='" + c + "'>X</button></div>");
}
});
$(document).on('click', '#inputs .remove', function() {
var nm = $(this).attr('name');
$('div[name="' + nm + '"]').remove();
c--;
resetCount();
});
function resetCount(){
$('#inputs div.inputs').each(function(i){
$('.number', $(this)).text(i+2);
$('input', $(this)).attr('name', i+2);
});
}
#remain,
#total {
background-color: #333;
width: 60px;
height: 20px;
color: #fff;
padding: 0 10px;
}
input:focus {
background-color: #000;
color: #fff;
}
input {
background-color: #ccc;
}
#show {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id='display'>Display</button>
<div id='show'>
<br>
<input type='text' class='cnt' value='1' placeholder="num of append" />
<button id='append'>+</button>
<br>
<div id='inputs'>
1.)
</div>
</div>
You should not be using the same ID for different elements
Also the way you could do this is by creating a function that resets the elements counting after each add/delete event
When creating and appending elements in jQuery its better to use this syntax:
$('<ELEMENT TAG/>',{
ATTRIBUTE: VALUE
});
When looping through elements in jQuery its better to use $.each
$('#append').on('click', function(){
$('<div/>', {
'class': 'inputs',
html: '<span class="count"></span><input type="text" class="time" name="0" value="00:00:00"/><button>X</button>'
}).appendTo('#inputs');
resetInputsCount();
});
$('#inputs').on('click', '.inputs button', function(){
var $this = $(this);
$this.parent().remove();
resetInputsCount();
});
//The function that resets the count span text and the name value based on the current count of elements
function resetInputsCount(){
//looping through elements
$('#inputs div.inputs').each(function(i){
//caching the current element in a var named $this
var $this = $(this);
//changing the count span text to i+2 the 2 is added because the index starts at 0 and there is already one element 1.)
$('.count', this).text((i+2) + '.) ');
//change the value of the input name
$('input', $this).attr('name', i+2);
});
}
Demo on JSFiddle
I know theres an answer already but since I did the work I might as well post it.
Here's the fiddle for the example
here's the code:
Html
<div id='button'>
<span>Add</span>
</div>
<div id='content'></div>
CSS
#button span {
padding: 5px 15px;
background: #ccc;
cursor: pointer;
}
#button {
margin: 5px 0;
}
.delete {
cursor: pointer;
padding: 0 5px;
border: 1px solid gray;
}
jQuery
$(document).ready(function() {
var index = 1;
$('#button').on('click', function() {
var add = '<div class="new"><span class="number">' + index + '</span><input type="text"/><span class="delete">x</span></div>';
$('#content').append(add);
index++;
});
$(document).on('click', '.delete', function() {
index--;
$(this).parent().remove();
var index2 = 1;
var newelement = $('.new');
$(newelement).each(function() {
$(this).find('.number').text(index2);
index2++;
});
});
});
Using your html structure and adding some input fields (to be sure we maintain values)
Here is my approach:
(Also fixed duplicate id and names you have)
$('#display').click(function() {
$('#show').show();
});
var c = 1;
var inputs = [];
$('#append').click(function() {
var cnt = $('.cnt').val();
for (var i=0; i<cnt; i++) {
c++;
$div = $("<div id='input"+c+"' />").data('index', c);
$span = $("<span />").text(c+".)");
$button = $("<button class='input_remove' />").text("X");
$input = $("<input type='text' class='small' />").attr("name","input"+c);
$div.append($div).append($span).append($input).append($button);
$('#inputs').append($div);
}
});
$(document).on('click', '.input_remove', function() {
index = $(this).parent().data('index');
$("#inputs").find('#input'+index).remove();
c = 1;
$("#inputs").find('div').each(function(index,ele){
c++;
$(ele).attr('id',"input"+c).data('index',c)
.find("span").text(c+".)").end()
.find("input").attr("name","input"+c);
});
});
#show {
display: none;
}
.small { width:100px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/igorescobar/jQuery-Mask-Plugin/master/src/jquery.mask.js"></script>
<button id='display'>Display</button>
<div id='show'>
<br>
<input type='text' class='cnt' value='1' placeholder="num of append" />
<button id='append'>+</button>
<br>
<div id='inputs'>
1.)
</div>
</div>

Categories

Resources