Create nested list items with given depths in JavaScript - javascript

I'm trying to make nested list items with the data below:
It creates the right indentation when depths are sorted with -1 +1 but I can't make the perfect indentation. Any help will be appreciated.
const data = [
{depth: 1, title: "Some Title Goes Here - First Title", url: "#some-title-goes-here-first-title-prs7ztig15"},
{depth: 2, title: "Yuck Almost Got it!", url: "#yuck-almost-got-it-qlx0i4727h"},
{depth: 1, title: "Whoops! Something went Wrong", url: "#whoops-something-went-wrong-qoflcur4iw"},
{depth: 1, title: "Don't Worry We Get You Covered", url: "#dont-worry-we-get-you-covered-ug4kxqz4kp"},
{depth: 3, title: "I Hate Writing Titles", url: "#i-hate-writing-titles-jrlw78vulm"},
{depth: 4, title: "Gonna Start to Lorem", url: "#gonna-start-to-lorem-whzh8e3qus"},
{depth: 2, title: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam, voluptate!", url: "#lorem-ipsum-dolor-sit-amet-consectetur-adipisicing-elit-quisquam-voluptate-agxlhkvs8c"},
{depth: 1, title: "Consectetur adipisicing elit. Quo, corporis!", url: "#consectetur-adipisicing-elit-quo-corporis-4xurvdulcn"},
{depth: 1, title: "Dolor sit amet, consectetur adipisicing elit. Fugiat, quae?", url: "#dolor-sit-amet-consectetur-adipisicing-elit-fugiat-quae-txu46oaitk"},
{depth: 2, title: "Adipisicing elit. Dolor, rem.", url: "#adipisicing-elit-dolor-rem-x6coih7o36"},
{depth: 3, title: "Elit. Consequuntur, cum.", url: "#elit-consequuntur-cum-zqyhfglbd4"},
{depth: 4, title: "Ipsum dolor sit amet.", url: "#ipsum-dolor-sit-amet-sz09eh07ma"},
{depth: 2, title: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo, corporis!", url: "#lorem-ipsum-dolor-sit-amet-consectetur-adipisicing-elit-quo-corporis-18g13jn4j5"}]
function getTOCOutput(data) {
if (data.length < 1) return '';
let tocOutput = "<ul>";
let currentDepth = data[0].depth;
let c = data.length;
for (let i = 0; i < c; i++) {
let itemDepth = data[i].depth;
if (currentDepth === itemDepth) {
tocOutput += '<li>' + data[i].title + '';
} else if (currentDepth < itemDepth) {
tocOutput += '<ul><li>' + data[i].title + '';
} else {
tocOutput += '</li>' + '</ul>'.repeat(currentDepth - itemDepth) + '<li>' + data[i].title + '</li>';
}
currentDepth = data[i].depth;
}
tocOutput += "</ul>";
return tocOutput;
}
document.body.innerHTML += getTOCOutput(data);

You can use two while loops inside the for loop in order to account for the depth changes. They repeat until the current depth is right:
function getTOCOutput(data) {
let currentDepth = 0;
let tocOutput = "";
for (let {depth, title, url} of data) {
while (depth > currentDepth) {
tocOutput += "<ul>";
currentDepth++;
}
while (depth < currentDepth) {
tocOutput += "</ul>";
currentDepth--;
}
tocOutput += '<li>' + title + '';
}
return tocOutput;
}
let data = [{depth: 1, title: "Some Title Goes Here - First Title", url: "#some-title-goes-here-first-title-prs7ztig15"},{depth: 2, title: "Yuck Almost Got it!", url: "#yuck-almost-got-it-qlx0i4727h"},{depth: 1, title: "Whoops! Something went Wrong", url: "#whoops-something-went-wrong-qoflcur4iw"},{depth: 1, title: "Don't Worry We Get You Covered", url: "#dont-worry-we-get-you-covered-ug4kxqz4kp"},{depth: 3, title: "I Hate Writing Titles", url: "#i-hate-writing-titles-jrlw78vulm"},{depth: 4, title: "Gonna Start to Lorem", url: "#gonna-start-to-lorem-whzh8e3qus"},{depth: 2, title: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam, voluptate!", url: "#lorem-ipsum-dolor-sit-amet-consectetur-adipisicing-elit-quisquam-voluptate-agxlhkvs8c"},{depth: 1, title: "Consectetur adipisicing elit. Quo, corporis!", url: "#consectetur-adipisicing-elit-quo-corporis-4xurvdulcn"},{depth: 1, title: "Dolor sit amet, consectetur adipisicing elit. Fugiat, quae?", url: "#dolor-sit-amet-consectetur-adipisicing-elit-fugiat-quae-txu46oaitk"},{depth: 2, title: "Adipisicing elit. Dolor, rem.", url: "#adipisicing-elit-dolor-rem-x6coih7o36"},{depth: 3, title: "Elit. Consequuntur, cum.", url: "#elit-consequuntur-cum-zqyhfglbd4"},{depth: 4, title: "Ipsum dolor sit amet.", url: "#ipsum-dolor-sit-amet-sz09eh07ma"},{depth: 2, title: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo, corporis!", url: "#lorem-ipsum-dolor-sit-amet-consectetur-adipisicing-elit-quo-corporis-18g13jn4j5"},];
document.body.insertAdjacentHTML("beforeend", getTOCOutput(data));

Related

Mongoose partial text search with sorting by revelance

I'm trying to query my mongodb database via mongoose, sorting the most relevant items first.
The following code works, but only returns results that contain the search parameter as a full word.
E.g. example will return items that include fields such as, ⁣ but{name: "example-item", description: "this is an example description"} but examp won't return that same item. I'd also like for it to search across multiple fields, as my current code does.
I'm aware you can do this partial search using regex but then you're not able to sort by textScore. Is there any way to do both? Sorting after each request is not possible as it will be paginated and handling somewhat large data.
let searchValue = "examp";
let matchingItems = await Items.find(
{
$text: {
$search: searchValue,
}
},
{
score: {
$meta: "textScore"
}
},
{
sort: {
score: {
$meta: "textScore"
}
}
}
);
Example DB data:
[
{name: "dignissim", description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."},
{name: "Fusce eget.", description: "Nullam malesuada ex sit amet diam ultrices"},
{name: "Duis nec", description: "Proin at dolor at est porta aliquet. Proin viverra imperdiet orci, a ornare tortor"},
{name: "Mauris.", description: "Aenean tristique ante et eros porttitor, ut sodales ipsum pulvinar."},
{name: "Pellentesque", description: "Nam dignissim ipsum a elit fermentum"},
{name: "facilisis augue", description: "Etiam sit amet dolor sed sapien rutrum sodales."},
{name: "erat suscipit", description: "this is an example description"},
]
My schema is defined as below:
const mongoose = require("mongoose");
const schema = new mongoose.Schema({
name: String,
description: String
});
schema.index({ name: "text", description: "text" });
const Items = mongoose.model("Item", schema);

filter data on multiple fields

I am trying to build a filter for JSON object at the moment, the json object looks like this,
created_at: null
deleted_at: null
id: 3
listings: Array(3)
0: {id: 3, name: "Learn the basics of the guitar from the anatomy of the guitar to scales, chords", slug: "learn-the-basics-of-the-guitar-from-the-anatomy-of-the-guitar-to-scales-chords", description: "We live in a unique and wonderful time where elect… going to give you a lifetime of awesome rockin’.", booking_details: "undefined", …}
1: {id: 8, name: "Advanced guitar skills with William Topa", slug: "advanced-guitar-skills-with-william-topa", description: "We live in a unique and wonderful time where elect… going to give you a lifetime of awesome rockin’.", booking_details: "Lorem ipsum dolor sit amet, consectetur adipiscing… laboris nisi ut aliquip ex ea commodo consequat.", …}
2: {id: 9, name: "Music production simplified", slug: "music-production-simplified", description: "We live in a unique and wonderful time where elect… going to give you a lifetime of awesome rockin’.", booking_details: "Lorem ipsum dolor sit amet, consectetur adipiscing… laboris nisi ut aliquip ex ea commodo consequat.", …}
length: 3
__proto__: Array(0)
tag: "Music"
updated_at: null
weight: null
This is part of a bigger object, the hierarchy looks like
[{ data, listings }, {data, listings}]
What I am wanting to do, is filter through the listings array and hide any listings that don't have a cost of "0.00"
Here is what i am trying,
<input type="checkbox" v-model="priceFilter" value="0.00" />
data() {
return {
this.priceFilter: []
}
},
computed: {
filteredTags() {
return this.tags.filter(tag => {
tag.listings.filter(listing => "0.00" === listing.cost);
//console.log(this.checkedPrice, listing.cost);
});
},
},
In the above I just trying to return the listings where the cost matches 0.00 with trigger it via the checkbox being checked but even that does not filter as I wish I still see all listings.
Anyone care to offer any advice?

How to pop and unshift elements from an array in object?

I have an object. And I have a scenario that what do I want to do with it.
Scenario :
All arrays and features were added in objeTest. After that I will call it, I want to remove 'Wednesday' value from default index. And I want to place all 'Wednesdays' in sequence from the first index.
*The following getted error :
Uncaught TypeError: Cannot read property 'day' of undefined*
The following is an example for my issue. You could try and will see error message from console.
I didn't find any solution, I need your advise and solution.
Code :
var objeTest = {
name : 'objeTest',
langs : {
0 : 'EN',
1 : 'VI',
2 : 'RU',
3 : 'AR'
},
commentGeneral : 'testComment'
};
var date = [{
day : 'Sunday',
month : 'July',
comment : ''
},
{
day : 'Wednesday',
month : 'June',
comment : 'lorem ipsum dolor sit amet consectetur adipiscing elit'
},
{
day : 'Wednesday',
month : 'June',
comment : 'lorem ipsum dolor sit amet consectetur adipiscing elit'
},
{
day : 'Friday',
month : 'February',
comment : 'lorem ipsum dolor sit amet consectetur adipiscing elit'
}];
/**
* I don't want to remove that using the array adding
* in the object process ( objeTest.dates = date.filter(...)etc).
*/
objeTest.dates = date; // You couldn't change from adding process. I don't need this solution from here.
// If you couldn't understand, please read again scenario. Thanks for your interesting.
var myObjLeng = objeTest.dates.length;
console.log(objeTest);
for(var i = 0; i < myObjLeng; i++) {
if(objeTest.dates[i].day == 'Wednesday') {
objeTest.dates[i].pop();
objeTest.dates[i].unshift();
}
};
console.log(objeTest);
So the new dates of the object I want to get should look like this in the object:
[
{
day : 'Wednesday',
month : 'June',
comment : 'lorem ipsum dolor sit amet consectetur adipiscing elit'
},
{
day : 'Wednesday',
month : 'August',
comment : 'lorem ipsum dolor sit amet consectetur adipiscing elit'
},
{
day : 'Sunday',
month : 'July',
comment : ''
},
{
day : 'Friday',
month : 'February',
comment : 'lorem ipsum dolor sit amet consectetur adipiscing elit'
}];
Try a sort.
objeTest.dates.sort((entryA, entryB) => {
return (entryB.day === 'Wednesday') - (entryA.day === 'Wednesday')
});
If you need to separate the array the easiest way is to forget about the original one and then set it again.
not_wednesdays = [];
wednesdays = [];
objeTest.dates.forEach(date=>{
if (date.day=="Wednesday") {
wednesdays.push(date);
}
else {
not_wednesdays.push(date);
}
});
objeTest.dates = not_wednesdays;

jQuery, on hover show text snippet in another div

I'm trying to build an interactive banner that when you hover over the banner, you can hover over each image and see a snippet of text.
Im trying to make this snippet of text appear in my div titled 'textbox' only im struggling to make it change when the mouse leaves each image (you will have to see my fiddle for an example)
Let each image load BEFORE hovering over the html blue box...
http://jsfiddle.net/uEDBA/3/
jQuery
$(document).ready(function () {
$(function () {
var people = [{
id: 1,
name: 'Adam',
bio: 'This is Adam\'s Biography. Sed ut perspiciatis unde omnis iste natus error sit voluptatem',
image: 'justin.jpg'
}, {
id: 2,
name: 'Brian',
bio: 'This is Brian\' Biography. Sed ut perspiciatis unde omnis iste natus error sit voluptatem',
image: 'chris.jpg'
}, {
id: 3,
name: 'Charlie',
bio: 'This is Charlie\'s Biography. Sed ut perspiciatis unde omnis iste natus error sit voluptatem',
image: 'sam.jpg'
},
];
w = 750;
h = 450;
var counter = 0;
(function nextFade() {
counter++;
var data = people[Math.floor(Math.random() * people.length)];
var figure = $('<figure style="float:left; width:150px; height:150px; background:red;" />');
var information = '<img src="http://www.placekitten.com/150/150" /><figcaption><h6>Meet ' + data.name + '</h6><p>' + data.bio + '</p>Read about ' + data.name + '. </figcaption>';
figure.html(information).appendTo('.interactive-banner-faces').hide().fadeIn(100, function () {
if (counter < 15) {
nextFade();
} else {
$('.interactive-banner-faces').children(':nth-child(12n+1), :nth-child(12n+2), :nth-child(12n+3)').addClass('rightTxt');
// On mouseover, fadeout the text overlay so we can play with the banner
$('.interactive-banner').on('mouseenter', function () {
$('.textbox').html(data.bio).fadeIn();
$('.overlay').stop().animate({
'top': '-450px'
}, 200, 'easeInCirc');
}).on('mouseleave', function () {
$('.textbox').html('').fadeOut();
$('.overlay').stop().animate({
'top': '0'
}, 600, 'easeOutCirc');
});
};
});
})();
});
});

for loop in fancybox given syntax error

function imgshow(val2){
var arrayVal2 = val2.split(',');
$.fancybox([
for (i=0; i<arrayVal2.length; i++){
'uploads/'+arrayVal2[i],
//'http://farm3.static.flickr.com/2687/4220681515_cc4f42d6b9.jpg',
{
'href' : 'uploads/'+arrayVal2[i],
'title' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
}
}
], {
'padding' : 0,
'transitionIn' : 'none',
'transitionOut' : 'none',
'type' : 'image',
'changeFade' : 0
});
}
can i give for loop there. there is syntax error where i place for loop
i have images name in database. explode tham and store in a array. and call a for loop to show all images,
but given syntax error
please Guide me
This is not valid javascript
[for (;;) {}]
But you could do this
[
(function() {
var val = [];
for (i=0; i<arrayVal2.length; i++){
val.push(['uploads/'+arrayVal2[i],
//'http://farm3.static.flickr.com/2687/4220681515_cc4f42d6b9.jpg',
{
'href' : 'uploads/'+arrayVal2[i],
'title' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
}]);
}
return val;
)()
]
Though it's not pretty. I would recommend refactoring that section.

Categories