Is there a method to implement through data attributes in JavaScript? - javascript

I want implement the card content in the card when expanded, I have used the help of JavaScript to implement the title, image, description ,I have used 'data-title' and 'data-type' for displaying title and image respectively which are by the working fine and when I try to implement card description by using data-desc attribute , it is displaying 'undefined'.
Anyone please help me with my code.
My code link: https://codepen.io/Avatar_73/pen/ExyNdMK
const getCardContent = (title, type, desc) => {
return `
<div class="card-content">
<h2>${title}</h2>
<img src="./assets/${type}.png" alt="${title}">
<p>${desc}</p>
</div>
`;
}
<div class="cards">
<div class="card" data-type="html" data-desc="I am HTML">
<h2>HTML5</h2>
</div>
</div>

On line 115, you forgot to pass the desc to your getCardContent function
Change to:
const content = getCardContent(card.textContent, card.dataset.type, card.dataset.desc)

Change your calling method signature from
getCardContent(card.textContent, card.dataset.type)
to
getCardContent(card.textContent, card.dataset.type, card.dataset.desc)
you are not passing the third parameter(card.dataset.desc) in the method thus it is rendering the value as undefined.

Related

Click to change image is changing the wrong one

So I'm working on a website that has a lot of movies, and people can choose what movies are they favorite, and for that, I have a star image that can be clicked and when clicked that image will change to another one
Like this:
To this:
The problem I have is that the only image that change is the first one, When I click, for example on the star next to the Ratatouille movie, it will change the first star
This is the HTML:
const getMovieHtml = (movie) => `<div class="movie">
<h2>${movie.title}</h2>
<img onclick="bottonclick()" id="estrelinhas" src="./icons/empty-star.png" alt="estrela vazia" width=40>
<div class="content">
<img src="${movie.posterUrl}" alt="${movie.title}" />
<div class="text">
<p>${movie.summary}</p>
<div class="year">${movie.year}</div>
<div><strong>Directors:</strong> ${movie.director}</div>
<div><strong>Actors:</strong> ${movie.actors}</div>
</div>
</div>
</div>`;
And this is the arrow function I used to make the star change:
const bottonclick = () => {
if (document.getElementById("estrelinhas").src.includes("empty-star.png")) {
document.getElementById("estrelinhas").src = "./icons/filled-star.png";
} else {
document.getElementById("estrelinhas").src = "./icons/empty-star.png";
}
};
ID attributes of HTML elements should be unique. If you don't have unique ID's the code doesn't know which star to update. Read more about IDs here: https://www.w3schools.com/html/html_id.asp
To fix this, a solution would be to use a unique identifier for each image, so that when you click "favourite" it knows which star to reference.
Assuming for example that the movie.posterURL is unique you can use that as the ID, however the data from wherever you are getting the movie from might already have a unique identifier that you could pass to the id attribute of the image instead
Your code could look something like this:
const getMovieHtml = (movie) => `<div class="movie">
<h2>${movie.title}</h2>
<img onclick="bottonclick(e)" id="${movie.posterUrl}" src="./icons/empty-star.png" alt="estrela vazia" width=40>
<div class="content">
<img src="${movie.posterUrl}" alt="${movie.title}" />
<div class="text">
<p>${movie.summary}</p>
<div class="year">${movie.year}</div>
<div><strong>Directors:</strong> ${movie.director}</div>
<div><strong>Actors:</strong> ${movie.actors}</div>
</div>
</div>
</div>`;
const buttonClick = (e) => {
const star = document.getElementById(e.target.id);
if (star.src.includes("empty-star.png")) {
star.src = "./icons/filled-star.png";
} else {
star.src = "./icons/empty-star.png";
}
}
beacuse you getElementById, so you not take all containers,
but you get 1, first,
change getElementById for querySelectorAll and give there some id,
to localizate in DOM ,
buttonClick(e)
and in
function buttonClick(e) {
e.target.value/id/or something
}

Render images from Entries in Contenful + Angular app

The issues:
How to I access the includes array so I can get the image url to render the image? (or how to I get the images to render in general)
Why is are my description fields not rendering?
So I have a contentful service that gets all the entries as such:
//get all exhibits
getExhibits(query?: object): Promise<Entry<any>[]> {
return this.cdaClient.getEntries(Object.assign({
include : 2,
content_type: CONFIG.contentTypeIds.exhibit
}, query))
.then(res => res.items);
}
The above function is called in my Gallery component as such:
ngOnInit() {
this.contentfulService.getExhibits()
.then(exhibits => this.exhibits = exhibits);
}
And the data is rendered in the corresponding HTML as such:
<section class="gallery__section" [class.menu--open]="menu.isMenuClosed" *ngFor="let exhibit of exhibits">
<figure>
<img src="{{ exhibit.fields.file.url }}" alt="">
<!-- HOW DO I GET THE IMG URL -->
</figure>
<div class="gallery__text">
<h2 class="gallery__heading">Gallery</h2>
<p class="gallery__title">{{ exhibit.fields.title }}</p>
<h3 class="gallery__artist">{{ exhibit.fields.artist }}</h3>
<p class="gallery_onview">On View</p>
<p class="gallery__dates">{{ exhibit.fields.date }}</p>
<p class="gallery__description" *ngIf="exhibit.fields.description.content[0].content[0].value">{{ exhibit.fields.description.content[0].content[0].value }}</p>
</div>
</section>
Bellow is the JSON of one item the items array:
And here the image that is supposed be part of the above item, but is placed in a different array called includes:
Below is the console.log output of one exhibit:
You don't need to access the includes array. The Contentful SDK will automatically resolve the fields that contain a reference.
For your image issue, I think you're missing the field name for your file field: exhibit.fields.YOUR_FIELD_NAME.fields.file.url
For your description field, I would recommend using ngx-contentful-rich-text to parse the rich text into HTML.

retrieving images from data return in vuejs

im trying to display som images in my code , already stored in my data in this way:
<div >
<tr v-for='(ships,index) in destroyedShipBox' :key='index'>
<td>{{ships}}</td>
<div v-for='(links,index1) in destroyedShipBoximages' :key='index1'>
{{links.type==ships?links.src:''}}
</div>
</tr>
</div>
where my data stores this arrays of objects:
data() {
return {
destroyedShipBox:['PatrolBoat','Destroyer'],
destroyedShipBoximages:[
{type:'PatrolBoat',src:require('../assets/patrolBoatHorizontalView.png')},
{type:'Submarine',src:require('../assets/submarineHorizontalView.png')},
{type:'BattleShip',src:require('../assets/battleshipHorizontalView.png')},
{type:'Carrier',src:require('../assets/carrierHorizontalView.png')},
{type:'Destroyer',src:require('../assets/destroyerHorizontalView.png')},
],
}
the destroyedShipBox gets fill automatically with some JSON already fetched then destroyedShipBoximages is just a collection of all type of ships in game as well as a image of its according to its type.
Thus my logic in the html template wants to set an image attuning with the kind of ships i already got in the destroyedShipBox array , but the the final result is this
PatrolBoat /img/patrolBoatHorizontalView.63b25d8d.png----->should be an image instead of this
Destroyer /img/destroyerHorizontalView.396ed25f.png ----->should be an image instead of this
simply the image don't appear...
Any advice about how to solve this problem...
thanks in advance!!!!
you can also ease up your template logic and have only one if condition if there is a 1:1 relation between ships and their images with the following computed property:
computed: {
shipsWithImages() {
return this.destroyedShipBoximages.filter((value) => {
if(this.destroyedShipBox.includes(value.type)) {
return value;
}
})
},
}
Cheers,
ewatch
You should assign links.src to src attribute of img tag like this:
<div>
<tr v-for='(ships,index) in destroyedShipBox' :key='index'>
<td>{{ships}}</td>
<td>
<div v-for='(links,index1) in destroyedShipBoximages' :key='index1'>
<img :src="links.src" v-if="links.type==ships"/>
</div>
</td>
</tr>
</div>

Meteor helper function exception when retrieving the count of all users

On my website I'm trying to display the number of users registered. The problem is that I get a long exception on render. My question is how do you do this dynamically instead of statically?
The code works on start up but if I switch pages and come back it defaults to a blank. The code follows:
Template.Home.helpers({
UserAmount: function() {
var Count = Meteor.users.find().count();
document.getElementById("UsersSignedUp").innerHTML = Count;
console.log("Users-helper: "+Count);
}
});
the following is now the HTML section on the home page
<section class="home-main">
<div class="container">
<div class="stats">
<div class="row">
<div class="col-md-4">
<label id="UsersSignedUp">{{UserAmount}}</label>
<span>Users</span>
</div>
<div class="col-md-4">
0
<span>Listings</span>
</div>
<div class="col-md-4">
0
<span>Matches</span>
</div>
</div>
</div>
</div>
</section>
I was able to make an onRender function to supplement the error but I'd rather not have to rely on it. I know that listings and Matches are both set to 0 but if I can fix this error the others will follow the same format.
This is the exception:
[Log] Exception in template helper: UserAmount#http://localhost:3000/Nomad.js?1c729a36a6d466ebe12126c301d77cc72299c832:56:47 (meteor.js, line 888)
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2880:21
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1651:21
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2928:71
_withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:16
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2927:52
call#http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:172:23
mustacheImpl#http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:109:30
mustache#http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:113:44
http://localhost:3000/template.Nomad.js?68e12845c8ef55042e39b4867426aab290c3711d:95:30
doRender#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2011:32
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1865:22
_withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:16
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1864:54
_withCurrentView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:16
lookup:UserAmount:materialize#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1863:34
_compute#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:327:36
Computation#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:243:18
autorun#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:566:34
autorun#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1875:29
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2005:17
nonreactive#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:593:13
_materializeView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2004:22
materializeDOMInner#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1476:31
_materializeDOM#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1428:26
http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2040:46
nonreactive#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:593:13
_materializeView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2004:22
render#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2296:25
insert#http://localhost:3000/packages/iron_dynamic-template.js?d425554c9847e4a80567f8ca55719cd6ae3f2722:522:15
insert#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:1632:22
maybeAutoInsertRouter#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:1622:20
If there is any other information I should provide please let me know.
Try using this as the helper instead:
Template.Home.helpers({
UserAmount: function() {
return Meteor.users.find().count();
}
});
The idea is this helper is called UserAmount so the value it returns on the Home template should replace itself into the handlebars expression {{UserAmount}}
You don't have to do the heavy lifting in changing the DOM yourself. Meteor probably gets confused as to why the dom is changing when it tries to change it and it gives up that error.

html parse jquery function

I;ve got troubles coding a function.
Here's the situation :
I've got divs like that :
<div class='sound'>
<img src='$artwork' class='artwork' />
<div>
<p class='genre'>$genre</p>
<p class='title'>$title</p>
<i href ="$link" class='link'></i>
</div>
<div class="sound' ... ...
and many others like that.
I'd like to make a button that get all the divs the content with the classname 'sound'
and use this with this function of the player's API :
$.fullwidthAudioPlayer.addTrack(trackUrl, title, meta, cover, linkUrl);
I tried this function in jquery, it gets the datas not parsed :
$('.sound').each(function() {
$.fullwidthAudioPlayer.addTrack($('.content',this).text());
So, I'd like to know the right way to do it !
Thank you so much in advance !
You have to query for each one separately:
var trackUrl = $('.link', this).attr('href'),
title = $('.title', this).text(),
meta = $('.genre', this).text(),
cover = $('.artwork', this).attr('src'),
linkUrl = null;
$.fullwidthAudioPlayer.addTrack(trackUrl, title, meta, cover, linkUrl);

Categories