Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read property 'element' of null when using vue component #647

Closed
alexeigs opened this issue May 28, 2019 · 15 comments
Closed

Cannot read property 'element' of null when using vue component #647

alexeigs opened this issue May 28, 2019 · 15 comments

Comments

@alexeigs
Copy link

Wrapping a div works while wrapping any vue component leads to an error for me. This code is within a nested tree of vue components of which one of the parents also uses draggable (without any issue there).

<draggable
      :list="items"
      tag="v-layout"
      class="row wrap fill-height justify-space-around align-center"
      ghost-class="draggable__ghost-class"
      :group="{ name: 'actions' }"
    >
      <v-flex v-for="(action, i) in items" :key="i" class="action-plan__action__row__edit dropitem" xs4>
        <!-- LEADS TO ERROR: <v-card style="height: 100px; width: 100px; background: green"></v-card> -->
        <div style="height: 100px; width: 100px; background: green"></div>
      </v-flex>
</draggable>

changing the div to a vue component like v-card results in an Cannot read property 'element' of null error when starting to drag.

@David-Desmaisons
Copy link
Member

Could you create a jsfiddle?

@David-Desmaisons
Copy link
Member

David-Desmaisons commented May 28, 2019

Vue component are also supported so this linked to your specific example.

@alexeigs
Copy link
Author

alexeigs commented May 28, 2019

See the following example:

        <v-layout row wrap>
          <v-flex
            v-for="(row, i) in rows"
            :key="i"
            xs12
          >
            <v-card>
              <draggable
                :value="rows"
                tag="v-layout"
                class="row wrap fill-height justify-space-around align-center"
                ghost-class="draggable__ghost-class"
                :group="{ name: 'actionRows' }"
                @input="onChangedRows($event)"
              >
                <v-flex
                  v-for="(item, itemIndex) in row"
                  :key="itemIndex"
                  class="action-plan__action__row__edit dropitem"
                  xs12
                >
                 <!-- div WORKS -->
                  <div style="min-height: 100px; background: brown">TEST</div>
                 <!-- but v-card and other vue components trigger the ERROR -->
                  <v-card style="min-height: 100px; background: brown">TEST</v-card>
                </v-flex>
              </draggable>
            </v-card>
          </v-flex>
        </v-layout>

Does this help or do you need more to dig into it?

@David-Desmaisons
Copy link
Member

Not really.
I can not debug without jsfiddle.

Note that you need to use or list or v-model.
value prop without updating the list on input will not work

@alexeigs
Copy link
Author

Sorry, it somehow did not copy the @input. That mechanism actually works. I'm also figuring out how to setup the right jsfiddle in the meantime though.

@alexeigs
Copy link
Author

alexeigs commented May 28, 2019

@David-Desmaisons I created a jsfiddle including some examples:

https://jsfiddle.net/lexixon/nf97erqx/64/

I think I have narrowed down the issue. It occurs whenever there is only one item left within a draggable section and you try to move it and it depends whether it was dynamically added or not (see all examples in jsfiddle). Potentially it has something to do with the nesting but I hope there's a simple explanation what triggers it and how to prevent it.

Error:

Uncaught TypeError: Cannot read property 'element' of null
    at VueComponent.onDragStart (vuedraggable.js:380)
    at mt.<anonymous> (vuedraggable.js:37)
    at Ct (Sortable.min.js:3)
    at mt._dragStarted (Sortable.min.js:3)

@alexeigs
Copy link
Author

@David-Desmaisons or anyone else any idea what I'm doing wrong or how the issues in the illustrated examples can be explained?

@David-Desmaisons
Copy link
Member

@alexeigs , I am investigating, this is something that can be correct on vue.draggable side.
Currently as a by-pass you can use a div with the required class instead of a v-layout and it will work.

@0xShammah
Copy link

0xShammah commented Jun 11, 2019

I've had the same issue with this error popping up when reordering nested properties.
I can confirm that wrapping my Vue component in a <div> fixed the error.

So for example, the following HTML code:

<draggable :list="page.children" v-bind="dragOptions">
    <transition-group name="list" tag="ul" v-if="hasChildren(page)" class="children">
        <menu-node :active-page="activePage"
                              v-for="child in page.children"
                              :page="child"
                              :key="child.id">
        </menu-node>
    </transition-group>
</draggable>

had to be replaced by:

<draggable :list="page.children" v-bind="dragOptions">
    <transition-group name="list" tag="ul" v-if="hasChildren(page)" class="children">
        <div v-for="child in page.children" :key="child.id">
            <menu-node :active-page="activePage" :page="child">
            </menu-node>
        </div>
    </transition-group>
</draggable>

@alexeigs
Copy link
Author

alexeigs commented Jun 13, 2019

@David-Desmaisons @Shammah

How would that work in my case exactly to transfer the full v-flex class on the div and let the v-layout and v-flex behave in the same way? Could someone share that bit of code?

@0xShammah
Copy link

0xShammah commented Jun 13, 2019

What worked in my case was to move the v-for out of my Vue component and into a <div> one layer up. So in your case that would be

<draggable :value="rows"
           tag="v-layout"
           class="row wrap fill-height justify-space-around align-center"
           ghost-class="draggable__ghost-class"
           :group="{ name: 'actionRows' }"
           @input="onChangedRows($event)">
  <div v-for="(item, itemIndex) in row" :key="itemIndex">
    <v-flex class="action-plan__action__row__edit dropitem" xs12>
            <v-card style="min-height: 100px; background: brown">TEST</v-card>
    </v-flex>
  </div>
</draggable>

I hope this fixes the issue for you as well.

@alexeigs
Copy link
Author

@Shammah The issue is that this will break the dependency of v-layout and v-flex. The flex boxes will not behave anymore as they do being directly nested in the layout which actually has been my challenge in finding a workaround for this issue.

@0xShammah
Copy link

0xShammah commented Jun 14, 2019

Hmm, I thought I fixed it, but it seems to have only solved a few of my cases. I now get the same error, even when wrapping in a div. My use case to reproduce:

  1. Start with an array with one element.
  2. Add a nested child to that element, thus the original element will become a parent.
  3. Move the child out of its parent.

The error does not happen if you start with an already existing list that contains both parent and child nested.

@0xShammah
Copy link

0xShammah commented Jun 14, 2019

My colleague found a fix, by simply forcing a Vue rerendering when the amount of children change. This is achievemed by supplying a :key to the draggable.

<draggable :list="myArray" :key="myArray.length"></draggable>

Does this work for you as well?

I noticed that the :key thingy was also applied to the <div> in my previous post, which is why I thought that the div itself fixed some of my cases.

Edit:
In your case that would be

<v-card>
    <draggable :value="rows" :key="rows.length">

David-Desmaisons added a commit that referenced this issue Jun 20, 2019
@David-Desmaisons
Copy link
Member

Corrected in version 2.22.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants