I'm trying to build a carousel in JS that uses an array to store my data.
I want my box on the left to show the value for "Client" and the box on the right to show the value for "Candidate".
I can't seem to get it working despite what I believe is all correct?
let testimonials = [{
client: "Raphel",
candidate: "male"
},
{
client: "Tom",
candidate: "male"
},
{
client: "Jerry",
candidate: "male"
},
{
client: "Dorry",
candidate: "female"
}
];
var i = 0;
function nextItem() {
i = i + 1;
i = i % testimonials.length;
return testimonials[i].candidate;
}
function prevItem() {
if (i === 0) {
i = testimonials.length;
}
i = i - 1;
return testimonials[i].client;
}
window.addEventListener('load', function() {
$('.client-box').html(testimonials[i].client);
$('.candidate-box').html(testimonials[i].candidate);
$('.left-btn').on('click', function(e) {
$('.client-box').html(prevItem());
$('.candidate-box').html(prevItem());
});
$('.right-btn').on('click', function(e) {
$('.client-box').html(nextItem());
$('.candidate-box').html(nextItem());
});
});
https://jsfiddle.net/cL5mok3f/
Fixing the code:
let testimonials = [{
client: "Raphel",
candidate: "male"
},
{
client: "Tom",
candidate: "male"
},
{
client: "Jerry",
candidate: "male"
},
{
client: "Dorry",
candidate: "female"
}
];
var i = 0;
function nextItem() {
i = i + 1;
i = i % testimonials.length;
return testimonials[i];
}
function prevItem() {
if (i === 0) {
i = testimonials.length;
}
i = i - 1;
return testimonials[i];
}
window.addEventListener('load', function() {
$('.client-box').html(testimonials[i].client);
$('.candidate-box').html(testimonials[i].candidate);
$('.left-btn').on('click', function(e) {
var prev = prevItem();
$('.client-box').html(prev.client);
$('.candidate-box').html(prev.candidate);
});
$('.right-btn').on('click', function(e) {
var next = nextItem();
$('.client-box').html(next.client);
$('.candidate-box').html(next.candidate);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="client-box"></div>
<div class="candidate-box"></div>
<input type="button" class="left-btn" value="Prev" />
<input type="button" class="right-btn" value="Next" />
To achieve expected result, use below option
Issue: PrevItem and nextItem methods are called twice on clicking left and right which creates inconsistent carousel
Code sample
let testimonials = [
{client: "Raphel", candidate: "male"},
{client: "Tom", candidate: "male"},
{client: "Jerry", candidate: "male"},
{client: "Dorry", candidate: "female"}
];
var i = 0;
$('.client-box').text(testimonials[0].client);
$('.candidate-box').text(testimonials[1].candidate);
function nextItem() {
i = i + 1;
if (i === testimonials.length) {
i = i % testimonials.length;
}
return testimonials[i];
}
function prevItem() {
if (i === 0) {
i = testimonials.length;
}
i = i - 1;
console.log("prev", i)
return testimonials[i];
}
$('.left-btn').on('click', function(e){
let val = prevItem()
$('.client-box').text(val.client);
$('.candidate-box').text(val.candidate);
});
$('.right-btn').on('click', function(e){
let val = nextItem()
$('.client-box').text(val.client);
$('.candidate-box').text(val.candidate);
});
.testimonial-carousel {
position: relative;
width: 1000px;
}
.testimonial-carousel::after {
content: "";
display: block;
clear: both;
}
.testimonial-carousel .testimonial-box {
width: 500px;
height: 100px;
float: left;
background: #999999;
}
.testimonial-carousel .testimonial-box.candidate-box {
background: white;
margin-top: 2rem;
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
}
.testimonial-carousel .buttons {
position: absolute;
bottom: -60px;
right: 20px;
}
.testimonial-carousel .buttons::after {
content: "";
display: block;
clear: both;
}
.testimonial-carousel .buttons .btn {
background: black;
width: 60px;
height: 60px;
float: left;
margin-right: 5px;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="testimonial-carousel">
<div class="testimonial-box client-box"></div>
<div class="testimonial-box candidate-box"></div>
<div class="buttons">
LEFT
RIGHT
</div>
</div>
codepen - https://codepen.io/nagasai/pen/wLKoVv
Related
How do i stop iterating tough this array at "pgn[46]"?
I want to be unable to go to the next move when i click the button. because this array will start back from 0 and if a piece is on the square it will move again. i need some more text to post this question here. I love you all, peace
$('#move1Btn').on('click', function () {
board.move(pgn[intpgnIndex])
})
var pgn = new Array()
pgn[0] = ""
pgn[1] = "e2-e4"
pgn[2] = "e7-e5"
pgn[3] = "f2-f4"
pgn[4] = "e5-f4"
pgn[5] = "f1-c4"
pgn[6] = "d8-h4"
pgn[7] = "e1-f1"
pgn[8] = "b7-b5"
pgn[9] = "c4-b5"
pgn[10] = "g8-f6"
pgn[11] = "g1-f3"
pgn[12] = "h4-h6"
pgn[13] = "d2-d3"
pgn[14] = "f6-h5"
pgn[15] = "f3-h4"
pgn[16] = "h6-g5"
pgn[17] = "h4-f5"
pgn[18] = "c7-c6"
pgn[19] = "g2-g4"
pgn[20] = "h5-f6"
pgn[21] = "h1-g1"
pgn[22] = "c6-b5"
pgn[23] = "h2-h4"
pgn[24] = "g5-g6"
pgn[25] = "h4-h5"
pgn[26] = "g6-g5"
pgn[27] = "d1-f3"
pgn[28] = "f6-g8"
pgn[29] = "c1-f4"
pgn[30] = "g5-f6"
pgn[31] = "b1-c3"
pgn[32] = "f8-c5"
pgn[33] = "c3-d5"
pgn[34] = "f6-b2"
pgn[35] = "f4-d6"
pgn[36] = "c5-g1"
pgn[37] = "e4-e5"
pgn[38] = "b2-a1"
pgn[39] = "f1-e2"
pgn[40] = "b8-a6"
pgn[41] = "f5-g7"
pgn[42] = "e8-d8"
pgn[43] = "f3-f6"
pgn[44] = "g8-f6"
pgn[45] = "d6-e7"
pgn[46] = ""
pgn[47] = ""
pgn[48] = ""
pgn[49] = ""
var intpgnIndex = 0;
function writeThing() {
if ( intpgnIndex == pgn.length ) intpgnIndex = 0;
intpgnIndex++;
}
I would check the value at the index and see if it is an empty string:
$('#move1Btn').on('click', function () {
var move = pgn[intpgnIndex];
if (move) {
board.move(move);
}
})
Here is a recommended approach:
const initialState = [
{ color: 'black', type: 'king', cells: ['e8'] },
{ color: 'black', type: 'queen', cells: ['d8'] },
{ color: 'black', type: 'rook', cells: ['a8', 'h8'] },
{ color: 'black', type: 'bishop', cells: ['c8', 'f8'] },
{ color: 'black', type: 'knight', cells: ['b8', 'g8'] },
{ color: 'black', type: 'pawn', cells: ['a7', 'b7', 'c7', 'd7', 'e7', 'f7', 'g7', 'h7'] },
{ color: 'white', type: 'king', cells: ['e1'] },
{ color: 'white', type: 'queen', cells: ['d1'] },
{ color: 'white', type: 'rook', cells: ['a1', 'h1'] },
{ color: 'white', type: 'bishop', cells: ['c1', 'f1'] },
{ color: 'white', type: 'knight', cells: ['b1', 'g1'] },
{ color: 'white', type: 'pawn', cells: ['a2', 'b2', 'c2', 'd2', 'e2', 'f2', 'g2', 'h2'] },
];
const moveList = ['e2-e4', 'e7-e5', 'f2-f4', 'e5-f4', 'f1-c4', 'd8-h4', 'e1-f1', 'b7-b5', 'c4-b5', 'g8-f6', 'g1-f3', 'h4-h6', 'd2-d3', 'f6-h5', 'f3-h4', 'h6-g5', 'h4-f5', 'c7-c6', 'g2-g4', 'h5-f6', 'h1-g1', 'c6-b5', 'h2-h4', 'g5-g6', 'h4-h5', 'g6-g5', 'd1-f3', 'f6-g8', 'c1-f4', 'g5-f6', 'b1-c3', 'f8-c5', 'c3-d5', 'f6-b2', 'f4-d6', 'c5-g1', 'e4-e5', 'b2-a1', 'f1-e2', 'b8-a6', 'f5-g7', 'e8-d8', 'f3-f6', 'g8-f6', 'd6-e7'];
const
$board = $('.chess-board'),
$moveInfo = $('.move-info');
let currentIndex = 0;
const currentPlayer = () => currentIndex % 2 === 0 ? 'white' : 'black';
const generateBoard = () => {
for (let i = 0; i < 100; i++) {
const
row = Math.floor(i / 10),
col = i % 10,
isOdd = ((row % 2 === 1) ^ (col % 2 === 0)) === 0,
$cell = $('<div>', { class: 'cell' });
if (row === 0 || row === 9) {
$cell.addClass('boundry');
if (col > 0 && col < 9) {
$cell.attr('data-index', String.fromCharCode(97 + col - 1));
}
} else if (col === 0 || col === 9) {
$cell.addClass('boundry');
if (row > 0 && row < 9) {
$cell.attr('data-index', 9 - row);
}
} else {
const
dr = 10 - row - 1, dc = String.fromCharCode(97 + col - 1),
code = `${dc}${dr}`;
$cell.attr('data-code', code).toggleClass('is-odd', isOdd);
}
$board.append($cell);
}
};
const initializePieces = () => {
initialState.forEach(({ color, type, cells }) => {
cells.forEach(code => {
$board
.find(`.cell[data-code="${code}"]`)
.attr('data-type', type)
.attr('data-color', color);
});
});
};
const resetBoard = () => {
currentIndex = 0;
$board.find('.cell')
.removeAttr('data-color')
.removeAttr('data-type');
initializePieces();
$moveInfo.find('[data-move-index]').text('');
$moveInfo.find('[data-move-value]').text('');
$moveInfo.find('[data-move-atk-color]').text('');
$moveInfo.find('[data-move-atk-type]').text('');
$moveInfo.find('[data-move-def-color]').text('');
$moveInfo.find('[data-move-def-type]').text('');
};
const nextMove = () => {
let move = moveList[currentIndex];
if (!move) {
alert('No more moves, reseting...');
resetBoard();
return;
}
const [from, to] = move.split('-');
const $prev = $board.find(`.cell[data-code="${from}"]`);
const $curr = $board.find(`.cell[data-code="${to}"]`);
const atkColor = $prev.attr('data-color');
const atkType = $prev.attr('data-type');
const defColor = $curr.attr('data-color') || '';
const defType = $curr.attr('data-type') || '';
$moveInfo.find('[data-move-index]').text(currentIndex + 1);
$moveInfo.find('[data-move-value]').text(move);
$moveInfo.find('[data-move-atk-color]').text(atkColor);
$moveInfo.find('[data-move-atk-type]').text(atkType);
$moveInfo.find('[data-move-def-color]').text(defColor);
$moveInfo.find('[data-move-def-type]').text(defType);
$prev.removeAttr('data-color').removeAttr('data-type');
$curr.attr('data-color', atkColor).attr('data-type', atkType);
currentIndex++;
};
generateBoard();
initializePieces();
$('#move-btn').on('click', nextMove);
*, *::before, *::after {
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
align-items: center;
justify-content: center;
gap: 1em;
background: #222;
}
.chess-board {
display: grid;
grid-template-columns: repeat(10, auto);
border: thin solid LightYellow;
}
.cell {
width: 16px;
height: 16px;
font-size: 1rem;
display: flex;
align-items: center;
justify-content: center;
background: LightYellow;
}
.cell.is-odd {
background: LightSalmon;
}
.cell.is-active {
color: green;
}
.cell[data-color="white"] { color: FireBrick }
.cell[data-color="black"] { color: FireBrick }
.cell[data-color="white"][data-type="king"]:after { content: "\2654" }
.cell[data-color="white"][data-type="queen"]:after { content: "\2655" }
.cell[data-color="white"][data-type="rook"]:after { content: "\2656" }
.cell[data-color="white"][data-type="bishop"]:after { content: "\2657" }
.cell[data-color="white"][data-type="knight"]:after { content: "\2658" }
.cell[data-color="white"][data-type="pawn"]:after { content: "\2659" }
.cell[data-color="black"][data-type="king"]:after { content: "\265A" }
.cell[data-color="black"][data-type="queen"]:after { content: "\265B" }
.cell[data-color="black"][data-type="rook"]:after { content: "\265C" }
.cell[data-color="black"][data-type="bishop"]:after { content: "\265D" }
.cell[data-color="black"][data-type="knight"]:after { content: "\265E" }
.cell[data-color="black"][data-type="pawn"]:after { content: "\265F" }
.cell[data-index]:after { content: attr(data-index); }
.cell.boundry { background: FireBrick; color: LightYellow; font-size: smaller; }
.sidebar {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.5rem;
min-width: 10rem;
border: thin solid FireBrick;
padding: 0.5rem;
background: LightYellow;
}
.move-info {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0.25rem;
font-family: monospace;
font-size: smaller;
text-transform: uppercase;
}
.move-info strong { text-align: right; }
.move-info strong:after { content: ":"; }
.move-info .details { display: flex; gap: 0.25rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chess-board"></div>
<div class="sidebar">
<div class="move-info">
<strong>Move</strong>
<div class="details">
<span data-move-index></span>
<span data-move-value></span>
</div>
<strong>Attacker</strong>
<div class="details">
<span data-move-atk-color></span>
<span data-move-atk-type></span>
</div>
<strong>Defender</strong>
<div class="details">
<span data-move-def-color></span>
<span data-move-def-type></span>
</div>
</div>
<button id="move-btn">Next</button>
</div>
I want to implement a chart like below.
But my problem is collision of the numbers in this chart and I couldn't find a suitable solution for this. For example when two or three values are very close together, the collision happens. (the image below)
<template>
<div style="width: 100%">
<div class="box" style="width: 100%">
<div :style="{ left: `${bound1.spaceLeft}%` }" class="box__q1-line" />
<div :style="{ left: `${bound2.spaceLeft}%` }" class="box__q2-line" />
<div :style="{ width: `${theValue.width}%` }" class="box__value" />
</div>
<div class="box__values-container">
<div
v-for="(item, i) in sorted"
:key="i"
class="box__amount"
:style="{ left: `${item.spaceLeft}%` }"
>
{{ item.realValue }}
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from "#vue/composition-api";
function round(number: number) {
return Math.floor(number * 1000) / 1000;
}
export default defineComponent({
setup(props) {
const bound1 = ref({
realValue: 0,
spaceLeft: 0,
});
const bound2 = ref({
realValue: 0,
spaceLeft: 0,
});
const theValue = ref({
realValue: 0,
spaceLeft: 0,
width: 0,
});
const eachWidth = 6;
type ChartData = { realValue: number; spaceLeft: number };
const sorted = ref<Array<ChartData>>();
function compare(obj1: ChartData, obj2: ChartData) {
if (obj1.spaceLeft < obj2.spaceLeft) return -1;
if (obj1.spaceLeft > obj2.spaceLeft) return 1;
return 0;
}
watch(
props,
() => {
bound1.value.realValue = props.q1!;
bound2.value.realValue = props.q2!;
theValue.value.realValue = props.value!;
bound1.value.spaceLeft = round((props.q1! / props.max!) * 100);
bound2.value.spaceLeft = round((props.q2! / props.max!) * 100);
theValue.value.spaceLeft = round((props.value! / props.max!) * 100);
theValue.value.width = round((props.value! / props.max!) * 100);
sorted.value = [bound1.value, bound2.value, theValue.value].sort(
compare
);
if (
sorted.value[1].spaceLeft + eachWidth >
sorted.value[2].spaceLeft
) {
sorted.value[1].spaceLeft = sorted.value[2].spaceLeft - eachWidth;
}
if (
sorted.value[0].spaceLeft + eachWidth >
sorted.value[1].spaceLeft
) {
sorted.value[0].spaceLeft = sorted.value[1].spaceLeft - eachWidth;
}
if (theValue.value.width < 0) theValue.value.width = 3;
if (bound1.value.spaceLeft < 0) bound1.value.spaceLeft = 3;
if (bound2.value.spaceLeft < 0) bound2.value.spaceLeft = 3;
},
{ deep: true, immediate: true }
);
return {
bound1,
bound2,
theValue,
sorted,
};
},
props: {
q1: {
type: Number,
},
q2: {
type: Number,
},
max: {
type: Number,
},
value: {
type: Number,
},
},
});
</script>
<style>
.box {
width: 100%;
height: 50px;
position: relative;
border-radius: 5px;
border: 2px solid #fff;
background: #b8d0de;
overflow: hidden;
}
.box__q1-line,
.box__q2-line {
position: absolute;
width: 2px;
background: #fff;
height: 100%;
}
.box__value {
background: #3c8dbc;
height: 100%;
}
.box__amount {
position: absolute;
width: 60px;
bottom: -25px;
}
.box__values-container {
position: relative;
}
</style>
I considered two thin divs with absolute position for the two lines and I set the left property of them according to their values and another div for the amount and I set the width of it according to its value.
Hello
I have a problem. The problem is, when I move an item to multiple slots it works perfectly.
But when i have two items of the same type, and I put them together it turns into a single item with the value of 2.
But I can't figure out how i could separate that two items into two separate items with the value of one.
if($(this)[0].querySelector('.size').innerText > 1) {
$(this).children().children().html(1);
}
Project: https://codepen.io/KsenonAdv/pen/bGRaRjR
Consider the following example.
$(function() {
function log(string) {
console.log(Date.now(), string);
}
function makeGrid() {
log("Make Grid...");
for (var i = 0; i < 36; i++) {
$("<div>", {
class: "slot"
}).data({
count: 0,
stackable: true
}).appendTo(".slots");
}
log("-* Grid Complete *-");
}
function makeDraggable(target) {
log("Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
$(target).draggable({
scroll: false,
helper: "clone",
cursor: "pointer",
zIndex: 27,
revert: "invalid"
});
log("After Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
}
function refreshSlot(target) {
log("Refresh Slot");
$(".size", target).html($(target).data("count"));
}
function addItem(slot, item) {
log("Add Item " + item.id);
$.extend(item, {
stackable: (item.category != 0),
count: (item.count == undefined ? 1 : item.count)
});
slot = $(slot);
var newItem = $("<div>", {
class: "item",
id: item.id,
})
.data(item)
.css("background-image", "url(" + item.img + ")");
newItem.appendTo(slot);
$("<div>", {
class: "size"
}).appendTo(slot);
slot.data({
count: item.count,
stackable: item.stackable
});
log("Item Added - Refreshing");
refreshSlot(slot);
}
function emptySlot(target) {
log("Empty Slot " + $(target).index());
$(target).data({
count: 0,
stackable: true
}).empty();
}
function loadPlayerItems(items) {
log("Loading Player Items...");
$.each(items, function(index, item) {
addItem($(".slots > .slot").eq(index), item);
});
log("-* Loading Complete *-");
}
function isAcceptable(item) {
if ($(this).children().length == 0 || $(".item", this).data("stackable")) {
return true;
}
return false;
}
var pItems = {
playerItems: [{
img: 'https://i.imgur.com/5cjSI9X.png',
name: 'bat',
id: 1,
category: 0
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 2,
category: 1
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 3,
category: 1
}
]
};
makeGrid();
loadPlayerItems(pItems.playerItems);
makeDraggable(".item");
$(".slots > .slot").droppable({
accept: isAcceptable,
drop: function(event, ui) {
var origin = ui.draggable.parent();
var target = $(this);
log("Drop Accepted; From: " + origin.index() + ", To: " + target.index());
// Increase the Count
target.data("count", target.data("count") + 1);
// Check for Stack
if (target.children().length == 0) {
addItem(target, ui.draggable.data());
} else {
refreshSlot(target);
}
// Check Orginal Stack
if (origin.data("count") > 1) {
origin.data("count", origin.data("count") - 1);
refreshSlot(origin);
} else {
emptySlot(origin);
}
makeDraggable($(".item", this));
}
});
});
body {
display: flex;
justify-content: space-between;
background: url(http://img.playground.ru/images/5/1/GTA5_2015-05-07_00-53-36-07.png);
}
#inventory {
height: 56.25vw;
background: rgba(0, 0, 0, .5);
}
.list-slots {
position: relative;
background: rgba(0, 0, 0, .7);
max-width: 80%;
}
.slots {
max-width: 87%;
margin: auto;
padding-top: 3.125vw;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.slots .slot {
width: 100px;
height: calc(100px + 1em);
background-color: #ccc;
margin-bottom: 0.781vw;
}
.slots .slot .item {
background-repeat: no-repeat;
width: 100px;
height: 100px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="inventory">
<div class="list-slots">
<div class="slots"></div>
</div>
</div>
As discussed in the comment, this updates the Count of items in the Slot by 1. When an items is dragged out, the count is lowered by 1.
To make things easier, I created a number of functions. You may choose to handle it in another manner if you like.
I have a problem
When i move a item on another slot, the item will block, and can't be moved.
Code:
$(function() {
function log(string) {
console.log(Date.now(), string);
}
function makeGrid() {
log("Make Grid...");
for (var i = 0; i < 36; i++) {
$("<div>", {
class: "slot"
}).data({
count: 0,
stackable: true
}).appendTo(".slots");
}
log("-* Grid Complete *-");
}
function makeDraggable(target) {
log("Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
$(target).draggable({
scroll: false,
helper: "clone",
cursor: "pointer",
zIndex: 27,
revert: "invalid"
});
log("After Make Drag, Current Class: " + $(target).attr("class"));
console.log(target);
}
function refreshSlot(target) {
log("Refresh Slot");
$(".size", target).html($(target).data("count"));
}
function addItem(slot, item) {
log("Add Item " + item.id);
$.extend(item, {
stackable: (item.category != 0),
count: (item.count == undefined ? 1 : item.count)
});
slot = $(slot);
var newItem = $("<div>", {
class: "item",
id: item.id,
})
.data(item)
.css("background-image", "url(" + item.img + ")");
newItem.appendTo(slot);
$("<div>", {
class: "size"
}).appendTo(slot);
slot.data({
count: item.count,
stackable: item.stackable
});
log("Item Added - Refreshing");
refreshSlot(slot);
}
function emptySlot(target) {
log("Empty Slot " + $(target).index());
$(target).data({
count: 0,
stackable: true
}).empty();
}
function loadPlayerItems(items) {
log("Loading Player Items...");
$.each(items, function(index, item) {
addItem($(".slots > .slot").eq(index), item);
});
log("-* Loading Complete *-");
}
function isAcceptable(item) {
if ($(this).children().length == 0 || $(".item", this).data("stackable")) {
return true;
}
return false;
}
var pItems = {
playerItems: [{
img: 'https://i.imgur.com/5cjSI9X.png',
name: 'bat',
id: 1,
category: 0
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 2,
category: 1
},
{
img: 'https://i.imgur.com/HLQORBk.png',
name: 'axe',
id: 3,
category: 1
}
]
};
makeGrid();
loadPlayerItems(pItems.playerItems);
makeDraggable(".item");
$(".slots > .slot").droppable({
accept: isAcceptable,
drop: function(event, ui) {
var origin = ui.draggable.parent();
var target = $(this);
log("Drop Accepted; From: " + origin.index() + ", To: " + target.index());
// Increase the Count
target.data("count", target.data("count") + 1);
// Check for Stack
if (target.children().length == 0) {
addItem(target, ui.draggable.data());
} else {
refreshSlot(target);
}
// Check Orginal Stack
if (origin.data("count") > 1) {
origin.data("count", origin.data("count") - 1);
refreshSlot(origin);
} else {
emptySlot(origin);
}
makeDraggable($(".item", this));
}
});
});
body {
display: flex;
justify-content: space-between;
}
#inventory {
width: 100vw;
height: 56.25vw;
background: rgba(0,0,0,.5);
}
.list-slots {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,.7);
width: 41.667vw;
height: 41.667vw;
max-width: 80%;
}
.slots {
max-width: 87%;
margin: auto;
padding-top: 3.125vw;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.slots .slot {
width: 100px;
height: calc(100px + 1em);
background-color: #ccc;
margin-bottom: 0.781vw;
}
.slots .slot .item {
background-repeat: no-repeat;
width: 100px;
height: 100px;
}
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="inventory">
<div class="list-slots">
<div class="slots"></div>
</div>
</div>
Here is my HTLM Page:
<!DOCTYPE html>
<script src="Scripts/knockout-3.4.2.js" type="text/javascript"></script>
<script src="Scripts/jquery-3.1.1.min.js"></script>
<script src="Scripts/knockout.simpleGrid.js"></script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Knockout GridView Örnek</title>
<style>
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; }
.ko-grid { margin-bottom: 1em; width: 25em; border: 1px solid silver; background-color:White; }
.ko-grid th { text-align:left; background-color: Black; color:White; }
.ko-grid td, th { padding: 0.4em; }
.ko-grid tr:nth-child(odd) { background-color: #DDD; }
.ko-grid-pageLinks { margin-bottom: 1em; }
.ko-grid-pageLinks a { padding: 0.5em; }
.ko-grid-pageLinks a.selected { background-color: Black; color: White; }
.liveExample { height:20em; overflow:auto }
li { list-style-type: disc; margin-left: 20px; }
</style>
</head>
<body>
<div data-bind='simpleGrid: gridViewModel'></div>
<div>Ad: </div> <input data-bind="value: Ad" /> <br />
<div>Satılan: </div> <input data-bind="value: Satis" /> <br />
<div>Fiyat: </div> <input data-bind="value: tutar" /> <br />
<button data-bind='click: addItem'>
Add item
</button>
<button data-bind='click: deleteFirst'>Delete first Row</button>
<button data-bind='click: deleteLast'>Delete Last Row</button>
<button data-bind='click: sortByName'>
Sort by name
</button>
<button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
Jump to first page
</button>
</body>
</html>
Here is my JavaScript:
<script type="text/javascript">
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var PagedGridModel = function (items) {
this.items = ko.observableArray(items);
this.sortByName = function () {
this.items.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
};
this.jumpToFirstPage = function () {
this.gridViewModel.currentPageIndex(0);
};
this.deleteFirst = function () {
this.items.shift();
}
this.deleteLast = function () {
this.items.pop();
}
this.removeGift = function (item) {
this.initialData.remove(item);
};
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: 4
});
this.Ad = ko.observable("");
this.Satis = ko.observable("");
this.tutar = ko.observable("");
this.addItem = function () {
if (this.Ad() != "" && this.Satis() != "" && this.tutar() != "") {
this.tutar(Number(this.tutar()));
this.Satis(Number(this.Satis()));
this.items.push({ name: this.Ad(), sales: this.Satis(), price: this.tutar() });
this.Ad("");
this.Satis("");
this.tutar("");
}
}.bind(this);
};
ko.applyBindings(new PagedGridModel(initialData));
</script>
Here is my Grid JS:
(function () {
// Private function
function getColumnsForScaffolding(data) {
if ((typeof data.length !== 'number') || data.length === 0) {
return [];
}
var columns = [];
for (var propertyName in data[0]) {
columns.push({ headerText: propertyName, rowText: propertyName });
}
return columns;
}
ko.simpleGrid = {
// Defines a view model class you can use to populate a grid
viewModel: function (configuration) {
this.data = configuration.data;
this.currentPageIndex = ko.observable(0);
this.pageSize = configuration.pageSize || 5;
// If you don't specify columns configuration, we'll use scaffolding
this.columns = configuration.columns || getColumnsForScaffolding(ko.unwrap(this.data));
this.itemsOnCurrentPage = ko.computed(function () {
var startIndex = this.pageSize * this.currentPageIndex();
return ko.unwrap(this.data).slice(startIndex, startIndex + this.pageSize);
}, this);
this.maxPageIndex = ko.computed(function () {
return Math.ceil(ko.unwrap(this.data).length / this.pageSize) - 1;
}, this);
}
};
// Templates used to render the grid
var templateEngine = new ko.nativeTemplateEngine();
templateEngine.addTemplate = function (templateName, templateMarkup) {
document.write("<script type='text/html' id='" + templateName + "'>" + templateMarkup + "<" + "/script>");
};
templateEngine.addTemplate("ko_simpleGrid_grid", "\
<table class=\"ko-grid\" cellspacing=\"0\">\
<thead>\
<tr data-bind=\"foreach: columns\">\
<th data-bind=\"text: headerText\"></th>\
</tr>\
</thead>\
<tbody data-bind=\"foreach: itemsOnCurrentPage\">\
<tr data-bind=\"foreach: $parent.columns\">\
<td data-bind=\"text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText] \"></td>\
<td>Delete</td>\
</tr>\
</tbody>\
</table>");
templateEngine.addTemplate("ko_simpleGrid_pageLinks", "\
<div class=\"ko-grid-pageLinks\">\
<span>Page:</span>\
<!-- ko foreach: ko.utils.range(0, maxPageIndex) -->\
<a href=\"#\" data-bind=\"text: $data + 1, click: function() { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }\">\
</a>\
<!-- /ko -->\
</div>");
// The "simpleGrid" binding
ko.bindingHandlers.simpleGrid = {
init: function () {
return { 'controlsDescendantBindings': true };
},
// This method is called to initialize the node, and will also be called again if you change what the grid is bound to
update: function (element, viewModelAccessor, allBindings) {
var viewModel = viewModelAccessor();
// Empty the element
while (element.firstChild)
ko.removeNode(element.firstChild);
// Allow the default templates to be overridden
var gridTemplateName = allBindings.get('simpleGridTemplate') || "ko_simpleGrid_grid",
pageLinksTemplateName = allBindings.get('simpleGridPagerTemplate') || "ko_simpleGrid_pageLinks";
// Render the main grid
var gridContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(gridTemplateName, viewModel, { templateEngine: templateEngine }, gridContainer, "replaceNode");
// Render the page links
var pageLinksContainer = element.appendChild(document.createElement("DIV"));
ko.renderTemplate(pageLinksTemplateName, viewModel, { templateEngine: templateEngine }, pageLinksContainer, "replaceNode");
}
};
})();
I want like this
But Delete not working and repeat 3 times always 1 line. I want it 1 Line 1 delete and I want to delete it. How I can do this ? I need your help guys. Thank you in advance.