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

issue with paginate url params #70

Open
hoangvn2404 opened this issue May 11, 2018 · 7 comments
Open

issue with paginate url params #70

hoangvn2404 opened this issue May 11, 2018 · 7 comments

Comments

@hoangvn2404
Copy link

pagination issue

I run into issue that by default the generated pagination do not included any params I used on the search, so basically click on next link will return wrong results.
I know that we have options to pass additional params into the pagination_links but that would be much work if we have to manually do that.

Did I miss something on the docs? or do you intentionally do that? I'm not sure this is an issue or not?

I have done a little work on my project to make it automatically pass all the params into the url, if you need it I can make an PR for this

@goravbhootra
Copy link

@hoangvn2404 I need to implement this. Could you pls explain how you managed this or raise a PR?

@msmontader
Copy link

msmontader commented Jul 26, 2018

@hoangvn2404 Having the exact same issue. Looking at the docs, it looks like the only way to pass params to pagination_links has to be done manually. If there is a better way of doing this that would be great.

@goravbhootra
Copy link

@msmontader I solved it by putting all the filters in an hash "filters" from html and then:

in candidate_controller.ex:

render(conn, :index,  candidates: candidates, filters: [filters: filter_params])

and then in index.html.eex:

<%= pagination_links @candidates, @filters %>

this retains the filters in the pagination links. Hope it helps.

@hoangvn2404
Copy link
Author

@goravbhootra @msmontader Hi guys, sorry for late reply,
I solved this by taking the filter value from the conn.query_params and puts it in as the options in Scrivener pagination links
Details as below, it work perfectly for my project, hope it help!

First I made a little helper that will be used in html view
<%= pagination_nav @conn, @page %>

Then I define that as below

def pagination_nav(conn, page) do
    # below take the params from the conn, leave out the page parameter
    opts =
      conn.query_params
      |> Enum.reject(fn {k, _v} -> k == "page" end)
      |> PARAMS.to_list()
      |> List.flatten()

    Scrivener.HTML.pagination_links(page, opts)
  end

with a little help from the module PARAMS

defmodule PARAMS do
  @moduledoc false

  def to_list(input, namespace) do
    input |> Enum.map(fn {key, value} -> parse("#{namespace}[#{key}]", value) end)
  end

  def to_list(input) do
    input |> Enum.map(fn {key, value} -> parse(key, value) end)
  end

  def parse(key, value) when is_map(value), do: to_list(value, key)

  def parse(key, value), do: ["#{key}": value]
end

@mgwidmann
Copy link
Owner

Sorry I missed this for such a long time. Did you try passing in the @conn as the first parameter? It has the query parameters inside it that you're looking for and we pass this directly onto phoenix so it would do whatever phoenix would do with it.

I'm not sure if we would want to take the query params from the @conn and always merge them with yours since we'd have to verify its the same page that you're currently on and where you're linking to. If this doesn't solve your problem let me know and we can further discuss.

@JohnKacz
Copy link

JohnKacz commented Feb 8, 2019

@mgwidmann I'm passing @conn but that doesn't give the desired results.

As an alternative to @hoangvn2404's workaround here is mine:

defmodule MyAppWeb.FooView do
  use MyAppWeb, :view
  import Scrivener.HTML

  @distance 2

  def pagination_params(params) do
    params
    |> Map.delete("page")
    |> Map.put("distance", @distance)
    |> map_to_keyword_list()
  end

  defp map_to_keyword_list(map) when is_map(map),
    do: Enum.map(map, fn {k, v} -> {String.to_atom(k), map_to_keyword_list(v)} end)

  defp map_to_keyword_list(value), do: value
end

Then in my_app_web/templates/foo/index.html.eex

<%= pagination_links @conn, @companies, pagination_params(@conn.params) %>

This also felt like a cleaner way to pass my default options (e.g., distance) until #74 is resolved.

@mgwidmann
Copy link
Owner

I think we should ideally replicate the query params in the links when we generate the link. We execute the path function in these areas:

https://github.com/mgwidmann/scrivener_html/blob/master/lib/scrivener/html.ex#L326
https://github.com/mgwidmann/scrivener_html/blob/master/lib/scrivener/html.ex#L356

But the url_params in that context does not contain the parameters from the conn object. They should be mixed in after this line unless they conflict with an existing key:
https://github.com/mgwidmann/scrivener_html/blob/master/lib/scrivener/html.ex#L114

If anyone has time for a PR I'd appreciate the help.

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

No branches or pull requests

5 participants