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

Auto refresh - Responsive grid #5

Open adrianmg opened 12 years ago

adrianmg commented 12 years ago

It would be nice if the grid system detect any change on size / position so it refresh automatically the entire grid.

Good job by the way!

MartinWeb commented 12 years ago

Yeah i think the same. Or an other solution it will be to put the widget_base_dimensions in percentage. I hope there will a new version for the responsive mode.

vauvarin commented 12 years ago

+1 for a responsive version of gridster.js

Congratulation, very nice work.

vieron commented 12 years ago

I have doubts about how to implement the logic to reposition the widgets that dont fit on the viewport. I don't know the order expected by the user after the resizing. Perhaps the order is not significant, and it is enough to fill holes from the top left. I think it also depends on the content…

And... what happens if there is a widget that takes 4 columns wide (about 650px)? Split the widget is not an option ;)

Thanks for the feedback!

lukeholder commented 12 years ago

I think that this goes against the whole idea of a user defined draggable layout. You want to have control over layout, that is why you are dragging.

I OP is referring to functionality like: http://isotope.metafizzy.co/

I think what is more important is user modifiable sizes of the widgets at the ratios defined in widget_base_dimensions with reflow based on a collision ater resize.

I have requested this in issue #15

ghz commented 12 years ago

Yes, it would be a great feature

sbward commented 12 years ago

For some developers, responsiveness is more important than preserving the grid's arrangement. It would make sense to implement this as an optional feature. I, for one, would certainly use it. Without this feature, we can't include this library into any responsive application whatsoever!

goldnead commented 12 years ago

+1 for optional responsiveness! Like said, The grid itself doesn't has to preserve it's arrangement. But it would be great, if gridster would support a fluid layout, or a function which can change the col sizes and the layout if the window resizes. For example, if you're watching a responsive website/application on a smartphone, in most cases the layout is only built with on column. So, a function which makes the grid one-columned would be enough to display properly on a smartphone device.

jessebsmith commented 12 years ago

+1 Using this with twitter bootstrap with a fluid layout is quiet useless. Such a awesome tool and idea!

davidgreiner commented 12 years ago

+1 for responsiveness! Everything has been said. I think this would be great in this world of liquid layouts.

AndyAyrey commented 12 years ago

Intelligently calculating layout on resize does sounds like something that could get really messy, particularly if you're saving/loading positions from a database. In that case, you would be better off with Isotope and a simple index of the order items should appear in. (which could be written to/read from with some jQuery Sortable based monstrosity, perhaps?)

For Gridster, though, I propose an alternative: what if there was the option to expand horizontally (with lots of extra columns) rather than vertically? In this case, you elegantly handle different screen sizes simply by revealing/hiding the extra content based on the viewport size. No crazy re-arrange logic required and just look at Metro or the new Myspace (https://new.myspace.com/) to see how great it can look.

masondominic commented 11 years ago

The way I kind of implement this is to call the gridster init method when the browser re-sizes. This pushes any widgets that no longer fit on the screen into a new location. I then save the new positions by calling the serialize method.

mcat commented 11 years ago

Check out this Pull request for this functionality.

https://github.com/ducksboard/gridster.js/pull/77

thomaskbird commented 11 years ago

Does anyone know if this has been implemented thus far? It would be nice to see the grid become responsive but also to have a built in method for resizing the wrapper and elements within.

galievruslan commented 10 years ago

Gridster wonderful. There are some solutions to add flexibility???

cjindustries commented 10 years ago

+1 I'm a new user - what a fantastic library! I'd love to see some responsiveness built-in too as an optional feature or a method we can call in resize handlers. Cheers!

zeldich commented 10 years ago

+1 for responsiveness!

NirHemed commented 10 years ago

+1

YOranski commented 10 years ago

+1. Responsiveness will be nice.

skozz commented 10 years ago

+1

nadeesha commented 10 years ago

I built a plugin to convert the gridster layouts to bootstrap - thereby achieving responsiveness. It's still largely in the works, but I think I've got a few things right. If anyone's ineterested: gridster-bootstrap

acesarewld commented 10 years ago

I wish there was some new news on this, but I'll jump into the same group - it'd be great if it were responsive!

gcphost commented 10 years ago

based on what mcat said a year ago, response #77 i was able to get a responsive layout https://github.com/gcphost/gridster-responsive

mine uses bootstrap and panels and has max/min/close and edit title color features since I wan ted this for a dash board.

ManiAkasapu commented 10 years ago

My Idea for responsiveness: 1) I am considering all my widgets should take same width (not pixel but percentage). 2) Define how many widgets per row (2 takes 50%, 4 takes 25% etc) 3) Define break points (Large device, medium device, small device, extra small device like bootstrap. 4) For each break point define number of widgets per row.

We can have attributes " layout: fixed-responsive (And variable-non responsive) " And "Breakpoints" If layout = fixed-responsive then all the above points apply.

Breakpoints should be defined by user some thing like:

breakpoints: { large: 4, --------# if width is > 1200 # medium: 3, ----# if width is > 1024 , < 1200 # small: 2, -------# if width is < 1024 , > 480 # mobile: 1 ------# if width < 480 # } Note: The above are not exact measures.

Responsive does not make any sense (And very hard to handle) if widgets are drag-able and different sizes. So, the responsiveness will applies only if the grid in evenly distributed.

What do you say ?

Misiu commented 10 years ago

:+1: on this!!

Gronan commented 10 years ago

:+1:

micheledisalvatore commented 10 years ago

This is my solution to make gridster responsive:

Add this to your sass:

$totalCols: 12 !default

.gridster
  & > *
    padding: 0
    width: 100%!important

  .gs-w
    list-style: none

    @for $i from 1 through $totalCols
      &[data-sizex="#{$i}"]
        width: 100% / $totalCols * $i

      &[data-col="#{$i}"]
        left: 100% / $totalCols * ($i - 1)

I'm working on media queries that will change each [data]

gedion commented 10 years ago

@micheledisalvatore,

I am figuring out the same issue to make gridster size and format remain intact according to the screen size. What exactly does the above CSS do? You mentioned about the media queries, I am looking forward for an update on media query. Thanks.

yuribit commented 10 years ago

Is there someone who is working on this functionality?

micheledisalvatore commented 10 years ago

tomorrow I'll make an example. Stay tuned :)

vampolo commented 10 years ago

Tomorrow was 24 days ago... :( is this project dead ?

Misiu commented 10 years ago

@micheledisalvatore could You please show us an example?

micheledisalvatore commented 10 years ago

I'm sorry, but at the end my team decided abandoning gridster.

Misiu commented 10 years ago

@micheledisalvatore if this isn't a secret could Yous write what have You chosen instead of Gridster?

micheledisalvatore commented 10 years ago

We decided migrating to bootstrap standard with an adapter from gridster to bootstrap, but this adapter is only a temporary solution. Here my code with angular:

<div data-ng-repeat="widget in layout" data-ng-class="{'col-sm-6': (widget.width < 6), 'col-sm-12': (widget.width > 5), 'clear-left': (widget.yposition != layout[$index - 1].yposition)}" class="layout-element col-xs-12 col-md-{{widget.width}}"></div>
        var temp = [];
        angular.forEach(layout, function(value, key) {
          value.orderNumber = value.xposition + (10 * value.yposition);
          return temp.push(value);
        });
        layout = $filter('orderBy')(temp, 'orderNumber');
yuribit commented 10 years ago

Why did you guys decide to leave Gridster? Only because it's not responsive?

mimhof1 commented 9 years ago

Greetings..so I've made it to this thread and after reading, here is what I did and it is working, I have to warn you, it is exactly a hack. I'm posting it here because I want to see if I can further reduce the code by using an api method already inside gridster that I have not discovered...let me know.

I added an on window.resize function and when it detects a resize ( more accurately, it waits for the resize to be completed) then fires a gridResize function that does the following: a) builds a serialized account of current layout...serwidget b) rebuilds the div to destroy the old on: $(".gridster").html('

');
c) attaches to the newly built div ... $(".gridster > ul").gridster({....... etc as normal d) uses the $.each(serwidget, function(i, widget){ ....to .add_widget.apply(gridster, serwidget)

So.. it "acts" responsive because it forces it to go rebuild coords from the new view. Steps b,c,d could actually be replaced if there was a gridRebuild or gridRedraw function and just send back in the serwidget.

Any thoughts?

ben69uaq commented 9 years ago

This is a Proof Of Concept which shows that Gridster can support responsive design: http://dbwgridster.herokuapp.com/index-0.5.6.html

Please contact me if you need any information about this POC

megaroeny commented 9 years ago

@ben69uaq Wow! Is there an easy way we can see the source code? Is all the work in main.js? Or did you do anything else in HTML/CSS specific?

ben69uaq commented 9 years ago

@jaminroe all the job is done in main.js of course you have to adapt you css in order to get a responsive design

megaroeny commented 9 years ago

Right. I'd just use a framework like Foundation or Bootstrap's grid.~ReonySent using CloudMagicOn Tue, Mar 31, 2015 at 12:48 PM, ducksboard/gridster.js reply@reply.github.com wrote: @jaminroe all the job is done in main.js of course you have to adapt you css in order to get a responsive design

—Reply to this email directly or view it on GitHub.

emente commented 9 years ago

the "gridster is so broken i can only apply a band aid" approach for bootstrap+gridster:

@media (max-width: 992px) { .gridster .gs-w { position:relative; top:auto; left:auto; margin-bottom:10px; width:645px; } } @media (max-width: 768px) { .gridster > ul { width:auto !important; } .gridster .gs-w { position:relative; top:auto; left:auto; margin-bottom:10px; width:auto; margin-right:40px; } }

gridster is abandonware, gridstack (based on gridster) is responsiveness enabled.

pankajvishwani commented 8 years ago

To make it responsive, I changed "width", and "left" stylesheet to use calc() instead of fixed values. This approach seems to be working fine for me. But this will NOT work with dynamic grid width, i.e., dynamic number of columns.

Here are the two functions you need to override:

` generate_stylesheet: function(opts){ var styles = ''; var max_size_x = this.options.max_size_x || this.cols; var max_rows = 0; var max_cols = 0; var i; var rules;

                opts = opts || (opts = {});
                opts.cols = opts.cols || (opts.cols = this.cols);
                opts.rows = opts.rows || (opts.rows = this.rows);
                opts.namespace = opts.namespace || (opts.namespace = this.options.namespace);
                opts.widget_base_dimensions = opts.widget_base_dimensions ||
                        (opts.widget_base_dimensions = this.options.widget_base_dimensions);
                opts.widget_margins = opts.widget_margins ||
                        (opts.widget_margins = this.options.widget_margins);
                opts.min_widget_width = (opts.widget_margins[0] * 2) +
                        opts.widget_base_dimensions[0];
                opts.min_widget_height = (opts.widget_margins[1] * 2) +
                        opts.widget_base_dimensions[1];

                // don't duplicate stylesheets for the same configuration
                var serialized_opts = $.param(opts);
                if($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0){
                    return false;
                }

                this.generated_stylesheets.push(serialized_opts);
                Gridster.generated_stylesheets.push(serialized_opts);

                /* generate CSS styles for cols */
                for (i = opts.cols; i > 0; i--){
                        styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' +
                                ('calc(' + i * (100/opts.cols) + '% + ' + opts.widget_margins[0]) + 'px); }\n');
                }
                styles += (opts.namespace + ' [data-col="1"] { left:' + opts.widget_margins[0] + 'px; }\n');

                /* generate CSS styles for rows */
                for (i = opts.rows; i >= 0; i--) {
                        styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' +
                                ((i * opts.widget_base_dimensions[1]) +
                                (i * opts.widget_margins[1]) +
                                ((i + 1) * opts.widget_margins[1]) ) + 'px; }\n');
                }

                for (var y = 1; y <= opts.rows; y++) {
                        styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' +
                                (y * opts.widget_base_dimensions[1] +
                                (y - 1) * (opts.widget_margins[1] * 2)) + 'px; }\n');
                }

                for (var x = 1; x <= max_size_x; x++) {
                        styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' +
                                'calc(' + x * (100/opts.cols) + '% - ' + (opts.widget_margins[0] * 2) + 'px); }\n');
                }

                this.remove_style_tags();

                return this.add_style_tag(styles);
            },

            set_dom_grid_width: function(cols){
                if(typeof cols === 'undefined'){
                    cols = this.get_highest_occupied_cell().col;
                }
                var max_cols = (this.options.autogrow_cols ? this.options.max_cols :
                this.cols);

                cols = Math.min(max_cols, Math.max(cols, this.options.min_cols));
                this.container_width = cols * this.min_widget_width;
                this.$el.css('width', "100%");
                return this;
            }

`