VueJS: Do not show div if image doesn't exist - javascript

I am rendering some div and I have like to not show a div when an image is not there.
An example image is here: https://clips-media-assets2.twitch.tv/AT-cm%7C891283246-preview-480x272.jpg
I am thinking of something like this:
<div v-show="twItem.imageurl">{{twItem.title}}</div>
But it doesn't work. Any help would be appreciated.

This task is not primitive.
No matter if you use v-if or v-show, both compare the same thing, but the result is different. v-if="false" will not render the element at all, whilst v-show="false" will render it, but hidden. (display: none;)
The problem here is, that you simply check if the twItem.imageurl is set and NOT if the image was loaded.
What you might be able to do is using #load:
<template>
<div v-if="twItem.loaded">{{ twItem.title }}</div>
<image :src="twItem.imageurl" #load="twItem.loaded = true">
</template>
See here for a more detailed explanation: https://renatello.com/vue-js-image-loaded/

Use v-if instead of v-show.
<div v-if="twItem.imageurl">{{ twItem.title }}</div>

Related

JS closest/parent not working on loaded page

I'm working with a third-party code and I'm quite limited in terms of filtering a list of elements.
Each of these elements has this structure:
<div class="item-preview">
<div class="item-info">
<div class="tag">
<svg class="tag-public"></svg>
</div>
</div>
</div>
The only thing that changes is the svg class, so it's whether tag-public or tag-private. Depending on the user type that's checking the content, I'd like to hide it when it's tag-private. I've tried this:
$('.tag-private').closest('.item-preview').hide();
And this:
$('.tag-private').parents('.item-preview').hide();
But any of them works. The code uses React and the items are brought by JSON/AJAX, so I guess the problem is related to trying to modify the page once is loaded...
Any thoughts on how to make my JS "override" the original code? Thanks a ton.

Draggable not applied to nested component

In
https://codesandbox.io/s/vskdf
I have a template that is not rendered inside of my vuedraggable. Any ideas why?
InventorySectionGroup.vue:
<template>
<!-- this div renders -->
<div class="inventory-section-group">
<p>{{ itemSectionGroupProps.itemSectionCategoryName }}</p>
<div
v-for="group in itemSectionGroupProps.itemSectionCategoryItemList"
:key="group.itemSectionCategoryId"
>
<inventory-section-group-item :itemDataProps="group">
</inventory-section-group-item>
</div>
<!-- div doesn't render :-(
<draggable v-model="itemSectionGroupProps.itemSectionCategoryItemList">
<transition-group>
<div
v-for="group in itemSectionGroupProps.itemSectionCategoryItemList"
:key="group.itemSectionCategoryId"
>
<inventory-section-group-item :itemDataProps="group">
</inventory-section-group-item>
</div>
</transition-group>
</draggable> -->
</div>
</template>
Fixed errors related to comp. init:
https://codesandbox.io/s/y2cur?file=/src/components/InventorySectionDraggable.vue
Nested dnd can be replicated like:
https://codesandbox.io/s/priceless-perlman-n6psw?file=/src/components/MyContainer.vue
You have several errors in your code (browser console + ESlint), try fixing them, this will highlight several issues that may be blocking at some point.
As for your current issue, you do have some duplicated code: the block that is rendered and the one that is not. This is coming from the fact that the :key needs to be unique. Since your code is the same on the 2 blocks, the key is duplicated and only one is rendered I guess.
If you take the second block with it's
<div :key="group.itemSectionCategoryId">
And update it to some naive unique key like this
<div :key="`${group.itemSectionCategoryId + 1}`">
This will render the 2 blocks as expected I guess.
Here is the end result.
I've decided to go with nested draggable (build satellite data related to inventory groups and items):
https://codesandbox.io/s/x8ur4?file=/src/components/InventorySectionDraggable.vue
I still need to wrap the props around components.
Done:
https://codesandbox.io/s/rmh2n

Vuetify on mouseover toggle data object within array list

I am trying to implement a functionality which will toggle a Vuetify badge element for each array object within the list when the containing div has been hovered over.
I am able to create a hover like functionality within v-for array list using css, which is fairly simple but how can I achieve similar outcome using vuetify components? As I have not found any questions discussing this or demonstrating it, assume it is possible. Have looked into
First Link
Second Link
Second Link
And much more but have not found similar enough example of what I desire.
I have added codepen example of what I currently have.
The badge should only appear on the element which is currently being hovered, however all badge elements are being executed when any element has been hovered on.
CodePen Link
Maybe I have missed out something obvious
HTML Part
<template>
<div id="app">
<div>My favourite fruit is <b>{{favouriteFruit}}</b></div> <br>
<div v-for="(dataArray, index) in testArray" #click="setCurrent(dataArray.name)">
<v-badge
:color="computedFavFruitColor[index]"
right
v-model="show"
>
<template v-slot:badge>
<span><v-icon color="#ECF0FF">{{computedFavFruit[index]}}</v-icon></span>
</template>
<div #mouseover="show = true" #mouseleave="show = false">
{{dataArray.name}}
</div>
</v-badge>
</div>
</div>
</template>
Any further help of suggestions regarding this manner would be appreciated.
While the show property is global, it counts for every item you hover. You want to target the element you hover. So I suggest to keep track of the index of the item you hover like this: https://codepen.io/reijnemans/pen/JjPrayp?editors=1010
<div v-for="(dataArray, index) in testArray" #click="setCurrent(dataArray.name)">
<v-badge
:color="computedFavFruitColor[index]"
right
>
<template v-slot:badge>
<span v-if="show == index"><v-icon color="#ECF0FF">{{computedFavFruit[index]}}</v-icon></span>
</template>
<div #mouseenter="show = index" #mouseleave="show = null">
{{dataArray.name}}
</div>
</v-badge>
</div>
And show = null ipv show = true in data block of vue

Angular switch Outer Div based on boolean

I am using Angular 1.4.7 and need to do the following
<div ng-if="varIsTrue">
<div ng-if="!(varIsTrue)" my-custom-directive>
A lot of content
</div>
So basically, if the div is set only the proper div shows up. I tried do a few variations of this with ng-if and ng-show but I believe because how the browser renders the dom it is messing it up with the multiple divs, but that is the concept I am going for. Does anyone know how I can accomplish this?
You cannot do this you should have 2 closing tags
<div ng-if="varIsTrue">
</div>
<div ng-if="!(varIsTrue)" my-custom-directive>
A lot of content
</div>
or you will have to switch in my-custom-directive

Angular extending ui.bootstrap.progressbar to support some text on the progressbar

I'm using ui.bootstrap.progressbar (code here: https://github.com/angular-ui/bootstrap/blob/master/src/progressbar/progressbar.js) and I'm trying to extend it to support some custom HTML (or just text) on the progess bar. It looks something like this in vanilla Bootstrap:
<div class="progress">
<div class="bar" style="width: 60%;">This thing is at 60%</div>
</div>
http://plnkr.co/edit/WURPlkA0y6CK7HYt3GL1?p=preview
I'm new at directives, so I this is what I tried:
in ProgressBarController I added a label variable
var label = angular.isDefined($attrs.label) ? $scope.$eval($attrs.label) : '';
also modified the object the controller returns to include the label. Then added the bar.label in the directive's template like so:
<div class="progress">
<progressbar ng-repeat="bar in bars"
width="bar.to" old="bar.from"
animate="bar.animate" type="bar.type">
</progressbar>
{{bar.label}}
</div>
The progressbar appears just fine, but I cannot see the value of the label.
What am I doing wrong? Thanks in advance.
This turned out to be pretty straightforward.
All I had to do was:
modify the progress directive and add transclude: true
modify the progress.html to include an ng-transclude directive, like so
:
<div class="progress">
<span ng-transclude></span>
<progressbar ng-repeat="bar in bars" width="bar.to" old="bar.from" animate="bar.animate" type="bar.type"></progressbar>
</div>
After this, text put between the <progressbar></progressbar> will render on the progressbar, however some CSS modifications are also needed to make the text appear in the correct position.
But every progressbar and every text needs additional positioning, so this part is still not a complete solution. Setting the wrapper's position to relative and the <span>'s to absolute is one step but still not enough.

Categories