Rendering Array from a Promise using lit-html's until - es6-promise

I am trying to render some HTML using lit-html and their until syntax. I must confess, promises frustrate me, but I am a back-end developer by trade so this boils down to a lack of knowledge on my part. Any assistance would be greatly appreciated.
My Code
... removed for brevity ...
async getCenters() {
try {
return await this.centerManager.allCenters;
}
catch (error) {
return error;
}
}
createView() {
return html`
<style>
h2 {
color: var(--ptsi-gold);
font-family: 'Helvetica Neue Medium';
font-size:1.4em;
}
p {
font-family: 'Helvetica Neue Roman';
font-size:1em;
}
.wrapper {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.tile {
background: var(--ptsi-gray);
padding: 25px;
margin: 25px 0px 25px 0px;
}
</style>
<div class="wrapper">
<div class="tile">
<h2>This is a Hard Typed Title</h2>
<p>This is a Hard Typed Body.</p>
</div>
</div>
${until(this.getCenters().then((data) => {
data.forEach(element => {
html`<div class="wrapper">
<div class="tile">
<h2>${element.program_code}</h2>
<p>${element.program_name}</p>
</div>
</div>
`
})
}), html`<span>Loading...</span>`)
}`
}
}
... removed for brevity ...
When the page loads, I am looping through the array and I can inspect the values. Additionally, I see the Loading... while in the debugger, but the html`` never renders the content within the until() function.

The first argument to until is not resolving to any content. Update the functions to return values and use map instead of forEach.
until(this.getCenters().then((data) => {
return data.map(element => {
return html`<div class="wrapper">
<div class="tile">
<h2>${element.program_code}</h2>
<p>${element.program_name}</p>
</div>
</div>`
})
}), html`<span>Loading...</span>`)

Related

html make 2 double-line texts have same distance between lines

I need to format my layout of html into this way:
However, my actual result is this:
I want the distance between "service name"(Pirate Service) and "status"(Proposed) equal to the distance between "API Name"(Get All Loot) and "Resource Name"(Pirates), but the service-status(Pirate Service, Proposed) distance is too large.
How to reduce the distance between "Service Name"(Pirate Service) and "Status"(Proposed)?
my typescript code:
import "./Description.css";
interface DescriptionProps {
name: string;
service: string;
resource: string;
status: string;
}
export const Description = ({name, service, resource, status,}: DescriptionProps) => {
return (
<div>
<div className="name-service-container">
<h1>
<span className="names">{name}</span>
</h1>
<h4>
<span className="services">{service}</span>
</h4>
</div>
<br />
<div className="resource-status-container">
<p>
<span className="resources">{resource}</span>
</p>
<p>
<span className="status">{status}</span>
</p>
</div>
</div>
);
};
my css:
.resources {
display: inline;
float: left;
font-style: italic;
clear: left;
}
.names {
display: inline;
float: left;
}
.services {
float: right;
bottom: 0;
}
.status{
float: right;
top:0;
}
.resource-status-container{
margin-right: 30px;
}
.name-service-container{
margin-right:30px;
}
Do you want something like this?
h1,h4,p {
margin:0;
}
.container {
display:flex;
align-items:center;
justify-content:space-between;
background-color:gray;
}
.name-service-container,
.resource-status-container {
display:flex;
flex-direction:column;
justify-content:center;
gap: 0.5rem; /* Control distance between elements */
}
<div class="container">
<div class="name-service-container">
<h1><span class="names">{name}</span></h1>
<h4><span class="services">{service}</span></h4>
</div>
<div class="resource-status-container">
<span class="resources">{resource}</span>
<span class="status">{status}</span>
</div>
</div>

OnMouseOver change the content of a (pop-up) window

I'm a visual artist with not that many coding skills. I know some HTML and some CSS but that's it. I like to create a webpage that does the following:
On the left, there is an image with lines. When hovering over a line the window on the right shows an image, movie, or plays a sound. Hovering over the next line triggers another image, movie, or sound.
Anyone can point me in the correct direction? I made a gif to show how it should work...
Simple solution:
Select HTML elements which we want to hover over (left, middle, right), and HTML elements which contain our images/videos/audio etc. (img1, sound, img2)
For every element you want to hover over, you need to add event listener (addEventListener), so you can manipulate your HTML/CSS code with JavaScript.
2.2 Inside each event listener you add or remove class: none, which has CSS value of display: none (this means element won't be shown), depending on what your goal is.
To make images disappear when we don't hover our cursor over the element, we need to again add event listener to elements which already have on mouseover event listener. In this case we use mouseover or blur. When cursor isn't on the element, JavaScript will automatically add none class to it.
const left = document.querySelector('.left-line');
const middle = document.querySelector('.middle-line');
const right = document.querySelector('.right-line');
const img1 = document.querySelector('.image-1');
const sound = document.querySelector('.sound');
const img2 = document.querySelector('.image-2');
left.addEventListener('mouseover', () => {
img1.classList.remove('none');
img2.classList.add('none');
sound.classList.add('none');
});
middle.addEventListener('mouseover', () => {
img1.classList.add('none');
img2.classList.remove('none');
sound.classList.add('none');
});
right.addEventListener('mouseover', () => {
img1.classList.add('none');
img2.classList.add('none');
sound.classList.remove('none');
});
left.addEventListener('mouseout',() => addNoneClass());
middle.addEventListener('mouseout', () => addNoneClass());
right.addEventListener('mouseout', () => addNoneClass());
function addNoneClass() {
img1.classList.add('none');
img2.classList.add('none');
sound.classList.add('none');
}
* {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
}
main {
display: flex;
width: 100%;
height: 100%;
}
section.left {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.line-container {
width: 150px;
height: 150px;
display: flex;
align-items: center;
border: 2px solid black;
}
.left-line, .middle-line, .right-line {
width: 50px;
height: 90%;
margin: 0 10px;
}
.left-line { background-color: green; }
.middle-line { background-color: red; }
.right-line { background-color: blue; }
section.right {
width: 50%;
display:flex;
align-items: center;
justify-content: center;
}
.box {
width: 200px;
height: 200px;
border: 2px solid black;
}
img {
width: 200px;
height: 200px;
}
.none {
display: none;
}
<main>
<section class="left">
<div class="line-container">
<div class="left-line">
</div>
<div class="middle-line">
</div>
<div class="right-line">
</div>
</div>
</section>
<section class="right">
<div class="box">
<div class="image-1 none">
<img src="https://play-lh.googleusercontent.com/aFWiT2lTa9CYBpyPjfgfNHd0r5puwKRGj2rHpdPTNrz2N9LXgN_MbLjePd1OTc0E8Rl1" alt="image-1">
</div>
<div class="sound none">
<img src="https://sm.pcmag.com/pcmag_uk/review/g/google-pho/google-photos_z68u.jpg" alt="sound">
</div>
<div class="image-2 none">
<img src="https://cdn.vox-cdn.com/thumbor/I2PsqRLIaCB1iYUuSptrrR5M8oQ=/0x0:2040x1360/1200x800/filters:focal(857x517:1183x843)/cdn.vox-cdn.com/uploads/chorus_image/image/68829483/acastro_210104_1777_google_0001.0.jpg" alt="image-2">
</div>
</div>
</section>
</main>
You can do this by the following code example.
HTML:
<div class="lines">
<span id='line-1'>|</span>
<span id='line-2'>|</span>
<span id='line-3'>|</span>
</div>
<div id='output'></div>
JS
const line1 = document.getElementById('line-1')
const line2 = document.getElementById('line-2')
const line3 = document.getElementById('line-3')
const output = document.getElementById('output')
line1.addEventListener('mouseover', () => {
output.innerHTML = 'Content One'
})
line2.addEventListener('mouseover', () => {
output.innerHTML = 'Content Two'
})
line3.addEventListener('mouseover', () => {
output.innerHTML = 'Content Three'
})

Is there way to do partial text stylization in vue (nuxt.js)

We are creating an application in vue
Does anyone know how to format text partially
like this?
You cannot create hard constraints from ellipses, but this functional may be procedural.
If you know what words you need to style, try like following snippet:
new Vue({
el: "#demo",
data() {
return {
messages: { unstyled: 'no styling!', styled: 'platformy dobrix del!' },
};
},
methods: {
words(string) {
return string.split(/\s+/);
},
isMarked(string) {
return /dobrix/i.test(string);
},
},
})
.marked {
color: red;
position:relative;
}
.marked::before {
content: "";
background: turquoise;
position: absolute;
height: 20px;
width: 92%;
top: 20px;
z-index: -1;
border-radius: 10px;
}
*{
font-weight: 800;
font-size: 32px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div class="container">
<div v-for="(value, name) in messages" :key="name">
<span v-for="(word, index) in words(value)" :key="index">
<span v-if="isMarked(word)" class="marked">{{ word }} </span>
<span v-else>{{ word }} </span>
</span>
</div>
</div>
</div>

How do I make a content div scrollable? React and CSS

Learning React.js framework and need some pointers on styling. CSS isn't my forte.
How do I style the static content div in the middle and make it scrollable only within the div?
No styling:
https://i.imgur.com/26wNAfH.jpg
How to style this?
https://i.imgur.com/c5nYCOz.jpg
Here's the scroll function:
https://storage.googleapis.com/hatchways-app.appspot.com/assessments/data/frontend/part%202.mp4
app.css
.name {
font-weight: bold;
font-size: 20px;
}
.centered {
margin: auto;
width: 50%;
border: 3px solid green;
padding: 10px;
}
.center {
position: fixed;
width: 500px;
height: 200px;
top: 50%;
left: 50%;
margin-top: -100px; /* Negative half of height. */
margin-left: -250px; /* Negative half of width. */
}
.content {
text-align: center;
border: 2px solid grey;
border-radius: 5px;
position: fixed;
/* center the div */
right: 0;
left: 0;
margin-right: auto;
margin-left: auto;
/* give it dimensions */
min-height: 10em;
width: 90%;
/* just for example presentation */
top: 5em;
background-color: white;
}
Output: https://i.imgur.com/Eyv6hab.png
HTML:
import React, { Component } from "react";
import "../App.css";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
const API = "https://www.hatchways.io/api/assessment/students";
class App extends Component {
constructor(props) {
super(props);
this.state = {
students: [],
isLoading: false,
error: null
};
}
componentDidMount() {
this.setState({ isLoading: true });
fetch(API)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error("Something went wrong ...");
}
})
.then(data =>
this.setState({ students: data.students, isLoading: false })
)
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
const { students, isLoading, error } = this.state;
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <p>Loading ...</p>;
}
return (
<body>
<div className="content">
<div>
{students.map(student => (
<div key={student.id}>
<p>
<img src={student.pic} />
</p>
<p className="name">
{student.firstName} {student.lastName}
</p>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p> Skill: {student.skill}</p>
<p>Average: {student.grades}</p>
</div>
))}
</div>
</div>
{/* <div class="card mb-3">
{students.map(student => (
<div class="row no-gutters">
<div class="col-md-4">
<img src={student.pic} class="card-img" alt="..." />
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">
{student.firstName} {student.lastName}
</h5>
<p class="card-text">
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p> Skill: {student.skill}</p>
<p>Average: {student.grades}</p>
</p>
</div>
</div>
</div>
))}
</div> */}
</body>
);
}
}
export default App;
This might not help I am unfamiliar with that JS framework. I am only posting this because nobody has answered and maybe this can help.
<style>
scroll
{
max-height: 400px;
overflow-y: scroll;
}
</style>
<div class="scroll">

Vue Single File Component binding data-v-xxxxxxxx to generated elements

I'm building a Vue component as a Single File Component:
<template>
<div class="chart"></div>
</template>
<script>
import * as d3 from 'd3';
export default {
data() {
return {
data: [4, 8, 15, 16, 23, 42],
};
},
mounted() {
d3.select('.chart')
.selectAll('div')
.data(this.data)
.enter()
.append('div')
.style('width', d => `${10 * d}px`)
.text(d => d);
},
};
</script>
<style lang="scss" scoped>
.chart {
div {
background-color: steelblue;
color: white;
font: 10px sans-serif;
margin: 1px;
padding: 3px;
text-align: right;
}
}
</style>
After processing with webpack, the CSS is rendered like so:
<style type="text/css">
.chart div[data-v-xxxxxxxx] {
background-color: steelblue;
color: white;
font: 10px sans-serif;
margin: 1px;
padding: 3px;
text-align: right;
}
</style>
But the HTML shows up as:
<div data-v-xxxxxxxx class="chart">
<div style="width: 40px;">4</div>
<div style="width: 80px;">8</div>
<div style="width: 150px;">15</div>
<div style="width: 160px;">16</div>
<div style="width: 230px;">23</div>
<div style="width: 420px;">42</div>
</div>
I'm using D3 to generate the child <div>s. I've found that data-v-xxxxxxxx isn't bound to generated elements. If I include the child <div>s in the original template rather than generating them, they each have the data-v-xxxxxxxx attribute and the styles apply as expected
I would think that any descendant of the root node, whether included in the template or generated, should be bound to the rules of the scoped CSS. Is there any way to force this?
New version of vue-loader (from version 12.2.0) allows you to use "deep scoped" css. You need to use it that way:
<style scoped> now support "deep" selectors that can affect child
components using the >>> combinator:
.foo >>> .bar { color: red; } will be compiled into:
.foo[data-v-xxxxxxx] .bar { color: red; }
More informations on the release page of vue-loader