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

Replace grid / list view javascript with pjax #706

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

Replace grid / list view javascript with pjax #706

phpnode opened this issue Aug 2, 2013 · 30 comments

Comments

@phpnode
Copy link

@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
Copy link
Member

@samdark samdark commented Aug 2, 2013

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

@bwoester
Copy link
Contributor

@bwoester 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
Copy link
Author

@phpnode 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
Copy link
Member

@cebe cebe commented Aug 4, 2013

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

@qiangxue
Copy link
Member

@qiangxue qiangxue commented Aug 4, 2013

Any suggestion for the server side code design?

@cebe
Copy link
Member

@cebe 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue 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
Copy link
Author

@phpnode 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
Copy link
Member

@qiangxue qiangxue commented Aug 5, 2013

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

@janisto
Copy link
Contributor

@janisto janisto commented Aug 21, 2013

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

@kartik-v
Copy link
Contributor

@kartik-v kartik-v commented Jan 18, 2014

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

@kop
Copy link

@kop kop commented Jan 18, 2014

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

@cebe
Copy link
Member

@cebe cebe commented Jan 18, 2014

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

@kartik-v
Copy link
Contributor

@kartik-v 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
Copy link
Contributor

@mitalcoi mitalcoi commented Jan 24, 2014

agree with @kartik-v, pjax is very expected

@cebe
Copy link
Member

@cebe 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
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants
You can’t perform that action at this time.