Draggable not applied to nested component - javascript

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

Related

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

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>

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

Conditional Root Tag on Vue Component

My Question
I have a Vue component that renders content like so:
<template>
<div class="item">
<h1>{{ title }}</h1>
<p>{{ contents }}</p>
<!-- Lot's of other stuff... -->
</div>
</template>
<script>
// export default...
</script>
<style lang="scss">
// style...
</style>
Note the contents within the div...
In some circumstances, I need to change <div class="item"> to <a class="item">. With that in mind, is there a way to conditionally change the tag (e.g. a, div) for the root element of a Vue component?
Research
I have searched around online and was able to find something about using the render function like so:
render (createElement) {
return createElement(this.tag, {}, this.$slots.default);
}
The issue I have with the above is that it implies that I need two separate components, for example; Item.vue and ItemTag.vue. Surely there is a way to do this with one component?
I believe you could use is:
<div :is="useA ? 'a' : 'div'">
...
</div>
This isn't quite what the docs suggests it's for but it does seem to have the desired effect.
https://v2.vuejs.org/v2/api/#is
Using a render function instead wouldn't necessarily require you to have two components but it would need you to rewrite your entire template as a render function.

Angular 4 - Printing a unique and dynamic value on an HTML with Angular's *ngFor

So i am presented with a task from the client to make a loop of div elements draggable. To make this happened, i have used angular2-draggable to make it possible.
It works on a single div that has not been looped over, as seen below:
<div ngDraggable [handle]="DemoHandle" class="card">
<div #DemoHandle class="card-header">I'm handle. Drag me!</div>
<div class="card-block">You can't drag this block now!</div>
</div>
But the question is, how to i make take this code an place it into an *ngFor loop in Angular (maybe just like the code seen below)?
<div *ngFor="let myValue of myValues" [handle]="{{myValue.id}}">
<div #{{ myValue.id }} >{{ myValue.title }}</div>
</div>
The problem here is that both this [handle]="DemoHandle" and #DemoHandle (Im talking about the DemoHandle value) needs to be unique. But i have no way to print a unique value similar to this code below:
<div *ngFor="let myValue of myValues">
<div [attr.id]="myValue.id" >{{ myValue.title }}</div>
</div>
How do i go about this?
Template reference variables are unique within enclosed view. *ngFor directive create embedded view for each item so that template reference variable is unique there.
So just try the following:
<div ngDraggable *ngFor="let item of [1,2,3]" [handle]="DemoHandle">
<div #DemoHandle class="card-header">I'm handle {{item}}. Drag me!</div>
...
</div>
Ng-run Example

React Conditional Rendering With Bootstrap, Keeping Layout In Tact

I'm working on a project using React and Bootstrap. I have one big bar graph and 2 little boxes that all need to sit horizontally together.
Here's how it should work.. expand the pen window to see them sit horizontally together (the correct way):
https://codesandbox.io/s/lO9rvrBYM
However I need some conditional rendering logic in there in case there is no data and I don't want to display the big bar graph. Check that out here:
https://codesandbox.io/s/ELLzLo3g
In the example with conditional rendering it can no longer properly position the elements. They sit permanently on top of one another.
I think it has to do with line 69. I need to render that graph with one less closing </div> to keep the horizontal layout in tact, but that throws a syntax error.
Anyone great at Bootstrap have any tips to solve this?
First of all, your question & samples are not that clear on what you want to achieve, so my answer might be missing the point :)
You basically want a 2 column layout mixed with a conditionnal display for the first column.
The column display will be handled fully by bootstrap (and you actually messed up a lot with your columns here), the conditionnal display should be managed through your component state.
First your layout should look like somthing like that :
<div className='row'>
<div className='col-sm-7'>
<div> [your chart here] </div>
</div>
<div className='col-sm-5'>
<div> [your first block here] </div>
<div> [your second block here] </div>
</div>
</div>
Then you need a boolean value inside your component state that will decide whether or not the chart should be displayed. Lets assume you store this information in this.state.showChart
<div className='row'>
{this.state.showChart ?
<div className='col-sm-7'>
<div> [your chart here] </div>
</div>
: '' }
<div className='col-sm-5'>
<div> [your first block here] </div>
<div> [your second block here] </div>
</div>
</div>
If this is insuffisant, try to improve your explanations a bit and I can work on your sandbox samples directly :)

Categories