I am practicing for a vue TestDome test this week. One of the practice questions is as follows :
An image gallery is a set of images with corresponding remove buttons. This is the HTML code for a gallery with two images:
<div>
<div class="image">
<img src="https://www.testdome.com/files/resources/12362/aff5c408-79f8-4220-9769-8b4cde774c98.jpg">
<button class="remove">X</button>
</div>
<div class="image">
<img src="https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg">
<button class="remove">X</button>
</div>
</div>
Implement the image-gallery component that accepts a links prop and renders the gallery described above so that the first item in the links prop is the src attribute of the first image in the gallery. It should also implement the following logic: When the button is clicked, the image that is in the same div as the button should be removed from the gallery.
The component should be usable with any root Vue instance.
For example, after the first image has been removed from the gallery above, it's HTML code should look like this:
<div>
<div class="image">
<img src="https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg">
<button class="remove">X</button>
</div>
</div>
Here is my solution, which when run locally, renders the two images and buttons, as well as deletes them when clicked.
<!DOCTYPE html>
<html>
<head>
<title>Image Gallery</title>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<image-gallery :links="links" #remove-link="removeLink"/>
</div>
<script>
// Create image-gallery component that accepts link prop
Vue.component('image-gallery', {
props: ['links'],
template: `
<div>
<div v-for="link in links" class="image">
<img :src="link" />
<button #click="removeLink(link)" class="remove">X</button>
</div>
</div>
`,
methods: {
removeLink (link) {
this.$emit('remove-link', link)
}
}}
);
var vm = new Vue({
el: "#app",
data () {
return {
links: ['https://www.testdome.com/files/resources/12362/aff5c408-79f8-4220-9769-8b4cde774c98.jpg', 'https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg']
}
},
methods: {
removeLink(link) {
this.links = this.links.filter(l => l !== link)
}
}
}
);
// Example case
let firstButton = document.querySelectorAll("div.image > button")[0];
if(firstButton) {
firstButton.click();
}
setTimeout(() => console.log(document.getElementById("app").innerHTML));
</script>
</body>
</html>
The results according to testdome:
Example case: Wrong answer
ImageGallery will render the correct list: Correct answer
Remove a single image: Wrong answer
Remove multiple images: Wrong answer
Run OK, but 3 out of 4 test cases failed.
Output:
<div><div class="image"><img src="https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg"> <button class="remove">X</button></div></div>
Unless I am reading the question wrong, the result is correct. What am I missing?
Related
How do I retrieve information stored in a js file? I assume I am labelling my node elements in HTML incorrectly
I'm hoping to gain a better understanding of how to retrieve a function node from localStorage
Below are the key factors I am trying to get using getElementById into local storage from post HTML.
This is not everything in my listing.html document, I have excluded everything but what I think are essential elements
<div class="listing">
<div class="container-form">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img class="img" value(src)="1" id="img" src="images/4.JPG" alt="img1">
</div>
<div class="infoBox">
<h5 post="weight" id="weight" value="7.00">7.00 : Under - 16 oz</h5>
</div>
<div class="column-bottom">
<div class="add-button">
<div class="add-button" method="post">
<p><input type="submit" onclick="addListing()" class="btn"></input></p>
<div class="buy-button">
<span class="price" post="price" id="price" value="60">$60</span>
<button type="button" class="btn" onclick="window.location.href='cart.html'" onclick="addListing()"
;>BuyMe</button>
</div>
</div>
</div>
</div>
</div>
</div>
I am trying to use the function below to store each element from the post HTML
function addlisting() {
let listing = ['listings'];
if (localStorage.getItem('listings')) {
listing = JSON.stringify(localStorage.getItem('listings'));
alert("added!");
}
listing.push({ 'listingId': listingId + 1, image: '<imageLink>' });
listingsId = listingsId + 1;
var listingsName = document.getElementById('name').innerHTML;
var listingsPrice = document.getElementById('price').getAttribute('data- value');
var listingsImage = document.getElementById("img").src;
var listingsWeight = document.getElementById('weight').getAttribute('data- value');
value = parseFloat(listingsPrice, listingsWeight).toFixed(2);
localStorage.getItem('name', 'price', 'img', 'weight', JSON.stringify(listingsName, listingPrice, listingsImage, listingsWeight));
}
here is the $(document).ready(function(){ function I'm hoping to implement into my code, I got this from another Stack Overflow page as it was the most fitting however I am yet to understand each component.
$(document).ready(function () {
$('#Btn').load(function () {
let listings = [];
if (localStorage.getItem('listings')) {
listings = JSON.parse(localStorage.setItem('listings'));
}
listings.push({ 'listingId': 1, image: '<imageLink>' });
});
});
my question again is how do I then execute this function using onload Onto a separate HTML, called cart.html. I did not display my cart.html file because there is nothing pertaining to this question on it. And furthermore how to go about styling Onload events that retrieve information from localStorage.
P.S.
There is an alert function within my first .js excerpt addListing(), that does not fire when clicked. probably a sign of bad programming. I've just never found a straightforward answer
I am creating a clone of the Netflix web app. I am currently developing the landing page. I have included my code below. This is one of the few different ways I have attempted structuring this page.
The layout currently is appearing how I want it to look, however the "main-slice__language-button" and the "main-slice__signin-button" at the top of the page are not working – meaning nothing happens when I click the select dropdown, and the Sign In button is not appearing as clickable. Can anyone explain why it does not work this way and any suggestions for better alternatives?
screenshot of landing page
import backgroundImage from '../../images/mooshflix-background.jpeg';
import netflixLogo from '../../images/netflix-logo.png';
import './MainSlice.css';
const MainSlice = () => {
return (
<div className='main-slice-container'>
<img className='background-image' src={backgroundImage} alt='mooshflix background' />
<div className='header'>
<img className='main-slice__logo' src={netflixLogo} alt='' />
<div className='main-slice__header-buttons'>
<select className='main-slice__language-button'>
<option>English</option>
<option>Spanish</option>
</select>
<button className='main-slice__signin-button'>Sign In</button>
</div>
</div>
<div className='main-slice__text-container'>
<h1 className='main-slice__title'>Unlimited movies, TV shows, and more.</h1>
<h2 className='main-slice__subtitle'>Watch anywhere. Cancel anytime.</h2>
<div className='main-slice__email-form-container'>
<h3 className='email-form-title'>Ready to watch? Enter your email to create or restart your membership.</h3>
<form>
<input placeholder='Email Address' ></input>
<button className='main-slice__email-form-button'>Get Started ></button>
</form>
</div>
</div>
</div>
)
}
export default MainSlice;```
because you DID NOT do anything, what event did u call for that button? you have to add some event listeners like onClick to your btn, like below:
const onStart = () => {
DO STH WHAT YOU WANT
}
<button className='main-slice__email-form-button' onClick={onStart}>
Get Started
</button>
I've created a component, and in that component is an audio tag. I've been trying to pass the file path of the mp3 to the component from its parent, but the audio element doesn't seem to be able to load the file successfully for some reason. The element just ends up greyed out, and I don't get any kind of error. I know the properties are being passed successfully because I'm also passing in the title of the track, and that loads just fine in the component. However, if I hardcode the same path in for the source, then it works fine. Which isn't a big deal, but I have 11 tracks to do and it would be much easier with a v-for statement.
Here's my parent component:
<template>
<div container>
<div class=banner>
<img src="../assets/CryptoLogo2.svg"/>
</div>
<div class="albumcontainer">
<div class="covercontainer"><img src="../assets/TIADCover(Final).png"/></div>
<div class="arrow"></div>
<div class="tracklistcontainer">
<table class="tracklist">
<tr class="track" v-for="track in tracks" :key="track.file" style="padding: 20px;">
<td>
<player :name="track.name" :file="track.file" />
</td>
</tr>
</table>
</div>
</div>
<div class="bio">
<p>
</p>
</div>
<div class="footer">
<div class="footericons">
<img src="../assets/icons/Facebook.svg" />
<img src="../assets/icons/Instagram.svg" />
<img src="../assets/icons/Twitter.svg" />
</div>
</div>
</div>
</template>
<script>
import player from './player'
export default {
name: "Album1",
data() {
return {
tracks: [
{
name: '5G',
file: '../assets/tracks/5G.mp3'
}
]
}
},
components:{
player
}
};
</script>
And then the component with the audio tag:
<template>
<div>
<h3>{{ name }}</h3>
<audio controls controlsList="nodownload">
<source ref="player" v-bind:src="file" type="audio/mpeg">
</audio>
</div>
</template>
<script>
export default{
name: "player",
props: {
name: {
type: String,
default: null
},
file:{
type: String,
default: null
}
}
}
</script>
Here you can see that my data is being passed successfully.
And you see that the source attribute is being loaded correctly as well.
This is what I get, and you can see the h3 loads fine, so I know the data is being passed. But the element is greyed out.
To test it out, I tried just hard coding the file path:
<source src="../assets/tracks/5G.mp3">
And that works just fine:
But I don't want to do it like that because I have about 11 tracks to do, so I would like for it to load from the data being passed so that I can reuse the component. Any ideas?
try using something like this in your Vue v-for I use this when src is not loading on the img tag.
:src="getSrc(x.src)"
methods: {
getSrc(src) {
return require("../assets/" + src);
}
}
Your watch function on file prop is never triggered because your file name is static, it never triggers a change on the watcher, before mounting the component, at least in the code you provided it is that way.
From Vue.js API vm.$watch
Watch an expression or a computed function on the Vue instance for changes. The callback gets called with the new value and the old value.
I have the following HTML markup:
<div id="app">
<div class="image">
<div class="overlay">
<p>Some overlay text</p>
</div>
<img src="https://placeimg.com/640/480/any" class="img-fluid">
</div>
<div class="info">
<h6 class="name">Title here</h6>
<p class="meta">Meta here</p>
</div>
<div class="info-button" #mouseover="addParentClass" #mouseout="removeParentClass">
Mouse over here!
</div>
What I would like to do is whenever someone hovers over the div with class "info-button" certain classes get added to the image above and the overlay.
I have got it working with the following Vue.js markup:
let vm = new Vue({
el: "#app",
data:{
isHovering: false
},
methods: {
addParentClass (event) {
event.target.parentElement.children[0].children[1].classList.add('active')
event.target.parentElement.children[0].children[0].classList.add('overlay-active')
},
removeParentClass (event) {
event.target.parentElement.children[0].children[1].classList.remove('active')
event.target.parentElement.children[0].children[0].classList.remove('overlay-active')
},
},
})
However it seems like a lot of redundant JS. I have tried to get it working with:
event.target.parent.closest('.overlay'.).classList.add('overlay-active')
And a lot of similar parent/children/closest selectors, however I can not seem to get the result I want. How can I get the "closest" selector to work here?
Here's a codepen with a very rough working example: Link to codepen
Edit: I want to point out that i want to use this in a loop, so I will have mulitple images and I want to make the overlay only appear on the current image.
VueJS is reactive. This means the data should drive the DOM. You should not play with the DOM yourself.
Add an active property to data;
let vm = new Vue({
el: "#app",
data:{
isHovering: false,
active: false
},
methods: {
addParentClass (event) {
this.active = true;
},
removeParentClass (event) {
this.active = false; },
},
})
And make the DOM reactive by;
<div class="overlay" :class="{'overlay-active': active}" >
<p>Some overlay text</p>
</div>
Here is the updated codepen
https://codepen.io/samialtundag/pen/Jeqooq
I have polymer 1.0 app. In my routing.html file I have following configuration for routes.
page('/applications', function () {
app.route = 'Applications';
});
page('/claims', function () {
app.route = 'Claims';
});
I have applied data-routes attr in index.html file to map the corresponding section part.
For Ex:
<a data-route="Claims" href="/claims">
<iron-icon icon="report-problem"></iron-icon>
<span>Claims</span>
</a>
<section data-route="Claims">
<div class="vertical layout center">
<div>
<p>Getting Claims...</p>
<paper-progress value="10" secondary-progress="30" class="" indeterminate elavation="4"></paper-progress>
</div>
</div>
</section>
So the main problem occurs when I try to change the routes through a function. In my case I am calling a function on paper-fab tab event
I want to change the route when a user click on paper fab, to achieve this I defined a method "createApplication" in app.js
app.createApplication = function() {
app.route = 'Create Application';
};
and section part for this route in index.html file
<section data-route="Create Application">
<div class="vertical layout center fit">
<p> Some content</p>
</div>
</section>
The problem is when I click on the paper -fab its not changing the route in browser but same code runs fine in mobile.