Support for data-* passthrough in data-method=delete #189

Open
ahutch opened this Issue Aug 7, 2011 · 8 comments

Comments

Projects
None yet
7 participants
@ahutch

ahutch commented Aug 7, 2011

In order to support a restful delete rails turns a link with data-method=delete into a form with an input _method=delete. When using additional frameworks such as jquery-mobile links and forms carry other data to control the behavior. (data-ajax=false).

The data from the link (data-ajax=false) is not copied/carried across to the form meaning that the other frameworks will not process the form as specified by the link. Is it possible to add a mechanism in which the form inherits data-* from a link.

@mislav

This comment has been minimized.

Show comment Hide comment
@mislav

mislav Aug 8, 2011

Member

On Mon, Aug 8, 2011 at 00:39, ahutch wrote:

The data from the link (data-ajax=false) is not copied/carried across to
the form meaning that the other frameworks will not process the form as
specified by the link. Is it possible to add a mechanism in which the form
inherits data-xxx from a link.

I can see your point but I also think that all data-* attributes shouldn't
just be blindly copied from the link to the form. Rails.js only operates
with data attributes it recognizes and leaves others alone.

Your use case obviously is about "data-ajax" attribute. What does that do?
You should try to explain your use-case better and how does the current
functionality prevent you from doing what you need.

Member

mislav commented Aug 8, 2011

On Mon, Aug 8, 2011 at 00:39, ahutch wrote:

The data from the link (data-ajax=false) is not copied/carried across to
the form meaning that the other frameworks will not process the form as
specified by the link. Is it possible to add a mechanism in which the form
inherits data-xxx from a link.

I can see your point but I also think that all data-* attributes shouldn't
just be blindly copied from the link to the form. Rails.js only operates
with data attributes it recognizes and leaves others alone.

Your use case obviously is about "data-ajax" attribute. What does that do?
You should try to explain your use-case better and how does the current
functionality prevent you from doing what you need.

@ahutch

This comment has been minimized.

Show comment Hide comment
@ahutch

ahutch Aug 8, 2011

JQM uses a variety of data-* for controlling the way in which a loads an transitions to a new pages. Its normal behavior is to load pages into the DOM as sub pages and seamlessly transition between them. This is done by using ajax to fetch the HTML and JQ to perform a transition. It uses data-* to control the features of this loading. To make JQM to perform a full reload of the page without ajax I can use data-ajax=false. Here are a few of the other data-* that I can see using on links data-ajax, data-transition, data-prefetch, data-cache, data-url.

I have a number of times run into cases where JQM did not seem to be obeying the data-* commands. As JQM is in beta I ignored it until I hit a case that I needed to solve. The case that is broken is:

  • The page contains a link to a sessions controller delete action : For signing out the user
    -- The delete action removes the users session/cookies signing them out
    -- The response for the action is always a 302 redirect to the home page
  • JQM performs the correct action on the link click
  • UJS turns the link into a form
  • JQM traps the generated form submission and performs the incorrect action. In this case an ajax request

I first tried fix JQM and force the ajax request to peform a redeirect. However Ajax is not able to see 3xx responses jquery/jquery-mobile#1571. So I used plan B. I know this is a redirect in which I want a full page reload so I added data-ajax=false on the link to disable JQM. As I have no control over the generated form JQM always performs its default action. Once I figured out rails.js was removing the data-* I understood why JQM miss-behaved so frequently.

I tested my theory by copying the data-ajax to the form in ujs:handleMethod. This solved the problem. I originally thought that you could not just blindly copy the data-* from the link to the form. These are my thoughts

a) How do I know ahead of time which data-* should be copied. I could possibly provide a list.
b) Why are data-* not in namespaces data-ujs-* data-jqm-. This would make things easier
c) Copy all the data-
as there is no reason that I would not want the same data-* on the form as the link. data-* have no effect on the form only on the javascript frameworks. Of course you would need to remove the ujs data-method to avoid a handleMethod loop.
d) Could the form be submitted without the knowledge of JQM? No as in the normal case JQM needs the response.
e) Ask the JQM guys to support data-method (RESTFUL requests)

ujs:handleMethod is the only place I found that the original element was not used for the request. For this case it seems to me that option C would be best.

ahutch commented Aug 8, 2011

JQM uses a variety of data-* for controlling the way in which a loads an transitions to a new pages. Its normal behavior is to load pages into the DOM as sub pages and seamlessly transition between them. This is done by using ajax to fetch the HTML and JQ to perform a transition. It uses data-* to control the features of this loading. To make JQM to perform a full reload of the page without ajax I can use data-ajax=false. Here are a few of the other data-* that I can see using on links data-ajax, data-transition, data-prefetch, data-cache, data-url.

I have a number of times run into cases where JQM did not seem to be obeying the data-* commands. As JQM is in beta I ignored it until I hit a case that I needed to solve. The case that is broken is:

  • The page contains a link to a sessions controller delete action : For signing out the user
    -- The delete action removes the users session/cookies signing them out
    -- The response for the action is always a 302 redirect to the home page
  • JQM performs the correct action on the link click
  • UJS turns the link into a form
  • JQM traps the generated form submission and performs the incorrect action. In this case an ajax request

I first tried fix JQM and force the ajax request to peform a redeirect. However Ajax is not able to see 3xx responses jquery/jquery-mobile#1571. So I used plan B. I know this is a redirect in which I want a full page reload so I added data-ajax=false on the link to disable JQM. As I have no control over the generated form JQM always performs its default action. Once I figured out rails.js was removing the data-* I understood why JQM miss-behaved so frequently.

I tested my theory by copying the data-ajax to the form in ujs:handleMethod. This solved the problem. I originally thought that you could not just blindly copy the data-* from the link to the form. These are my thoughts

a) How do I know ahead of time which data-* should be copied. I could possibly provide a list.
b) Why are data-* not in namespaces data-ujs-* data-jqm-. This would make things easier
c) Copy all the data-
as there is no reason that I would not want the same data-* on the form as the link. data-* have no effect on the form only on the javascript frameworks. Of course you would need to remove the ujs data-method to avoid a handleMethod loop.
d) Could the form be submitted without the knowledge of JQM? No as in the normal case JQM needs the response.
e) Ask the JQM guys to support data-method (RESTFUL requests)

ujs:handleMethod is the only place I found that the original element was not used for the request. For this case it seems to me that option C would be best.

@JangoSteve

This comment has been minimized.

Show comment Hide comment
@JangoSteve

JangoSteve Aug 11, 2011

Member

I'm honestly not sure what the best solution here would be. I can see your point for copying the data- attributes over to the form. However, it's one of those situations that could go either way, as Mislav has pointed out. Changing it could break the other half of people's applications that rely on the current behavior. In these situations, I tend to lean toward not changing it so we can at least establish some sort of consistency.

But then the question remains, how do you accomplish DELETE, PUT, and POST links that are compatible with other frameworks like JQM?

Member

JangoSteve commented Aug 11, 2011

I'm honestly not sure what the best solution here would be. I can see your point for copying the data- attributes over to the form. However, it's one of those situations that could go either way, as Mislav has pointed out. Changing it could break the other half of people's applications that rely on the current behavior. In these situations, I tend to lean toward not changing it so we can at least establish some sort of consistency.

But then the question remains, how do you accomplish DELETE, PUT, and POST links that are compatible with other frameworks like JQM?

@ahutch

This comment has been minimized.

Show comment Hide comment
@ahutch

ahutch Aug 11, 2011

I would be ok with adding one of the following to my links. Then the copy would be under my control
data-method-copy='true' //Copy all
or
data-method-copy='ajax,or,other,data" //Copy data elements from the list split on ','

ahutch commented Aug 11, 2011

I would be ok with adding one of the following to my links. Then the copy would be under my control
data-method-copy='true' //Copy all
or
data-method-copy='ajax,or,other,data" //Copy data elements from the list split on ','

@scottwb

This comment has been minimized.

Show comment Hide comment
@scottwb

scottwb Feb 18, 2012

I agree we need a proper solution. I need jQuery Mobile with Rails UJS to honor data-ajax="false" on links that are using data-method="delete". I can see both sides of the argument, and think either of @ahutch's suggestions would be great.

In the meantime, I've patched rails.js to one-off copy data-ajax from the link to the form: 4d6bc50

scottwb commented Feb 18, 2012

I agree we need a proper solution. I need jQuery Mobile with Rails UJS to honor data-ajax="false" on links that are using data-method="delete". I can see both sides of the argument, and think either of @ahutch's suggestions would be great.

In the meantime, I've patched rails.js to one-off copy data-ajax from the link to the form: 4d6bc50

@ccmcbeck

This comment has been minimized.

Show comment Hide comment
@ccmcbeck

ccmcbeck Aug 9, 2012

Would love to see something done. Consider this: in JQM 1.1 you can set data-ajax on a container if you set $.mobile.ignoreContentEnabled=true in mobileinit per http://jquerymobile.com/test/docs/pages/page-scripting.html. Alas, UJS does form.hide().append(metadata_input).appendTo('body'); so the only eligible container is body. So another approach (or workaround) might be to appendTo(link)

ccmcbeck commented Aug 9, 2012

Would love to see something done. Consider this: in JQM 1.1 you can set data-ajax on a container if you set $.mobile.ignoreContentEnabled=true in mobileinit per http://jquerymobile.com/test/docs/pages/page-scripting.html. Alas, UJS does form.hide().append(metadata_input).appendTo('body'); so the only eligible container is body. So another approach (or workaround) might be to appendTo(link)

@jpmcgrath

This comment has been minimized.

Show comment Hide comment
@jpmcgrath

jpmcgrath Aug 17, 2012

I would also like to see something done here as well. Here's my suggestion: Add a form_html argument to the link_to and button_to helpers.

Currently the button_to helper has a :form_class argument that allows you to specify the class of the form surrounding the button. We could have something similar, but more flexible.

I think it should work like this:

link_to "delete", user_path(user), :form_html => {:'data-ajax' => false, :class => 'delete-button-form', :anything => 'yeah!'}

The helpers would then inject each of the attributes found into the form. So the output would be something like:

This allows the functionality to be used at will, without breaking existing applications AND it provides the flexibility to add any attributes needed at a future date.

I would also like to see something done here as well. Here's my suggestion: Add a form_html argument to the link_to and button_to helpers.

Currently the button_to helper has a :form_class argument that allows you to specify the class of the form surrounding the button. We could have something similar, but more flexible.

I think it should work like this:

link_to "delete", user_path(user), :form_html => {:'data-ajax' => false, :class => 'delete-button-form', :anything => 'yeah!'}

The helpers would then inject each of the attributes found into the form. So the output would be something like:

This allows the functionality to be used at will, without breaking existing applications AND it provides the flexibility to add any attributes needed at a future date.

@marcolinux

This comment has been minimized.

Show comment Hide comment
@marcolinux

marcolinux Feb 27, 2013

Hello,
I have searched thoroughly and could not find a clean way to fix this exact.
is there a final solution or a workaround for this issue?

As far I could understand, there are basically two options to have jQuery-mobile working properly on Rails:
1- make @ahutch patch (=> each one need to maintain a personal fork of jquery-uis)
2 - disable ajax for the whole project ( $.mobile.ajaxEnabled = false;)

thanks in advance

Hello,
I have searched thoroughly and could not find a clean way to fix this exact.
is there a final solution or a workaround for this issue?

As far I could understand, there are basically two options to have jQuery-mobile working properly on Rails:
1- make @ahutch patch (=> each one need to maintain a personal fork of jquery-uis)
2 - disable ajax for the whole project ( $.mobile.ajaxEnabled = false;)

thanks in advance

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