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

Replace grid / list view javascript with pjax #706

Closed
phpnode opened this Issue Aug 2, 2013 · 30 comments

Comments

Projects
None yet
9 participants
@phpnode

phpnode commented Aug 2, 2013

The JS for the list view and grid view in 1.1 is pretty convoluted and restrictive. For 2.0 I propose we scrap them entirely and instead support PJAX in the core - see https://github.com/defunkt/jquery-pjax for a widely supported implementation. This would allow any item on the page to be fetched via ajax, with nice URL and back button support. Since pjax sends a special HTTP header, we could detect this when rendering views and automatically send back a partial view without layout.

@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark Aug 2, 2013

Member

Sounds interesting. It's the lib used by github and rails. Actively supported.

Member

samdark commented Aug 2, 2013

Sounds interesting. It's the lib used by github and rails. Actively supported.

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester Aug 3, 2013

Contributor

In yii 1.1, we had a problem when binding handlers to elements that were part of grid/ list views. Basically, one had to care about re-binding whenever the grid/ list got replaced after an ajax call. Does pjax care about such requirements?

Contributor

bwoester commented Aug 3, 2013

In yii 1.1, we had a problem when binding handlers to elements that were part of grid/ list views. Basically, one had to care about re-binding whenever the grid/ list got replaced after an ajax call. Does pjax care about such requirements?

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 4, 2013

@bwoester as long as you use jQuery's delegate method, which you should be anyway, you won't have this issue.

phpnode commented Aug 4, 2013

@bwoester as long as you use jQuery's delegate method, which you should be anyway, you won't have this issue.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Aug 4, 2013

Member

+1 for using pajax. Will help with getting consistent urls.

Member

cebe commented Aug 4, 2013

+1 for using pajax. Will help with getting consistent urls.

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 4, 2013

Member

Any suggestion for the server side code design?

Member

qiangxue commented Aug 4, 2013

Any suggestion for the server side code design?

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Aug 4, 2013

Member

https://github.com/defunkt/jquery-pjax#server-side tells us there is a X-PJAX header to detect pajax request.

Member

cebe commented Aug 4, 2013

https://github.com/defunkt/jquery-pjax#server-side tells us there is a X-PJAX header to detect pajax request.

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 4, 2013

Member

Yes, I know that. I was asking how the server side code should be organized to respond to the partial data request. We only want to render the grid part upon such an update request, and we also don't want to repeat our code.

Member

qiangxue commented Aug 4, 2013

Yes, I know that. I was asking how the server side code should be organized to respond to the partial data request. We only want to render the grid part upon such an update request, and we also don't want to repeat our code.

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

@qiangxue there are scenarios where you'd want to be able to specify a separate layout to use for pjax requests - e.g. one containing a minimal <head> element with a title tag so that the page title gets updated correctly. Perhaps there should be a $ajaxLayout property on the controller that deals with this? it could default to null so that by default no layout gets rendered for ajax requests, but you can turn it on if you need it. Then it's simply a matter of looking for the header in render() and using either $this->layout or $this->ajaxLayout as a appropriate

phpnode commented Aug 5, 2013

@qiangxue there are scenarios where you'd want to be able to specify a separate layout to use for pjax requests - e.g. one containing a minimal <head> element with a title tag so that the page title gets updated correctly. Perhaps there should be a $ajaxLayout property on the controller that deals with this? it could default to null so that by default no layout gets rendered for ajax requests, but you can turn it on if you need it. Then it's simply a matter of looking for the header in render() and using either $this->layout or $this->ajaxLayout as a appropriate

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

@phpnode What if the view contains something else besides the grid?

A typical usage of ListView/GridView is: the page contains a search form or filter condition form; a user submits the form (via GET method) and the ListView/GridView should update accordingly. How should this problem be solved with pjax?

Member

qiangxue commented Aug 5, 2013

@phpnode What if the view contains something else besides the grid?

A typical usage of ListView/GridView is: the page contains a search form or filter condition form; a user submits the form (via GET method) and the ListView/GridView should update accordingly. How should this problem be solved with pjax?

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

@qiangxue we have a couple of options i think:

  1. We just send back the whole html in the response, so if there are multiple list views on the page, they will all be reloaded. This means slightly more work for the server but it will likely produce the most reliable results - the right views will always get updated and it can work out of the box, very simple to implement.
  2. We devise a way of binding pjax to 'scopes', via directives a bit like how angular js does it, e.g. we'd render a list view like this:
    <div x-pjax-scope>
        <ul class="list-view">
             <li>Some Item</ul>
        </ul>
    </div>

We can then use some simple javascript so that when a user clicks on a link, we look for a parent element with an x-pjax-scope attribute and ensure that only that element is replaced. This approach means less work for the server but probably more work for the developer. It would also be difficult to generate sensible URLs.

I think the first option is simpler, better, faster :)

phpnode commented Aug 5, 2013

@qiangxue we have a couple of options i think:

  1. We just send back the whole html in the response, so if there are multiple list views on the page, they will all be reloaded. This means slightly more work for the server but it will likely produce the most reliable results - the right views will always get updated and it can work out of the box, very simple to implement.
  2. We devise a way of binding pjax to 'scopes', via directives a bit like how angular js does it, e.g. we'd render a list view like this:
    <div x-pjax-scope>
        <ul class="list-view">
             <li>Some Item</ul>
        </ul>
    </div>

We can then use some simple javascript so that when a user clicks on a link, we look for a parent element with an x-pjax-scope attribute and ensure that only that element is replaced. This approach means less work for the server but probably more work for the developer. It would also be difficult to generate sensible URLs.

I think the first option is simpler, better, faster :)

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

I'm wondering what JavaScript code should be provided at the core by GridView and ListView.

In 1.1, the JS code mainly provides these features: 1. the ajax-based grid/list update (triggered by sorting, pagination, filtering etc.); 2. row selection of grid.

With pjax, it seems feature 1 no longer needs to be built in the old way. In fact, I'm wondering if we need to provide anything in the core because it is so easy for developers to directly use pjax and support ajax-update for grid/list. Or perhaps I missed something?

Member

qiangxue commented Aug 5, 2013

I'm wondering what JavaScript code should be provided at the core by GridView and ListView.

In 1.1, the JS code mainly provides these features: 1. the ajax-based grid/list update (triggered by sorting, pagination, filtering etc.); 2. row selection of grid.

With pjax, it seems feature 1 no longer needs to be built in the old way. In fact, I'm wondering if we need to provide anything in the core because it is so easy for developers to directly use pjax and support ajax-update for grid/list. Or perhaps I missed something?

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

Perhaps we can provide a more generic solution of using pjax. Something like this:

Pjax::begin();
...content here can be updated via pjax...
Pjax::end();

We could also support the concept of scopes as you proposed above.

Member

qiangxue commented Aug 5, 2013

Perhaps we can provide a more generic solution of using pjax. Something like this:

Pjax::begin();
...content here can be updated via pjax...
Pjax::end();

We could also support the concept of scopes as you proposed above.

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

I don't think we'd need any custom JS at all for these. We could rely totally on pjax

phpnode commented Aug 5, 2013

I don't think we'd need any custom JS at all for these. We could rely totally on pjax

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

I think having Pjax::begin()... will complicate things. I would imagine that most people will choose to leave pjax on for all page loads, because it offers a very good user experience. Having a getAjaxLayout() or similar would provide the same functionality

phpnode commented Aug 5, 2013

I think having Pjax::begin()... will complicate things. I would imagine that most people will choose to leave pjax on for all page loads, because it offers a very good user experience. Having a getAjaxLayout() or similar would provide the same functionality

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

Doesn't pjax require you to specify what elements to be updated? And what if different pages load different js/css files?

Member

qiangxue commented Aug 5, 2013

Doesn't pjax require you to specify what elements to be updated? And what if different pages load different js/css files?

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

yeah it specifies the parent element that should be updated, usually you'd use the main page container that your views would normally get rendered in - the bit between beginContent() and endContent() in 1.1X. If different pages used different JS/CSS, they should still work as those scripts would be registered from the pjax layout - i haven't tested this however.

phpnode commented Aug 5, 2013

yeah it specifies the parent element that should be updated, usually you'd use the main page container that your views would normally get rendered in - the bit between beginContent() and endContent() in 1.1X. If different pages used different JS/CSS, they should still work as those scripts would be registered from the pjax layout - i haven't tested this however.

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

I think applying pjax to the main page container for ALL pages is too much - problems will almost certainly pop up when different pages use different js/css files, even if you use pjax layout to register the new js/css files. What would you do with old and unneeded js/css files? What if there are dependency between js/css files?

Member

qiangxue commented Aug 5, 2013

I think applying pjax to the main page container for ALL pages is too much - problems will almost certainly pop up when different pages use different js/css files, even if you use pjax layout to register the new js/css files. What would you do with old and unneeded js/css files? What if there are dependency between js/css files?

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

well, it should certainly be opt in, but i think it should be possible for us to sanely return things in a pjax layout (or no layout at all) if we recieve a pjax request. After that it's up to the developer to specify an alternative pjax layout if they need to, just as they would with a normal layout.

regarding your point about css / js, i believe pushState() and popState() could handle that, but would need further investigation.

as long as we can make it easy for developers to specify which links and forms should (or should not) be converted to pjax, we can allow for this more complicated use case even if pushState() etc don't work.

phpnode commented Aug 5, 2013

well, it should certainly be opt in, but i think it should be possible for us to sanely return things in a pjax layout (or no layout at all) if we recieve a pjax request. After that it's up to the developer to specify an alternative pjax layout if they need to, just as they would with a normal layout.

regarding your point about css / js, i believe pushState() and popState() could handle that, but would need further investigation.

as long as we can make it easy for developers to specify which links and forms should (or should not) be converted to pjax, we can allow for this more complicated use case even if pushState() etc don't work.

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

That's exactly why I proposed the Pjax widget as it would allow you to specify which part of your view to use pjax (and possibly how.) It can support the scopes you suggested, and it can also support using pjax for the whole page container.

The only thing unclear to me now is how to handle GET form submission. For example, how should we handle the filtering of grid?

Member

qiangxue commented Aug 5, 2013

That's exactly why I proposed the Pjax widget as it would allow you to specify which part of your view to use pjax (and possibly how.) It can support the scopes you suggested, and it can also support using pjax for the whole page container.

The only thing unclear to me now is how to handle GET form submission. For example, how should we handle the filtering of grid?

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

@qiangxue ok, so we could have Pjax::begin() but if we don't use it, we render the whole view (without layout, or with pjaxLayout) instead? Do we only allow one Pjax::begin() per request or would we support multiple calls? if so we'd need to handle that on the client somehow which might become awkward.

Form submissions should go over pjax too, and we could include a data attribute on the form that indicates which element the submission should replace

phpnode commented Aug 5, 2013

@qiangxue ok, so we could have Pjax::begin() but if we don't use it, we render the whole view (without layout, or with pjaxLayout) instead? Do we only allow one Pjax::begin() per request or would we support multiple calls? if so we'd need to handle that on the client somehow which might become awkward.

Form submissions should go over pjax too, and we could include a data attribute on the form that indicates which element the submission should replace

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

Whether to use whole view or not is determined by the action code. Pjax has no control over it.

There could be multiple Pjax in the same view. Each Pjax defines a container, and only updates the content in this container if links are clicked within this container. There's no special client handling.

How can form submissions (only GET method is needed) automatically use pjax? Do you have some example code snippet?

Member

qiangxue commented Aug 5, 2013

Whether to use whole view or not is determined by the action code. Pjax has no control over it.

There could be multiple Pjax in the same view. Each Pjax defines a container, and only updates the content in this container if links are clicked within this container. There's no special client handling.

How can form submissions (only GET method is needed) automatically use pjax? Do you have some example code snippet?

@phpnode

This comment has been minimized.

Show comment
Hide comment
@phpnode

phpnode Aug 5, 2013

ah so Pjax::begin would basically just render a div with the appropriate data attributes? that makes more sense.

i don't have a snippet handy, i will try and release an extension for 1.1X that wraps what i have so far and post back here when it's ready, that will hopefully make things a bit clearer.

phpnode commented Aug 5, 2013

ah so Pjax::begin would basically just render a div with the appropriate data attributes? that makes more sense.

i don't have a snippet handy, i will try and release an extension for 1.1X that wraps what i have so far and post back here when it's ready, that will hopefully make things a bit clearer.

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Aug 5, 2013

Member

Yes. So to make a GridView updates via AJAX, simply enclose it with a Pjax.

Member

qiangxue commented Aug 5, 2013

Yes. So to make a GridView updates via AJAX, simply enclose it with a Pjax.

@janisto

This comment has been minimized.

Show comment
Hide comment
@janisto

janisto Aug 21, 2013

Contributor

NProgress.js might work pretty nicely with Pjax: https://github.com/rstacruz/nprogress

Contributor

janisto commented Aug 21, 2013

NProgress.js might work pretty nicely with Pjax: https://github.com/rstacruz/nprogress

@kartik-v

This comment has been minimized.

Show comment
Hide comment
@kartik-v

kartik-v Jan 18, 2014

Contributor

When can PJAX and such grid enhancements be expected for testing?

Contributor

kartik-v commented Jan 18, 2014

When can PJAX and such grid enhancements be expected for testing?

@kop

This comment has been minimized.

Show comment
Hide comment
@kop

kop Jan 18, 2014

+1 to @kartik-v question. Missing AJAX updates in GridView and ListView are very annoying.

kop commented Jan 18, 2014

+1 to @kartik-v question. Missing AJAX updates in GridView and ListView are very annoying.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Jan 18, 2014

Member

Need a Pjax implementation and a good concept first. Not planned for the beta right now.

Member

cebe commented Jan 18, 2014

Need a Pjax implementation and a good concept first. Not planned for the beta right now.

@kartik-v

This comment has been minimized.

Show comment
Hide comment
@kartik-v

kartik-v Jan 24, 2014

Contributor

Hm... can it please be prioritized to move ahead somehow? Yii2 core looks stable enough now to start development. Gridview / Listview are one of the core tools for yii developers when designing applications. I do understand a plan the core team has... but developers are a bit handicapped without using the full power of these great yii widgets. If we do start a yii2 project with current gridview/listview, the fear is applications may need significant change when the PJAX is implemented eventually to use the related feature(s) better.

Contributor

kartik-v commented Jan 24, 2014

Hm... can it please be prioritized to move ahead somehow? Yii2 core looks stable enough now to start development. Gridview / Listview are one of the core tools for yii developers when designing applications. I do understand a plan the core team has... but developers are a bit handicapped without using the full power of these great yii widgets. If we do start a yii2 project with current gridview/listview, the fear is applications may need significant change when the PJAX is implemented eventually to use the related feature(s) better.

@mitalcoi

This comment has been minimized.

Show comment
Hide comment
@mitalcoi

mitalcoi Jan 24, 2014

Contributor

agree with @kartik-v, pjax is very expected

Contributor

mitalcoi commented Jan 24, 2014

agree with @kartik-v, pjax is very expected

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Jan 25, 2014

Member

set it for beta milestone, we'll see if we find time for it in beta. Can not promise though.

Member

cebe commented Jan 25, 2014

set it for beta milestone, we'll see if we find time for it in beta. Can not promise though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment