how to dynamically resize text in a vue component - javascript

I have built an application with different widgets you can drop into a dashboard. Each widget contains a component that a user would like to see (kind of like grafana if you've ever seen it).
Question: When the user drags the grid-item to increase or decrease the size, how do you update the html inside of my component to adjust to the size of the new item?
What I've tried:
attempted to wrap the p tags in an SVG and use viewport.
attempted to change my size to VW to dynamically scale by the viewport but the viewport is not of the component but of the entire spa.
I attempted to get the parent size using this.$parent and did some math to get the text size and dynamically assign it to a component but this was very messy. Also, the sizes displayed were not right.
Below is my code for my grid using the vue-grid-layout package
<grid-layout
ref="widgetGrid"
:layout.sync="widgets"
:col-num="12"
:row-height="verticalSize"
:is-draggable="editable"
:is-resizable="editable"
:is-mirrored="false"
:responsive="true"
:autoSize="editable"
:prevent-collision="false"
:vertical-compact="false"
:margin="[10, 10]"
:use-css-transforms="true"
#layout-updated="layoutUpdatedEvent"
>
<grid-item
:ref="`widget_${widget.i}`"
v-for="widget in widgets"
:key="widget.i"
:x="widget.x"
:y="widget.y"
:w="widget.w"
:h="widget.h"
:i="widget.i"
:static="!editable"
>
<template>
<component
:is="widget.WidgetType"
:setup="false"
:widgetConfig="widget.WidgetConfig"
></component>
</template>
</grid-item>
</grid-layout>
My component that I'm trying to resize the text for is below. It's a vue file and I've included styling.
<template>
<div>
<div id="clock">
<p class="date">{{ date }}</p>
<p class="time">{{ time }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
time: '',
date: '',
week: ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'],
ticker: null
};
},
created() {
this.ticker = setInterval(this.updateTime, 1000);
},
mounted() {
this.showDate =
this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowDate').Value ||
false;
this.showTime =
this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowTime').Value ||
false;
},
methods: {
updateTime() {
let cd = new Date();
this.time =
this.zeroPadding(cd.getHours(), 2) +
':' +
this.zeroPadding(cd.getMinutes(), 2) +
':' +
this.zeroPadding(cd.getSeconds(), 2);
this.date =
this.zeroPadding(cd.getFullYear(), 4) +
'-' +
this.zeroPadding(cd.getMonth() + 1, 2) +
'-' +
this.zeroPadding(cd.getDate(), 2) +
' ' +
this.week[cd.getDay()];
},
zeroPadding(num, digit) {
let zero = '';
for (let i = 0; i < digit; i++) {
zero += '0';
}
return (zero + num).slice(-digit);
}
},
};
</script>
<style lang="scss" scoped>
html,
body {
height: 100%;
}
body {
background: #0f3854!important;
background: radial-gradient(ellipse at center, #0a2e38 0%, #000000 70%)!important;
background-size: 100%;
}
p {
margin: 0;
padding: 0;
}
#clock {
font-family: 'Share Tech Mono', monospace;
color: #ffffff;
text-align: center;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: #daf6ff;
text-shadow: 0 0 20px rgba(10, 175, 230, 1), 0 0 20px rgba(10, 175, 230, 0);
.time {
letter-spacing: 0.05em;
font-size: 1vw;
padding: 5px 0;
}
.date {
letter-spacing: 0.1em;
font-size: 1vw;
}
.text {
letter-spacing: 0.1em;
font-size: 1vw;
padding: 20px 0 0;
}
}
</style>
Nuxt Config
module.exports = {
head: {
titleTemplate: '',
title: 'QVue',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'QVue Web UI' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
css: [],
plugins: [
{ src: '#/plugins/vueGrid', ssr: false }
],
publicRuntimeConfig: {},
privateRuntimeConfig: {},
components: true,
buildModules: [
'#nuxtjs/vuetify'
],
modules: [
'#nuxtjs/axios'
],
axios: {
},
build: {
},
render: {
compressor: false,
},
srcDir: 'client/',
};

If you'd like to resize the text size for your clock component, one solution is uses svg -> viewbox the one you already mentioned. But you need to use <text> instead of <p>.
Below is the demo:
Vue.component('v-clock',{
template:`
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<text x="0" y="25" fill="red">{{date}}</text>
<text x="0" y="75" fill="red">{{time}}</text>
</svg>
`,
data() {
return {
time: '',
date: '',
week: ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'],
ticker: null
};
},
created() {
this.ticker = setInterval(this.updateTime, 1000);
},
mounted() {
this.showDate =
this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowDate').Value ||
false;
this.showTime =
this.widgetConfig?.Settings?.find((x) => x.Key === 'ShowTime').Value ||
false;
},
methods: {
updateTime() {
let cd = new Date();
this.time =
this.zeroPadding(cd.getHours(), 2) +
':' +
this.zeroPadding(cd.getMinutes(), 2) +
':' +
this.zeroPadding(cd.getSeconds(), 2);
this.date =
this.zeroPadding(cd.getFullYear(), 4) +
'-' +
this.zeroPadding(cd.getMonth() + 1, 2) +
'-' +
this.zeroPadding(cd.getDate(), 2) +
' ' +
this.week[cd.getDay()];
},
zeroPadding(num, digit) {
let zero = '';
for (let i = 0; i < digit; i++) {
zero += '0';
}
return (zero + num).slice(-digit);
}
}
})
new Vue ({
el:'#app',
data () {
return {
size: 100
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<input v-model.number="size" type="range" min="50" max="500"/>
<div :style="{width: size + 'px', height: size + 'px'}" style="border: solid 1px blue">
<v-clock></v-clock>
</div>
</div>

Related

How to implement a simple box plot chart with javascript and css?

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.

jQuery UI Droppable items

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.

jquery UI inventory items block after move slot

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>

how can we display different legends container for same graph(sunburst drill down)? in Amcharts4

I was trying to add two legends containers for the same graph(sunburst drill-down). one on the left side and another on the right side of the graph.
After lots of research, I found the solution but it was for piechart not for sunburst drill down. I want the same solution for sunburst drill down.
Below is the Image of the solution which I found.
enter image description here
code for above image:
Js, CSS, HTML
/**
* ---------------------------------------
* This demo was created using amCharts 4.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v4/
* ---------------------------------------
*/
am4core.useTheme(am4themes_animated);
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.PieChart);
// Add data
chart.data =
[{
"country": "Lithuania",
"litres": 501.9
}, {
"country": "Czechia",
"litres": 301.9
}, {
"country": "Ireland",
"litres": 201.1
}, {
"country": "Germany",
"litres": 165.8
}, {
"country": "Australia",
"litres": 139.9
}, {
"country": "Austria",
"litres": 128.3
}, {
"country": "UK",
"litres": 99
}, {
"country": "Belgium",
"litres": 60
}, {
"country": "The Netherlands",
"litres": 50
}];
// Add and configure Series
var pieSeries = chart.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "litres";
pieSeries.dataFields.category = "country";
pieSeries.labels.template.disabled = true;
radius = am4core.percent(95);
chart.legend = new am4charts.Legend();
chart.legend.position = "left";
chart.legend.scrollable = true;
// Create custom legend
chart.events.on("ready", function(event) {
// populate our custom legend when chart renders
chart.customLegend = document.getElementById('legend');
pieSeries.dataItems.each(function(row, i) {
var color = chart.colors.getIndex(i);
var percent = Math.round(row.values.value.percent * 100) / 100;
var value = row.value;
legend.innerHTML += '<div class="legend-item" id="legend-item-' + i + '" onclick="toggleSlice(' + i + ');" onmouseover="hoverSlice(' + i + ');" onmouseout="blurSlice(' + i + ');" style="color: ' + color + ';"><div class="legend-marker" style="background: ' + color + '"></div>' + row.category + '<div class="legend-value">' + value + ' | ' + percent + '%</div></div>';
});
});
function toggleSlice(item) {
var slice = pieSeries.dataItems.getIndex(item);
if (slice.visible) {
slice.hide();
}
else {
slice.show();
}
}
function hoverSlice(item) {
var slice = pieSeries.slices.getIndex(item);
slice.isHover = true;
}
function blurSlice(item) {
var slice = pieSeries.slices.getIndex(item);
slice.isHover = false;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 530px;
height: 450px;
font-size: 11px;
border: 1px solid #eee;
float: left;
}
#legend {
width: 200px;
height: 450px;
border: 1px solid #eee;
margin-left: 10px;
float: left;
}
#legend .legend-item {
margin: 10px;
font-size: 15px;
font-weight: bold;
cursor: pointer;
}
#legend .legend-item .legend-value {
font-size: 12px;
font-weight: normal;
margin-left: 22px;
}
#legend .legend-item .legend-marker {
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #ccc;
margin-right: 10px;
}
#legend .legend-item.disabled .legend-marker {
opacity: 0.5;
background: #ddd;
}
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
<div id="legend"></div>
I tried to solve my problem with the above solution but it didn't work.
Below are the details for my changes :
enter image description here
/**
* ---------------------------------------
* This demo was created using amCharts 4.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v4/
* ---------------------------------------
*/
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// create chart
var chart = am4core.create("chartdiv", am4plugins_sunburst.Sunburst);
chart.padding(0, 0, 0, 0);
chart.radius = am4core.percent(98);
data1 = [{
name: "First",
children: [
{ name: "A1", value: 100 },
{ name: "A2", value: 60 }
]
},
{
name: "Second",
children: [
{ name: "B1", value: 135 },
{ name: "B2", value: 98 }
]
},
{
name: "Third",
children: [
{
name: "C1",
children: [
{ name: "EE1", value: 130 },
{ name: "EE2", value: 87 },
{ name: "EE3", value: 55 }
]
},
{ name: "C2", value: 148 },
{
name: "C3", children: [
{ name: "CC1", value: 53 },
{ name: "CC2", value: 30 }
]
},
{ name: "C4", value: 26 }
]
},
{
name: "Fourth",
children: [
{ name: "D1", value: 415 },
{ name: "D2", value: 148 },
{ name: "D3", value: 89 }
]
},
{
name: "Fifth",
children: [
{
name: "E1",
children: [
{ name: "EE1", value: 33 },
{ name: "EE2", value: 40 },
{ name: "EE3", value: 89 }
]
},
{
name: "E2",
value: 148
}
]
}];
let dt1 = [];
for(var i=0;i<data1.length;i++){
dt1[i] = {"name":data1[i].name,"fill":"#72A6B2"};
}
chart.data = data1;
chart.colors.step = 2;
chart.fontSize = 11;
chart.innerRadius = am4core.percent(20);
// define data fields
chart.dataFields.value = "value";
chart.dataFields.name = "name";
chart.dataFields.children = "children";
var level0SeriesTemplate = new am4plugins_sunburst.SunburstSeries();
chart.seriesTemplates.setKey("0", level0SeriesTemplate)
// this makes labels to be hidden if they don't fit
level0SeriesTemplate.labels.template.truncate = true;
level0SeriesTemplate.labels.template.hideOversized = true;
level0SeriesTemplate.showOnInit = false;
level0SeriesTemplate.usePercentHack = false;
level0SeriesTemplate.radius = am4core.percent(100);
level0SeriesTemplate.innerRadius = am4core.percent(0);
let selectedState = level0SeriesTemplate.states.create("selected");
selectedState.properties.opacity = 0.7;
level0SeriesTemplate.defaultState.properties.radius = am4core.percent(100);
var currentlySelected;
level0SeriesTemplate.slices.template.events.on("over", function(event) {
if(event.target.dataItem.sunburstDataItem.children){
event.target.cursorOverStyle = am4core.MouseCursorStyle.pointer;
}
})
level0SeriesTemplate.slices.template.events.on("hit", function(event) {
zoomOutButton.show();
var hitSlice = event.target;
if (hitSlice.dataItem.sunburstDataItem.children) {
var series = event.target.dataItem.component;
if (!series.dummyData) {
series.tooltip.disabled = true;
hitSlice.dataItem.label.radius = (hitSlice.radius - hitSlice.pixelInnerRadius) - 7;
hitSlice.dataItem.label.bent = true;
hitSlice.dataItem.label.rotation = -180;
currentlySelected = hitSlice;
series.dummyData = true;
series.setState("selected");
hitSlice.dataItem.sunburstDataItem.series.show();
series.slices.each(function(slice) {
if (slice != event.target) {
slice.dataItem.hide();
}
})
}
else {
drillUp(hitSlice);
}
}
})
level0SeriesTemplate.labels.template.adapter.add("rotation", function(rotation, target) {
target.maxWidth = target.dataItem.slice.radius - target.dataItem.slice.innerRadius - 10;
target.maxHeight = Math.abs(target.dataItem.slice.arc * (target.dataItem.slice.innerRadius + target.dataItem.slice.radius) / 2 * am4core.math.RADIANS);
return rotation;
})
var level1SeriesTemplate = level0SeriesTemplate.clone();
level1SeriesTemplate.hidden = true;
level1SeriesTemplate.innerRadius = am4core.percent(10);
chart.seriesTemplates.setKey("1", level1SeriesTemplate)
level1SeriesTemplate.fillOpacity = 0.75;
var level2SeriesTemplate = level0SeriesTemplate.clone();
level2SeriesTemplate.hidden = true;
level2SeriesTemplate.innerRadius = am4core.percent(20);
chart.seriesTemplates.setKey("2", level2SeriesTemplate)
level0SeriesTemplate.hiddenInLegend = false;
level1SeriesTemplate.hiddenInLegend = true;
level2SeriesTemplate.hiddenInLegend = true;
var zoomOutButton = chart.seriesContainer.createChild(am4core.ZoomOutButton);
zoomOutButton.visible = false;
zoomOutButton.horizontalCenter = "middle";
zoomOutButton.verticalCenter = "middle";
zoomOutButton.events.on("hit", function() {
drillUp(currentlySelected)
})
function drillUp(slice) {
collapse(slice);
var series = slice.dataItem.component;
series.tooltip.disabled = false;
series.dummyData = false;
series.setState("default");
series.slices.each(function(slice) {
if (slice != event.target) {
slice.dataItem.show();
}
})
if (series.parentDataItem.seriesDataItem) {
currentlySelected = series.parentDataItem.seriesDataItem.slice;
}
else {
zoomOutButton.hide();
}
}
function collapse(slice) {
slice.dataItem.label.bent = false;
slice.dataItem.label.radius = 10;
if (slice.dataItem.sunburstDataItem.children) {
slice.dataItem.sunburstDataItem.children.each(function(child) {
child.seriesDataItem.component.setState("hidden");
collapse(child.seriesDataItem.slice);
})
}
}
/* var legend = new am4charts.Legend();
legend.position = "right";
legend.scrollable = true;
legend.parent = chart.chartContainer;
legend.background.fill = am4core.color("#000");
legend.background.fillOpacity = 0.05;
legend.width = 120;
legend.align = "right";
legend.data = dt1; */
/*
[{
"name": "2016",
"fill":"#72A6B2"
}, {
"name": "2017",
"fill": "#667E93"
}, {
"name": "2018",
"fill": "#488BB2"
}];*/
chart.legend = new am4charts.Legend();
//chart.legend.parent = chart.chartContainer;
//chart.legend.itemContainers.template.togglable = true;
chart.legend.position = "left";
chart.legend.scrollable = true;
// Create custom legend
chart.events.on("ready", function(event) {
// populate our custom legend when chart renders
chart.customLegend = document.getElementById('legend');
/* level0SeriesTemplate.slices.dataItems.each(function(row, i) { */
level0SeriesTemplate.dataItems.each(function(row, i) {
var color = chart.colors.getIndex(i);
var percent = Math.round(row.values.value.percent * 100) / 100;
var value = row.value;
legend.innerHTML += '<div class="legend-item" id="legend-item-' + i + '" onclick="toggleSlice(' + i + ');" onmouseover="hoverSlice(' + i + ');" onmouseout="blurSlice(' + i + ');" style="color: ' + color + ';"><div class="legend-marker" style="background: ' + color + '"></div>' + row.name + '<div class="legend-value">' + value + ' | ' + percent + '%</div></div>';
});
});
function toggleSlice(item) {
var slice = level0SeriesTemplate.dataItems.getIndex(item);
if (slice.visible) {
slice.hide();
}
else {
slice.show();
}
}
function hoverSlice(item) {
var slice = level0SeriesTemplate.slices.getIndex(item);
slice.isHover = true;
}
function blurSlice(item) {
var slice = level0SeriesTemplate.slices.getIndex(item);
slice.isHover = false;
}
/* var legendContainer = am4core.create("legend", am4core.Container);
legendContainer.width = am4core.percent(100);
legendContainer.height = am4core.percent(100);
legend = new am4charts.Legend();
legend.parent = legendContainer;
legend.position = "middle";
legend.valign = "middle";
legend.data = dt1;
legend.scrollable = true;
let Label1 = legendContainer.createChild(am4core.Label);
//Label1.height = 50;
Label1.fontWeight = "600";
Label1.align = "left";
Label1.paddingTop = 6;
Label1.paddingBottom = 6;
Label1.text = "Non-Reco Analytics"; */
/*
chart.legend.data = [{
"name": "2016",
"fill":"#72A6B2"
}, {
"name": "2017",
"fill": "#667E93"
}, {
"name": "2018",
"fill": "#488BB2"
}]; */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 530px;
height: 450px;
font-size: 11px;
border: 1px solid #eee;
float: left;
}
#legend {
width: 200px;
height: 450px;
border: 1px solid #eee;
margin-left: 10px;
float: left;
}
#legend .legend-item {
margin: 10px;
font-size: 15px;
font-weight: bold;
cursor: pointer;
}
#legend .legend-item .legend-value {
font-size: 12px;
font-weight: normal;
margin-left: 22px;
}
#legend .legend-item .legend-marker {
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #ccc;
margin-right: 10px;
}
#legend .legend-item.disabled .legend-marker {
opacity: 0.5;
background: #ddd;
}
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/plugins/sunburst.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
<div id="legend"></div>
objective: I want legends for the 1st layer of the sunburst on the right side and the 2nd layer on the left side of the chart.
I hope you get enough understanding of my problem.

Javascript - Fixing searching system?

Down below, there's two pieces of codes. For infinite scroll & search system. Everything works, but the problem with the search system is that, if I search something, then it messes up positioning of the cards or boxes. They should be on one line, if you search them, but those a bit up etc.. I also have added an picture about that. 2nd problem is that, I have an Infinite scroll on my site, but I think I would have to change the search system to search from JSON Data, so it would work correctly? By that I mean, You type something into search, click enter then it searches matches from the JSON and then shows them in that container. I hope I was clear enough about my problem and I hope someone can help me out to solve it :). Thanks to everyone! :)
Here's some CSS as well:
main.css - http://pastebin.com/Tgds0kuJ
zmd-hierarchical-display - http://pastebin.com/Fn5JBpaQ
Materialize - http://pastebin.com/ZxSGZtc8
Here's picture of normal piece: http://prntscr.com/b3yrwa
Here's picture if I search them: http://prntscr.com/b3yrub
Here's the infinite scroll & cards
var perPage = 50;
function paginate(items, page) {
var start = perPage * page;
return items.slice(start, start + perPage);
}
var condition = '';
function renderItems(pageItems) {
pageItems.forEach(function(item, index, arr) {
var message = 'BitSkins Price: $' + Math.round(item.bprice) + '';
if (item.price !== null) {
if (item.bprice === '') {
message = 'Item never sold on BitSkins!';
}
if (item.name != 'Operation Phoenix Case Key' && item.name != 'CS:GO Case Key' && item.name != 'Winter Offensive Case Key' && item.name != 'Revolver Case Key' && item.name != 'Operation Vanguard Case Key' && item.name != 'Operation Wildfire Case Key' && item.name != 'Shadow Case Key' && item.name != 'Operation Breakout Case Key' && item.name != 'Chroma Case Key' && item.name != 'Huntsman Case Key' && item.name != 'Falchion Case Key' && item.name != 'Chroma 2 Case Key') {
$("#inventory").html($("#inventory").html() + "<li class='col 2 zoomIn animated' style='padding:8px;font-weight:bold;font-size:13.5px'><div class='card item-card waves-effect waves-light' style='margin:0%;min-height:295px;width:245.438px;border-radius: 0px;height: 295px;box-shadow: inset 0px 0px 25px 2px #232323;border: 1px solid black' id='" + item.id + "'><div class='iteam' style='text-decoration: underline;text-align: left;font-size: 14.5px;color: #E8E8E8;font-family: Roboto;position: relative;right: -3px;'>" + item.name + "</div><div class='condition' style='text-align: left;color: #E8E8E8;font-family: Roboto;position: relative;left: 3px;'>" + item.condition + "</div><div class='center-align' style='position: relative;padding:0%;top: -33px;'><img title=\"" + item.originalname + "\" draggable='false' src='https://steamcommunity-a.akamaihd.net/economy/image/" + item.iconurl + "/235fx235f'></div><div class='secondarea' style='position: relative;top: -129px;background: rgba(0, 0, 0,0.15);display: block;height: 163px;'><div class='buyer-price center-align' style='font-size:22.5px;font-family: Arial Black;color:#E8E8E8'>$" + Math.round(item.price) + "<div class='bitskinscomp' style='font-weight: normal;font-size:12px;font-family: Roboto;font: bold;'>" + message + "</div></div><a class='btn waves-effect waves-light' style='position:relative;left:-5px;top:50px' href='" + item.inspect + "' target='_blank'>Inspect</a><a class='btn waves-effect waves-light' style='position:relative;right:-5px;top:50px' id='purchaseButton'>Cart</a></div></li>");
}
}
});
}
var win = $(window);
var page = 0;
renderItems(paginate(items, page));
win.scroll(function() {
if ($(document).height() - win.height() == win.scrollTop()) {
page++;
renderItems(paginate(items, page));
}
});
JavaScript search system
$('#SearchItemsFromList').keyup(function() {
var valThis = $(this).val().toLowerCase();
if (valThis === "") {
$('#inventory > li > div').show();
} else {
$('#inventory > li > div').each(function() {
var text = $(this).text().toLowerCase();
(text.indexOf(valThis) >= 0) ? $(this).show(): $(this).hide();
});
}
});
Overview
First off, I have no visibility to the
...messes up positioning of the cards or boxes...
since I do not know what your CSS consists of so I simply made some guesses on that. I suspect it may be due to the actual rendering of your items somehow. To assist in this I removed all the CSS from the injected markup as injecting those "style" attributes is not best practice and frankly difficult to debug as you seem to have experienced. I made an attempt but you will need to adjust the CSS I have provided as it simply does not have all yours in it.
To assist with this, I simply did a "replace" with the current page rather than append each time and then face the challenge of end of scroll/start and deal with the search disruption of that.
I removed the injection of duplicate id on the button and instead used a class injection instead. This will resolve the issue of the invalid HTML which would cause unexpected results at some point that would be very difficult to debug.
The more difficult issue is the dynamic nature of your items array when searching the on-page object list. This I have addressed by creation of a "view candidate list called currentSearch which I have taken the liberty of adding to a name called myApp.data as myApp.data.currentSearch.
Speaking of the namespace, I did that to avoid multiple global objects. I also did that with my custom functions as a best practice.
Here is my sample markup that I used:
<div id="search">
<input id="SearchItemsFromList" type="text" />
</div>
<ul id="inventory">
</ul>
CSS
Here is the CSS which in great part was extracted from the style properties. I took the liberty of naming them poorly as first-style-thing class, second-style-thing etc. which simply coordinate to the injected sequence of elements. This has the additional benefit of reducing the injection string size as well.
.li-style-thing {
padding: 8px;
font-weight: bold;
font-size: 13.5px;
}
.first-style-thing {
margin: 0%;
min-height: 295px;
width: 245.438px;
border-radius: 0px;
height: 295px;
box-shadow: inset 0px 0px 25px 2px #232323;
border: 1px solid black;
}
.second-style-thing {
text-decoration: underline;
text-align: left;
font-size: 14.5px;
color: #E8E8E8;
font-family: Roboto;
position: relative;
right: -3px;
}
.third-style-thing {
text-align: left;
color: #E8E8E8;
font-family: Roboto;
position: relative;
left: 3px;
}
.fourth-style-thing {
position: relative;
padding: 0%;
top: -33px;
}
.fifth-style-thing {
position: relative;
top: -129px;
background: rgba(0, 0, 0, 0.15);
display: block;
height: 163px;
}
.sixth-style-thing {
font-size: 22.5px;
font-family: Arial Black;
color: #E8E8E8;
}
.seventh-style-thing {
font-weight: normal;
font-size: 12px;
font-family: Roboto;
font: bold;
}
.eighth-style-thing {
position: relative;
left: -5px;
top: 50px;
}
.ninth-style-thing {
position: relative;
right: -5px;
top: 50px;
}
.btn {
position: relative;
display: block;
height: 1.5em;
width: 5em;
color: cyan;
background-color: blue;
font-weight: bold;
text-align: center;
padding-top: 0.5em;
margin: 1em;
text-decoration: none;
text-transform: uppercase;
}
#inventory {
display: block;
position: relative;
top: 1em;
left: 0em;
border: solid lime 1px;
}
#inventory li {
background-color: #888888;
}
#inventory li {
display: inline-block;
float: left;
}
.purchaseButton {
right: -8em;
top: 0;
}
#search {
height: 4em;
width: 100%;
background-color: #00aaaa;
padding: 1em;
}
Code:
About the code, note the items object which I simply made from reverse engineering your injection code and likely needs adjusted to your exact object properties.
Note the debounce function which addresses an issue where you might fire the scroll/mouse wheel events too often. I added a "throttle" which you might use instead, borrowed from here: https://remysharp.com/2010/07/21/throttling-function-calls Speaking of, I added the "wheel" event to the "scroll" event so that if you are at the top/bottom of the scroll the mouse wheel can also fire the scroll when no scroll actually occurs. I did not address other possible challenges such as the down/up arrow when the scroll is at the top/bottom; I will leave that up to you to address based upon your needs.
Note that upon a "search" event when typing, I reset the currentSearch list.
I left some console.log in place which you can remove - but allows you to see the page and some event fire logging.
Here is a sample so you can try this all out https://jsfiddle.net/MarkSchultheiss/hgfhh2y7/3/
var myApp = myApp || {};
myApp.data = {
currentSearch: [],
pageStart: 0,
pageEnd: 0,ma
perPage: 3,
page: 0,
lastScroll: 0,
scrollDelay: 250,
outputContainer: $('#inventory'),
excludes: ['Operation Phoenix Case Key', 'CS:GO Case Key', 'Winter Offensive Case Key', 'Revolver Case Key', 'Operation Vanguard Case Key', 'Operation Wildfire Case Key', 'Shadow Case Key', 'Operation Breakout Case Key', 'Chroma Case Key', 'Huntsman Case Key', 'Falchion Case Key', 'Chroma 2 Case Key']
};
myApp.func = {
contains: function(myArray, searchTerm, property) {
var found = [];
var len = myArray.length;
for (var i = 0; i < len; i++) {
if (myArray[i][property].toLowerCase().indexOf(searchTerm.toLowerCase()) > -1) found.push(myArray[i]);
}
return found;
},
paginate: function(items) {
myApp.data.pageStart = myApp.data.perPage * myApp.data.page;
myApp.data.pageEnd = myApp.data.pageStart + myApp.data.perPage;
if (myApp.data.pageEnd > items.length) {
myApp.data.pageEnd = items.length;
myApp.data.pageStart = myApp.data.pageEnd - myApp.data.perPage >= 0 ? myApp.data.pageEnd - myApp.data.perPage : 0;
}
console.log("Page:" + myApp.data.page + " Start:" + myApp.data.pageStart + " End:" + myApp.data.pageEnd + " max:" + items.length);
return items;
},
debounce: function(fn, delay) {
var timer = null;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
};
},
throttle: function(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function() {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function() {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
}
},
renderItems: function(pageItems) {
// $("#inventory").html("");
console.log('renderStart Items:' + pageItems.length);
console.log(myApp.data.pageStart + ":" + myApp.data.pageEnd);
var renderList = pageItems.filter(function(itemValue) {
return !!(myApp.data.excludes.indexOf(itemValue) == -1)
}).slice(myApp.data.pageStart, myApp.data.pageEnd);
console.log(renderList);
var newContent = "";
renderList.forEach(function(item, index, arr) {
var message = 'BitSkins Price: $' + Math.round((item.bprice * 1));
if (item && item.price !== null) {
if (item.bprice === '') {
message = 'Item never sold on BitSkins!';
}
if (myApp.data.excludes.indexOf(item.name) == -1) {
newContent += "<li class='col 2 zoomIn animated'><div class='card item-card waves-effect waves-light first-style-thing' id='" + item.id + "'><div class='iteam second-style-thing' >" + item.name + "</div><div class='condition third-style-thing'>" + item.condition + "</div><div class='center-align fourth-style-thing' ><img title='" + item.originalname + "' draggable='false' src='https://steamcommunity-a.akamaihd.net/economy/image/" + item.iconurl + "/235fx235f'></div><div class='secondarea fifth-style-thing'><div class='buyer-price center-align sixth-style-thing'>$" + Math.round(item.price) + "<div class='bitskinscomp seventh-style-thing'>" + message + "</div></div><a class='btn waves-effect waves-light eighth-style-thing' href='" + item.inspect + "' target='_blank'>Inspect</a><a class='btn waves-effect waves-light purchaseButton'>Cart</a></div></li>";
}
}
myApp.data.outputContainer.html(newContent);
});
}
};
var items = [{
id: "123",
name: "freddy Beer",
condition: "worn",
originalname: "beer stein",
price: 10.22,
bprice: "34.33",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "123",
name: "freddy Beer",
condition: "worn",
originalname: "beer stein",
price: 10.22,
bprice: "34.33",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "123",
name: "freddy Beer",
condition: "worn",
originalname: "beer stein",
price: 10.22,
bprice: "34.33",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "123",
name: "freddy Beer",
condition: "worn",
originalname: "beer stein",
price: 10.22,
bprice: "34.33",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "123",
name: "Operation Phoenix Case Key",
condition: "worn",
originalname: "Operation Phoenix Case Key",
price: 10.22,
bprice: "34.33",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "234",
name: "Johnson Wax",
condition: "waxy",
originalname: "Ear wax",
price: 2244.22,
bprice: "",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "45245",
name: "Door Knob | Green",
condition: "green tint",
originalname: "Green door knob",
price: 35.68,
bprice: "",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA",
inspect: "http://example.com/myinspect/4"
}, {
id: "45245red",
name: "Door Knob | Red",
condition: "red tint",
originalname: "Red door knob",
price: 35.68,
bprice: "",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA",
inspect: "http://example.com/myinspect/4"
}, {
id: "45245red",
name: "Door Knob | Red",
condition: "red tint",
originalname: "Red door knob",
price: 35.68,
bprice: "",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA",
inspect: "http://example.com/myinspect/4"
}, {
id: "45245blue",
name: "Door Knob | Blue",
condition: "blue tint",
originalname: "Blue door knob",
price: 35.68,
bprice: "",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA",
inspect: "http://example.com/myinspect/4"
}, {
id: "45245Brown",
name: "Door Knob | Brown",
condition: "brown tint",
originalname: "Brown door knob",
price: 35.68,
bprice: "34.23",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA",
inspect: "http://example.com/myinspect/4"
}, {
id: "45245Malt",
name: "Beer malt | Brown",
condition: "brown tint",
originalname: "Brown Beer Malt ",
price: 35.68,
bprice: "34.23",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}, {
id: "4Beef",
name: "Beefeaters Mug | Brown",
condition: "new tint",
originalname: "Brown Beefeaters mug",
price: 35.68,
bprice: "34.23",
iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og",
inspect: "http://example.com/myinspect/4"
}];
myApp.data.outputContainer.on('customRenderEvent', function() {
myApp.func.renderItems(myApp.func.paginate(myApp.data.currentSearch));
});
$('#SearchItemsFromList').on('keyup', function() {
var valThis = $(this).val();
if (valThis === "") {
// item-card
// items hold the things to pageinate
// currentSearch holds the filtered items
myApp.data.currentSearch = items;
} else {
// "name" is the matching property in the object
myApp.data.currentSearch = myApp.func.contains(items, valThis, "name");
}
myApp.data.outputContainer.trigger('customRenderEvent');
console.log("keyup len:" + myApp.data.currentSearch.length);
}).trigger('keyup'); // trigger for initial display
$(window).on('scroll wheel', myApp.func.debounce(function(event) {
// set the page on scroll up/down
if ($(this).scrollTop() == 0) {
myApp.data.page > 0 ? myApp.data.page-- : myApp.data.page = 0;
} else {
myApp.data.page++;
}
myApp.func.renderItems(myApp.func.paginate(myApp.data.currentSearch));
}, myApp.data.scrollDelay));
Final note on the code, you have a quite long, difficult to maintain conditional which I replaced by added an array with the exclusions and then the code uses it with a filter: .filter(function(itemValue) {
return !!(myApp.data.excludes.indexOf(itemValue) == -1)
})

Categories