Buefy Carousel Thumbnail Indicator show duplicated image (Vuejs) - vue.js

I'm trying to create a carousel with vertical thumbnails, but the thumbnails are being duplicated. I only have 2 image URLs, but it's showing 4 thumbnails.
App.vue:
<template>
<div id="app">
<b-carousel
:indicator-inside="false"
class="is-hidden-mobile"
:pause-hover="false"
:pause-info="false"
>
<b-carousel-item v-for="(item, i) in imagess" :key="i">
<figure class="image">
<img :src="item.url">
</figure>
</b-carousel-item>
<span v-if="gallery" #click="switchGallery(false)" class="modal-close is-large"/>
<template slot="indicators" slot-scope="props">
<span class="al image">
<img v-for="(p,index) in imagess" :key="index" :src="p.url" :title="props.i">
</span>
</template>
</b-carousel>
</div>
</template>
<script>
export default {
name: "App",
components: {},
data() {
return {
bundledatas: null,
imagess: [
{
url:
"https://specials-images.forbesimg.com/imageserve/37645633/960x0.jpg?cropX1=445&cropX2=3910&cropY1=258&cropY2=2207"
},
{
url:
"https://www.sovereigngroup.com/wp-content/uploads/2018/12/HK-4.jpg"
}
]
};
}
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.is-active .al img {
filter: grayscale(0%);
}
.al img {
filter: grayscale(100%);
margin: 2px 0;
}
.carousel {
display: grid;
grid-template-columns: auto 25%;
align-items: center;
}
.carousel-indicator {
flex-direction: column;
}
.indicator-item {
margin-right: initial !important;
}
</style>
demo
I only want to display 2 thumbnails for (one for each image) like this:

The problem is your indicators slot is displaying all items of imagess when it should only be displaying the one specified in props.i, which is the current index shown in the carousel.
The solution is to lookup the item in imagess by the index in props.i, and set the img's source URL accordingly:
<template slot="indicators" slot-scope="props">
<span class="al image">
<!-- BEFORE: -->
<!-- <img v-for="(p,index) in imagess" :key="index" :src="p.url" :title="props.i"> -->
<img :src="imagess[props.i].url">
</span>
</template>
updated codesandbox

Related

Use an existing DNSdig (golang) in a return to display JSON (VueJS)

I'm fairly new to programming so sometimes when things are explained they get lost in translation.
This is the assignment.
would need a new component with a basic form (one for requested domain, then a drop down with values of A, AAAA, PTR, MX and CNAME) ---- on submit would use that wayfinderAPI.getDNSDig, and then display the results -- its all JSOn returned
getDNSDig(domain: string, recordtype: string): Promise<any> {
http.defaults.headers.post['Authorization'] = 'Bearer ' + localStorage.getItem('webApiToken')
return http.post("/v1/dns/dig", {request: domain, record_type: recordtype})
}
so would be a start from scratch component -- (can copy paste one to start with and just clear out the variables and methods, etc.) (edited)
the golang function is already there is ready
can modify the return if its wonky
something like this but cleaner: https://toolbox.googleapps.com/apps/dig/#A/
I have created the basic component but am unsure how to do the actual api DNS call and the return as Json.
<template>
<div>
<form
v-if="!formSubmitted"
#submit.prevent="submitForm"
>
<span>Name</span><br>
<input
v-model="name"
type="text"
placeholder="Name"
><br>
<span>Type</span><br>
<div>
<b-dropdown
id="dropdown-left"
text="Left align"
variant="primary"
class="m-2"
>
<b-dropdown-item href="#">
A
</b-dropdown-item>
<b-dropdown-item href="#">
AAAA
</b-dropdown-item>
<b-dropdown-item href="#">
PTR
</b-dropdown-item>
<b-dropdown-item href="#">
MX
</b-dropdown-item>
<b-dropdown-item href="#">
CNAME
</b-dropdown-item>
</b-dropdown>
</div>
</form>
<div v-if="formSubmitted">
<h3>Form Submitted</h3>
<p>Name: {{ name }}</p>
<p>Type: {{ type }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
name: "",
type: "",
};
},
methods: {
submitForm: function () {
this.formSubmitted = true
}
},
};
</script>
<style>
form {
padding: 10px;
border: 2px solid black;
border-radius: 5px;
}
input {
padding: 4px 8px;
margin: 4px;
}
span {
font-size: 18px;
margin: 4px;
font-weight: 500;
}
.submit {
font-size: 15px;
color: #fff;
background: #222;
padding: 6px 12px;
border: none;
margin-top: 8px;
cursor: pointer;
border-radius: 5px;
}
</style>
However I am struggling to figure out the return with the requested DNSDig call.
Any help on this would be greatly appreciated.

How to pass props dynamically in vue

I am trying to pass props to a router-link which is used to take me to the update or delete page. In order for me to update the right element, I need to pass the item's id as a prop to the component(dropdown menu) to dynamically render the update and delete pages.
Here is my dropdown component:
<template>
<div class="dropdown">
<button #click="toggleMenu">
<fa class="dropdown_icon" icon="fa-solid fa-arrow-down" />
</button>
<div v-if="showMenu" class="menu">
<div class="menu-item" #click="itemClicked">
<router-link :to="`/updateList/${id}`" class="list__link"
>Update</router-link
>
<br />
<router-link :to="`/deleteList/${id}`" class="list__link"
>Delete</router-link
>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'DropdownList',
props: ['id'],
data() {
return {
showMenu: false,
};
},
methods: {
toggleMenu() {
this.showMenu = !this.showMenu;
},
itemClicked() {
this.toggleMenu();
},
},
};
</script>
<style scoped>
.dropdown_icon {
padding: 0.2rem;
color: #ffd700;
background: black;
margin-top: 15px;
transition: var(--transition);
border-radius: 0.2rem;
height: 17px;
}
.dropdown_icon:hover {
background: white;
color: black;
height: 17px;
}
.menu {
background: white;
padding-left: 2rem;
padding-right: 2rem;
border-radius: 1rem;
}
.list_plus {
padding: 0.5rem;
border: 1px solid gray;
border-radius: 1rem;
transition: var(--transition);
}
.list_plus:hover {
background: black;
color: #ffd700;
}
.createList {
text-decoration: none;
}
.list__link {
text-decoration: none;
color: black;
}
</style>
Here is my code for the part in which I am sending the element's id as a prop to the component:
div class="all__lists" v-for="(item, index) in items" :key="index">
<div class="list">
<div class="title">
<div class="title__options">
<h1 class="list_name">{{ item[0].list_name }}</h1>
<Dropdown :v-bind:id="`${item[0].list_id}`" />
<!-- V-menu -->
<!--menu ends-->
</div>
</div>
</div>
</div>
The Items object looks like:
But when I Try to access the update or delete page, the router redirects me to /updateList/undefined instead of /updateList/1 or something. Can anybody help me in fixing this?
Your problem is that you mixed the v-bind directive with its shorthand :.
You wrote :v-bind:id instead of v-bind:id (or :id).
With your code, you should be able to get the id by defining the props v-bind:id in the child. It will work since :v-bind:id will be converted as v-bind:v-bind:id.

Navbar transparent in buefy

I am creating a landpaging and I am facing some style difficulties due to lack of practice.
I want to modify the backgroud of the navbar, so I wanted to make the background transparent so that the bottom of the page appears. How can I do this?
enter image description here
<template>
<div class="Shellhub-LP-1280">
<div class="textura Nuvem">
<b-navbar>
<template slot="brand">
<b-navbar-item tag="router-link" :to="{ path: '/' }" transparent="true">
<img
src="https://raw.githubusercontent.com/buefy/buefy/dev/static/img/buefy-logo.png"
alt="Lightweight UI components for Vue.js based on Bulma"
>
<!-- <img src="#/static/logo-inverted.png"> -->
</b-navbar-item>
</template>
...
</b-navbar>
</div>
</div>
</template>
<style>
.Shellhub-LP-1280 {
/* width: 100%; */
height: 2283px;
background-color: #333640;
}
.textura {
/* width: 100%; */
height: 771px;
}
.Nuvem {
width: 100%;
height: 755px;
object-fit: contain;
opacity: 0.9;
float: right;
background: url('../static/nuvem.png');
background-repeat: no-repeat;
background-position: right;
}
Thanks
buefy navbar API:
https://buefy.org/documentation/navbar/#api-view
Passing this props:
<b-navbar :fixed-top="true" :transparent="true" >
Vue docs - components props (recommend to read):
https://v2.vuejs.org/v2/guide/components-props.html
transparent "bug":
Open github issue:
BUG: navbar is-transparent not working .
IMPORTANT: transparent affect navbar items (Not the navbar wrapper himself).
Remove any hover or active background from the navbar items
So add simple CSS styling:
nav.navbar.is-fixed-top {
background: transparent;
}
body top padding issue
I won't find a way to remove body top padding. I added this style:
body{
padding-top: 0px!important;
}
Basic example:
const app = new Vue()
app.$mount('#app')
img.responsive_img{
width: 100%;
height: auto;
}
body{
padding-top: 0px!important;
}
/* change navbar background color */
nav.navbar.is-fixed-top {
background: transparent;
}
<link href="https://unpkg.com/buefy/dist/buefy.min.css" rel="stylesheet"/>
<div id="app">
<b-navbar class="is-link" :fixed-top="true" :transparent="true">
<template slot="brand">
<b-navbar-item tag="router-link" :to="{ path: '/' }">
<img
src="https://raw.githubusercontent.com/buefy/buefy/dev/static/img/buefy-logo.png"
alt="Lightweight UI components for Vue.js based on Bulma"
>
</b-navbar-item>
</template>
<template slot="start">
<b-navbar-item href="#">
Home
</b-navbar-item>
<b-navbar-item href="#">
Documentation
</b-navbar-item>
<b-navbar-dropdown label="Info">
<b-navbar-item href="#">
About
</b-navbar-item>
<b-navbar-item href="#">
Contact
</b-navbar-item>
</b-navbar-dropdown>
</template>
<template slot="end">
<b-navbar-item tag="div">
<div class="buttons">
<a class="button is-primary">
<strong>Sign up</strong>
</a>
<a class="button is-light">
Log in
</a>
</div>
</b-navbar-item>
</template>
</b-navbar>
<header style="min-height: 200vh;">
<img class="responsive_img" src="https://picsum.photos/2000/600"/>
</header>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
Change navbar background color on scroll
only by custom code
See this codepen (I added a class on scroll):
https://codepen.io/ezra_siton/pen/jOPZgmR
Change the background color on scroll her:
nav.navbar.is-fixed-top.isActive{
transition: background-color 0.5s ease;
background: red; /* change color on scroll */
}
Change navbar links color to white (For dark hero) - add "is-link" modifier:
https://bulma.io/documentation/components/navbar/#colors
<b-navbar class="is-link" :fixed-top="true" :transparent="true" >
Remove hover/active
:transparent="true"
Remove any hover or active background from the navbar items.

Nested vue-draggable elements

I am trying to have nested vue-draggable elements to visually represent a song structure (with potential repetitions).
This is what I came up with as a prototype:
var vm = new Vue({
el: "#main",
data: {
"structure": ["Prelude", "Verse", ["Chorus", "Verse"], "Last Chorus"]
},
});
#main {
text-align: center;
width: 300px;
background-color: #EEE;
padding:10px;
}
.element {
text-align: center;
padding: 10px;
margin: 5px auto;
border-radius: 10px;
color: #FFF;
font-family: sans-serif;
font-weight: bold;
}
.tag {
width: 150px;
background-color: #007BFF;
}
.group {
width: 175px;
border: 3px solid #CED4DA;
background-color: #FFF;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/sortablejs#1.7.0/Sortable.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.15.0/vuedraggable.min.js"></script>
<div id="main">
<draggable v-for="tag in structure" :options="{group:'tags'}">
<div v-if="!Array.isArray(tag)" class="tag element">
{{tag}}
</div>
<draggable v-else :options="{group:'tags'}" class="group element">
<div v-for="tag2 in tag" class="tag element">
{{tag2}}
</div>
</draggable>
</draggable>
{{structure}}
</div>
Even being new to Vue.js this seems so not "the way" to go. My concrete problems with this solution are:
When the grouping element is at the top, I can't drag anything else above it (same applies to the very bottom)
The dragged structure does not get represented in the data.structure property
How would I go about nesting even more? Group in group in group...
You should:
Change the data structure into a recursive one:
data: {
"structure": [
{ name: "Prelude"},
{ name: "Verse"},
{ name: "Middle", children: [{ name: "Chorus"}, { name: "Verse"}]},
{ name: "Last Chorus"}
]
},
Use recursive components using draggable, something like:
<template>
<draggable class="dragArea" tag="ul" :list="data" :group="{ name: 'g1' }">
<li v-for="el in children" :key="el.name">
<p>{{ el.name }}</p>
<nested-draggable v-if="el.children" :tasks="el.children" />
</li>
</draggable>
</template>
See this working example:
https://sortablejs.github.io/Vue.Draggable/#/nested-example

How do I convert my vue into a component.vue

I have a fiddle that changes the contrast and brightness of an image.
When I try and add it as a .vue component onto my site the slider no longer effects the image. I know the issue is around my filter function. I just can't understand why my :style attribute isn't applying the change to me element.
What am I doing wrong/not getting?
fiddle that works - https://jsfiddle.net/BBMAN/fxtrtqpj/14/
code for my .vue component that does not work.
<template>
<div class="brightness-slider container">
<h1>{{ msg }}</h1>
<h2>Built using Vue.js</h2>
<div class="row">
<div class="col-md-10">
<img ref="img" class="img img-responsive" :style="filters" />
</div>
<div class="col-md-2">
<strong>Contrast ({{contrast}})</strong>
<input class="slider vertical" type="range" orient="vertical" v-model="contrast" max="1" min="0" step="0.01" />
</div>
</div>
<div class="row">
<div class="col-md-12">
<h4>
<strong>Brightness ({{brightness}})</strong>
</h4>
<input class="slider horizontal" type="range" v-model="brightness" max="3" min="0" step="0.01" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ImageBrightnessSlider',
data() {
return {
//sending data to view.
msg: 'Audience Republic Brightness Modifier',
brightness: 1,
contrast: 1
}
},computed: {
filters() {
const toDash = (str) => str.replace( /([a-z])([A-Z])/g, '$1-$2' ).toLowerCase()
debugger;
return { filter: Object.entries(this._data).filter(item => typeof(item[1]) !== 'object').map(item => `${toDash(item[0])}(${item[1]})`).join(' ') }
}
},
mounted() {
this.$refs.img.src = require('../assets/pleasure-garden-1200-by-768.jpg')
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
input[type=range][orient=vertical]{
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* WebKit */
width: 8px;
height: 100%;
padding: 0 5px;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 3px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
</style>
"fiddle that works" = incorrect
you are trying to shove HTML CSS JavaScript into Javascript!!!
interpreter Javascript does not understand HTML CSS!
you code must be something like this
index.html
<div id="App">
<!-- HTML code -->
</div>
<script>
// js code
</script>
<style scoped>
/* css code */
</style>
you have many mistakes, please see official documentation
also, you can see my vue examples
UPDATED:
SFC example