Vue Js displaying object in qoutes - javascript

i faced an issue. I have an array of "Lessons" in which i have stored 5 objects. Each of them have parameter (url). Example:
Lessons: [
{
url: "../assets/Math.png",
Title: "Lesson",
Subject: "Math",
Location: "London",
Price: "£100",
Spaces: 5,
},
Now i did v-for to display each of them, everything is working except i dont know how to show the image i have in the /assets folder. i have tried simple way img src=" {{ lesson.url }}" and this one:
<div class="col-md-6 col-lg-3" v-for="lesson in Lessons" :key="lesson.id">
<div class="card" >
<img src="'${lesson.url}'" alt="" class="card-img-top img-fluid">
can anyone suggest me how to do it?

To use image routes in this way you must first import them for Webpack to be able to process them from the data:
import mathImg from "../assets/Math.png"
// in your data
Lessons: [
{
url: mathImg, // use the import name
Title: "Lesson",
Subject: "Math",
Location: "London",
Price: "£100",
Spaces: 5,
}
]
in your template
<img :src="Lessons.url" />

I believe you want to bind the src attribute like so:
<img :src="lesson.url" ...>

I guess you forgot the :
<img :src="`${lesson.url}`" alt="" class="card-img-top img-fluid">
and you also can
<img :src="lesson.url" alt="" class="card-img-top img-fluid">

Related

Angular HTML use ngFor index

<div (click)="switchImg($event)" class="containerImgSmall">
<img
[ngStyle]="imgs.img1.zero.style"
id="1"
src="{{ imgs.img1.zero.src }}"
alt=""
/>
<img
[ngStyle]="imgs.img1.one.style"
id="1"
src="{{ imgs.img1.one.src }}"
alt=""
/>
</div>
Is it possible to replicate this div in html in Angular 10 times using ngFor? The index number is needed to fill the id (1,2,3,4..) and also the properties ngStyle and src. For example ngStyle for first img is imgs.img1.zero.style so I would like to replace the "1" with index so the next two for example should be imgs.img2.zero.style imgs.img3.zero.style. So to give full picture second div should look like this
<div (click)="switchImg($event)" class="containerImgSmall">
<img
[ngStyle]="imgs.img2.zero.style"
id="2"
src="{{ imgs.img2.zero.src }}"
alt=""
/>
<img
[ngStyle]="imgs.img2.one.style"
id="2"
src="{{ imgs.img2.one.src }}"
alt=""
/>
</div>
wrap div with ng-container
<ng-container *ngFor="let index of indexes>
*your div here*
</ng-container>
where indexes is array of numbers (1, 2, 3, 4...10) and then use the index as you want
but it would be better if you have array of objects and inside objects you would have style, src and all the other property which you want for image
like so:
[
{
style: '',
src: ''
},
{
style: '',
src: ''
}
]
also if you are using property as a img src, insted of this:
src="{{ imgs.img1.zero.src }}"
you can use it like this:
[src]="imgs.img1.zero.src"

Giving random background images to each div in the for loop in Vue Js

I have a v-for loop that runs on a div and gives out a bunch of tags. I need each of those tags to have a different src. Everything that I have tried so far results in all the tags getting the same source. Is there any way I can do this?
<div class="wrapper" v-for="result in results" :key="result.index">
<div class='small-card'>
<img class="thumbnail" :src="backgroundImage">
<div class="text-elements">
<span class="md-display-2 minicard-title">{{result.name}}</span>
<br class="break">
<span class="md-display-1 minicard-subtitle">{{result.state}}</span>
</div>
</div>
<br class="br3">
</div>
I recently did this in a project.
What I ended up doing was setting the style tag for background-image using the :style attribute.
Depending on how you are acquiring the image source, you will need to either create a method to return a random image URL, or access the image URL provided in the object. As you said "random" I assume the first approach would be the best fit.
Here's a very rough and untested example:
<template>
<div>
<div
v-for="index in 10"
:key="index"
:style="{'background-image': randomImage()}"
/>
</div>
</template>
<script>
export default {
name: 'Example',
data() {
return {
images: ['1.jpg', '2.jpg', '3.jpg', '4.jpg'],
};
},
methods: {
randomImage() {
return `url("${
this.images[Math.floor(Math.random() * this.images.length)]
}")`;
},
},
};
</script>
Make sure that the :style="{'background-image': randomImage()}" contains a () to ensure the method is called vs being referenced.

Adding some logic in v-for with v-if Vue

I have some json with below results
{
"module": [
{
"id": 1,
"title": "Module 1",
"type": "URL",
"size": 1,
"image": "https://localhost/image1.png"
},
{
"id": 2,
"title": "Module 2",
"type": "YOUTUBE",
"size": 2,
"image": "https://localhost/image2.png"
}
]
}
Now i want to render it on a page with some loop and conditional, like below
<template>
<section class="page-section homescreen mt-4">
<div class="container">
<div class="row">
<div class="col-lg-3" v-bind:key="data.index" v-for="data in modules" v-if="data.size == 1">
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
<div class="col-lg-6" v-bind:key="data.index" v-for="data in modules" v-if="data.size == 2">
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
</div>
</div>
</section>
</template>
<script>
export default {
data() {
return {
modules: [
{
"id": 1,
"title": "Module 1",
"type": "URL",
"size": 1,
"image": "https://localhost/image1.png"
},
{
"id": 2,
"title": "Module 2",
"type": "YOUTUBE",
"size": 2,
"image": "https://localhost/image2.png"
}
]
};
}
};
</script>
But instead of success, i got some error saying
5:99 error The 'modules' variable inside 'v-for' directive should be
replaced with a computed property that returns filtered array instead.
You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for
8:99 error The 'modules' variable inside 'v-for' directive should be
replaced with a computed property that returns filtered array instead.
You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for
Actually i want to create the <div class="col-lg-3"> part to be dynamic based on the json, if size:1 mean to have col-lg-3 and if size:2 mean to have col-lg-6
Any explanation and suggestion will be appreciated.
Thank you
eslint-plugin-vue was telling you to do this:
<div class="col-lg-3" v-bind:key="data.index" v-for="data in modules.filter(o=>o.size == 1)">
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
<div class="col-lg-6" v-bind:key="data.index" v-for="data in modules.filter(o=>o.size == 2)">
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
In your case, it can be simplified as
<div :class="'col-lg-'+data.size*3" v-bind:key="data.index" v-for="data in modules">
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
If it's essentially something with css classes, why don't you use v-bind:class or :class with your condition ?
https://v2.vuejs.org/v2/guide/class-and-style.html
But like said in the error message you'll certainly have to create a sub component and then use props on it
https://v2.vuejs.org/v2/guide/components-props.html
In case you have just two sizes:
You can use Computed Properties to achieve this requirement.
First, create two new computed properties like:
computed: {
modulesSize1: function() {
return this.modules.filter(x => x.size == 1)
},
modulesSize2: function() {
return this.modules.filter(x => x.size == 2)
}
}
Now, you can easily loop through computed properties modulesSize1 && modulesSize2 like:
<div class="row">
<div class="col-lg-3" v-bind:key="data.index" v-for="data in modulesSize1" >
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
<div class="col-lg-6" v-bind:key="data.index" v-for="data in modulesSize2" >
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
</div>
In case you have multiple sizes:
First, create a simple method like:
methods: {
getClass: function(size) {
return `col-lg-${size * 3}`
},
}
and then we can update template and use Class Bindings like:
<div :class="getClass(data.size)" :key="data.index" v-for="data in modules">
<img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
The v-if is essentially baked in to the v-for (if modules is empty nothing will render) so it's recommended not to use them in combination. If you need it for a separate condition, like you do here, then you'll have to move your v-for on to the <img> itself.
You also won't be able to use data.size this way so you'd have to use something like v-if="modules[0].size == 1" etc.
Edit
#Palash answer is probably the more efficient way to solve this.
Edit 2
#r0ulito and #xianshenglu also makes a really good point, if it's just a class issue, use v-bind.

Bind list to multiple target divs in WinJS

I have list declared in js file like this (full list contain 6 items, but can be more or less than that)
var dataArray = [
{
type: "item", title: "Cliff",
picture: "../../images/slike_etnologija/srednji_vek/01.jpg",
text: "some description"
},
{
type: "item", title: "Grapes",
picture: "../../images/slike_etnologija/srednji_vek/02.jpg",
text: "another description"
},
two templates declared in html file
<div id="galleryTemplate" data-win-control="WinJS.Binding.Template">
<div class="overlaidItemTemplate">
<img class="image img-responsive" src="#" data-win-bind="src: picture; alt: title" />
<div class="overlay">
<h2 class="ItemTitle" data-win-bind="innerText: title"></h2>
</div>
</div>
</div>
<div id="textTemplate" data-win-control="WinJS.Binding.Template">
<div>
<p data-win-bind="innerText: text"></p>
</div>
</div>
and two controls where i need to show data from list
<div class="col-md-12" id="basicFlipView"
data-win-control="WinJS.UI.FlipView"
data-win-options="{ itemDataSource : EtnologijaGallery.itemList.dataSource, itemTemplate: galleryTemplate }">
</div>
<p data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource : EtnologijaGallery.itemList.dataSource, itemTemplate: textTemplate }">
</p>
I'm trying to show image gallery in flipbox and text description associated to each image in listview next to it. Due to design i can't put both things in same template.
My flipbox works fine, and shows all images, but listview don't work. It shows, first, only 3 descriptions from list, and those 3 descriptions are shown in control with scroll bar, instead changing when user change image in flipbox.
Can someone help me solve this?
As mentioned on http://www.buildwinjs.com/tutorial/2WinJS_Binding/bindingInit/, WinJS Binding is one-time binding and you bound the same array to two separate controls.
I think you should check FlipView's onpageselected event and when that event occurs, update the div with the proper text. I guess the ListView is not needed to be used in this case at all.

HTML functions? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a repeated HTML code, like:
<figure class="print">
<a href="#">
<img src="images/5.png" alt="" />
<dl>
<dt>Client</dt>
<dd>Envato</dd>
<dt>Role</dt>
<dd>Print</dd>
</dl>
</a>
</figure>
Is there a smart way to make a 'function' out of it (that accept the captions and image as parameters), or do I need to repeat that code so many times?
with HTML you don't have the possibility to write functions that generate what you want. It seems that you would like to generate dynamic content. This is usually done by employing a scripting language.
So you have two options here:
Use a server side scripting language like PHP
If you want a client side solution you could use JavaScript which can dynamically create content for you.
For further information just Google for some simple tutorials.
There are no way in pure HTML.
You can use JavaScript(jQuery) or back-end script, like PHP.
$("html").append($(".print").clone());
As other people have said, HTML is a declarative language. However, with modern frameworks like AngularJS, you can write things like:
<figure class="print" ng-repeat="figure in figures">
<a href="#">
<img ng-src="{{figure.image}}" alt="" />
<dl>
<dt>Client</dt>
<dd>{{figure.captions.client}}</dd>
<dt>Role</dt>
<dd>{{figure.captions.role}}</dd>
</dl>
</a>
</figure>
The corresponding model would be:
var figures = [{
image: 'images/5.png',
captions: {
client: 'Envato',
role: 'Print'
}
}, {
image: 'images/6.png',
captions: {
client: 'Another caption',
role: 'Print'
}
}];
It takes some time to get used to it, but you should read the code of their TODO example app.
Try using jquery template.
<script src="jquery.tmpl.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var data = [
{ name: "Astor", product: "astor", stocklevel: "10", price: 2.99},
{ name: "Daffodil", product: "daffodil", stocklevel: "12", price: 1.99},
{ name: "Rose", product: "rose", stocklevel: "2", price: 4.99},
{ name: "Peony", product: "peony", stocklevel: "0", price: 1.50},
{ name: "Primula", product: "primula", stocklevel: "1", price: 3.12},
{ name: "Snowdrop", product: "snowdrop", stocklevel: "15", price: 0.99},
];
$('#flowerTmpl').tmpl(data).appendTo('#row1');
});
</script>
<script id="flowerTmpl" type="text/x-jquery-tmpl">
<div class="dcell">
<img src="${product}.png"/>
<label for="${product}">${name}:</label>
<input name="${product}" data-price="${price}" data-stock="${stocklevel}"
value="0" required />
</div>
</script>
You can do this with underscore templates, for example:
<script src="http://documentcloud.github.io/underscore/underscore-min.js"></script>
<script id="template" type="text/html">
<% data.forEach(function(item){ %>
<figure class="print">
<a href="#">
<img src="<%= item.src %>" alt="" />
<dl>
<dt>Client</dt>
<dd><%= item.client %></dd>
<dt>Role</dt>
<dd><%= item.role %></dd>
</dl>
</a>
</figure>
<% }); %>
</script>
<div id="container"></div>
In your JavaScript:
var data = [
{
src: 'images/5.png',
client: 'Envato',
role: 'Print'
},
{
src: 'images/4.png',
client: 'Foo',
role: 'Bar'
}
];
var template = document.querySelector('#template').innerHTML;
var html = _.template(template, {data: data});
document.querySelector('#container').innerHTML = html;

Categories

Resources