ducksboard / gridster.js

gridster.js is a jQuery plugin that makes building intuitive draggable layouts from elements spanning multiple columns
http://gridster.net/
MIT License
6.03k stars 1.2k forks source link

After calling remove_all_widgets, then adding more widgets, I can't drag a widget where an old widget once was. #271

Open thecoleorton opened 10 years ago

thecoleorton commented 10 years ago

After calling remove_all_widgets(), then adding more widgets, I can't drag a widget where an old widget once was.

For example, if I create a grid with 2 rows and 3 columns like so:

+-----+-----+----+
|  1  | 2  |  3 | 
+-----+-----+----+
|  4  | 5  |  6 | 
+-----+-----+----+

Then call remove_all_widgets(), then recreate the same grid as above, I can't drag any widget onto another widget without getting the below errors (multiple times):

Uncaught TypeError: Cannot read property 'row' of undefined

I can however, move a widget below into, say "the third row", onto 7, 8, and 9.

Thanks in advance for any help.

boyzoid commented 10 years ago

I get the same error when I remove a single widget and then put it back.

I can add new widgets without issue, but trying to re-add one that was removed throws the same 'Cannot read property 'row' of undefined.

m-schrepel commented 10 years ago

I am having the same issue as boyzold.

simplenotezy commented 10 years ago

I am experinceing the exact same issue here. What up?

simplenotezy commented 10 years ago

Has anyone been able to look at the issue? I experience the exact same thing. You don't have to create even, just use remove_widget, to remove all the widgets. Then afterwards, if you drag around a box, the error will show up.

It happens when row 1 is full, and you move from row 2 (after they have been removed) to row 1.

simplenotezy commented 10 years ago

If you by incident .init() two times, this will happen it seems.

rept commented 10 years ago

It's in this part:

fn.empty_cells = function(col, row, size_x, size_y, $exclude) {
    var $nexts = this.widgets_below({
        col: col,
        row: row - size_y,
        size_x: size_x,
        size_y: size_y
    });

    $nexts.not($exclude).each($.proxy(function(i, w) {
        var wgd = $(w).coords().grid;

wdg will be undefined...

miztizm commented 9 years ago

same here with

   $(document).on('click', '#red', function() {
    gridster.remove_widget( $(this).parent());
    });

Uncaught TypeError: Cannot read property 'row' of undefined // var next_row = el_grid_data.row + el_grid_data.size_y - 1;

and with this

  $(document).on('click', 'li.gs-w', function(){
  $(this).parents('li.gs-w').addClass('deleted');
  gridster.remove_widget($(this).parents('li.gs-w'));
   })

Uncaught TypeError: Cannot set property 'width' of undefined // jquery.gridster.js:54 adding works fine

bondt commented 9 years ago

@canfiax +1

bondt commented 9 years ago

Haven't gotten any luck when adding Simply add a namespace, as is done in the example: http://gridster.net/demos/multiple-grids.html -- Anyone else has?

sniperwolfpk5 commented 9 years ago

I am using single instance. I am getting same issue. The solution given by @bondt is not working with me. Please if some one have solution post it here.

thx in advance

sniperwolfpk5 commented 9 years ago

Bump

OscarEriksen commented 9 years ago

Also stuck on this problem. Help please.

sniperwolfpk5 commented 9 years ago

I have temporary solution. example <div class="gridster"> <ul> </ul> </div> Once I delete all widgets then what i do is delete <ul> as well and re-add it like $('.gridster').html(''); $('.gridster').append(<ul></ul>);

But this case is only working if you want to delete all the widgets.

OscarEriksen commented 9 years ago

Alright, so I fiddled a bit with this. Managed to find a VERY simple workaround:

draggable: {
    stop: function (event, ui) {
        Dashboard.update('widgets', { widgets: app.grid.serialize_changed() });
    }
},
serialize_params: function($w, wgd) { 
    var widget;
    widget = (typeof wgd === 'undefined') ? $($w).data() : wgd;

    widget_object = {
        id:     $($w).data('id'), 
        col:    widget.col, 
        row:    widget.row, 
        size_x: widget.sizex, 
        size_y: widget.sizey, 
    }

    return widget_object;
}

Edit: shortened it.

Maybe if someone has the time you could apply the fix to its core-code and make a pull request?

parliament718 commented 8 years ago

@sniperwolfpk5 thanks for posting the fix. $('.gridster ul').empty() sufficed for me. The following "cleanup routine" seems to work the best:

gridster.remove_all_widgets();
gridster.destroy();
$('.gridster ul').empty();
jvelezc commented 8 years ago

1+ please fix it on the underlying library with @OscarEriksen fix.

If you invoke removeWidget("#something"); Then right after invoke removeWidget("#somethingelse");

Then you try to add_widget("#something"); You get the same error.

My work around:


  let svc = new GridSterService(); //TypeScript class I will not bore you with details but it gives me 
//the a gridster instance. 
  $('#vrxAddOpenPanel').click(() => {
            if (!$("#openPanel").length) {
                createOpenPanelWidget(svc);
                //Because there something broken with gridster I choose to invoke a jquery click event
                //https://github.com/ducksboard/gridster.js/issues/271
                //Which circumvents the issue all together.
                $("#vrxAddWelcomeMessageWidget").trigger("click");
            }
        });

Which triggers a jquery event to actually handle things properly instead of the javascript nonsense exception.


  $('#vrxAddWelcomeMessageWidget').click(() => {

            if (!$("#welcomeMessageWidget").length) {

                createWelcomeMessage(svc);
            }
        });

and to remove.

 $('#vrxRemoveOpenPanel').click((element: HTMLElement) => {
            if ($("#openPanelWidget").length) {
                svc.removeWidget($("#openPanelWidget"));

                $("#vrxRemovedWelcomeMessageWidget").trigger("click");
            }

        });
  $('#vrxRemovedWelcomeMessageWidget').click(() => {
            if ($("#welcomeMessageWidget").length) {
                svc.removeWidget($("#welcomeMessageWidget"));
            }
        });

Nasty but works.