-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
sortable has_many #2656
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
sortable has_many #2656
Conversation
@seanlinsley, are the jasmine tests used? or should I implement cucumber/capybara tests? |
We have Jasmine, but have never actually used it. I'd very much like to have JS tests, but for some reason Jasmine is throwing an error when I try running it. |
This only thing thats missing here are tests. But the jasmine tests are broken & there doesn't appear to be any js tests implemented via cucumber/capybara. Unfortunately I don't have time to open up that can of worms (figuring out why jasmine is broken and then fixing all the existing tests because they haven't been run in awhile). @seanlinsley Would you merge this w/o js tests? or should I spin this off into a separate gem? |
I'll answer your question with a question: is there anything I can do to get you to write tests? Any way I can accommodate your skills and schedule?
I'd hope not! IMO the whole create "spin-off gems extending AA" thing was just a way for the previous maintainers to be lazy. We don't need more fragmentation. |
I have a couple of competing goals:
One of the admin interfaces that a client signed off on was a sortable has_many UI, which was implemented in my fork, but was antiquated by the changes in #2679. Hence this PR, which rebases that functionality on current FormBuilder structure. My client's next priority is to get an autocomplete widget for selecting editions for their homepage. Since they will need both functionalities, I will need to have one of these features merged in master or available in a gem or living in my own fork of active admin. I don't have a problem with writing tests for this functionality, but I'm concerned about the amount of work necessary to get my tests running along side the existing js tests & passing again, so I can't commit to working on that until december. The path of least resistance for me would be: to get this merged into master, open up a PR for the autocomplete feature, base my client's admin off that PR, then deal with jasmine tests as a whole in december. |
@igorbernstein Just FYI, Select2 is actually pretty simple to integrate in ActiveAdmin on its own. In my apps, I simply add |
@igorbernstein if you're going to be around for the long haul then I think we can forgo the tests for now. Later this month I'll try tackling the JS testing issue so we have a framework that is actually operational. Is this PR fully functional? I'll try it out locally and we can hopefully get it merged tonight. |
parent.children('fieldset').each -> | ||
fieldset = $(@) | ||
destroy = fieldset.find ':input[name$="[_destroy]"]' | ||
sortable_input = fieldset.find ":input[name$='[#{input_name}]']:eq(0)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the :eq(0)
necessary? Are there going to be multiple inputs with the same name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm kinda hair-splitting here but line 7 uses " '' "
while line 8 uses ' "" '
. One way or another, I think they should be consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the eq(0) is necessary in the nested has_many case
sorry about the inconsistency, i'll switch it to " ' ' " because I need to interpolate the input_name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case wouldn't it make more sense to have a direct descendent CSS rule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a little ugly:
sortable_input = fieldset.find "> ol > li > :input[name$='[#{input_name}]']"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also the _destroy finder has the same issues
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the correct but ugly selectors for the time being
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so the simplest ideas I have are:
- the closestDescendant plugin
- or just to localize the crazy in a helper:
recompute_positions = (parent)->
....
destroy = find_fieldset_input fieldset, "_destroy"
sortable_input = find_fieldset_input fieldset, input_name
find_fieldset_input = (parent, name)->
parent.find "> ol > .input > :input[name$='[#{name}]']"
edit: i prefer no. 2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I prefer it like it is, with long but obvious CSS selectors. As the behavior grows it might be worth it to abstract things some more, but for now I think what you already have in the PR is appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm cool with that, I added a comment to avoid future head scratching
f.inputs :taggings, sortable: :position do |t| | ||
t.input :tag | ||
t.input :position | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be has_many
, not inputs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry that was sloppy. fixed now
One problem I noticed is that if there's another |
Not sure what you mean about arrows not scoping to just the .has_many area...but maybe I accidentally fixed it in the other changes?
|
Can you post the form definition code for that screenshot? On Wed, Nov 13, 2013 at 7:33 PM, Sean Linsley notifications@github.comwrote:
|
It was a |
Here it is: form do |f|
f.inputs :body
f.has_many :taggings, sortable: :position do |t|
t.input :tag
t.input :position
end
f.actions
end |
thanks! just pushed a fix On Wed, Nov 13, 2013 at 7:41 PM, Sean Linsley notifications@github.comwrote:
|
Cool. What about centering the handle vertically to the fieldset? With this CSS: .has_many_container .handle {
top: calc(50% - 3em / 2);
} You get a nicely centered handle: Also, it'd be great if the developer didn't have to manually build the input for the sortable attribute, and it was built automatically. |
👍 👍 on auto generating sortable input |
the problem with the image you attached is that the nested |
i moved the arrows back to the vertical center, but could use some help making the margins look ok...ui & css aren't not a strong suit of mine |
Could you use the |
pushed, though for personal curiosity, I don't understand why the negative margin gives different results from the calc ie. why is calculation of: calc(50% - HEIGHT / 2); different from top: 50%;
margin-top:- HEIGHT/2; |
In my browser these both have the same effect: top: calc(50% - 3em / 2);
/* and */
top: 50%;
margin-top: -1.5em; |
I guess we had a miscommunication somewhere around commit aa24c69 & your 'Could you use the calc setting I gave earlier? That will get it exactly in the middle, accounting for the height of the icons.' comment. But I don't think it really matters. When you have a free moment, would you mind suggesting how I can improve the right margins to avoid arrow soup when nesting sortables? |
@@ -64,6 +64,12 @@ ActiveAdmin.register Post do | |||
end | |||
end | |||
f.inputs do | |||
f.has_many :taggings, sortable: :position do |t| | |||
t.input :tag | |||
t.input :position |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update this since the t.input :position
part is no longer needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still needs to be updated
I just noticed an interesting bug. Given this form: form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs
f.has_many :posts, allow_destroy: true do |o|
o.input :title
o.has_many :taggings, sortable: :position do |t|
t.input :tag
end
end
f.actions
end A just-added post's taggings aren't sortable. |
I cherry picked the css changes from your PR. Good catch on b8bba4b , but I think we should generalize your solution a bit. # application
$ ->
$(document).trigger('initialize_content')
# datepicker
$(document).on('initialize_content', (e) ->
$(@).find('.datepicker').datepicker()
$(document).on('teardown_content', (e) ->
$(@).find('.datepicker').datepicker('destroy')
# has_many (in addition to the existing has_many_*:* events)
$(document).on 'click', 'a.button.has_many_add', (e)->
# ..
fieldset.trigger('initialize_content')
# sortable
$(document).on 'initialize_content' (e)->
$('.has_many_container[data-sortable]').sortable()
|
How about we get this PR merged first, in a state where it's fully functional? In general I'm all for standardizing the way our JavaScript works. |
I think you can merge this, I'll open up a separate PR to deal with the generalized widget initialization I mentioned earlier. |
Coverage decreased (-0.33%) when pulling b59e82c8dfdb2dd3888419a7a7aed8876a3ddd1a on igorbernstein:has_many-sortable into 12b19a7 on gregbell:master. |
Hmm, 21 commits for 100 changes... Would you mind squashing this either into one commit or a handful of commits? |
Awesome. Thanks for working on this! 💙 |
Thanks for helping :) |
parent.trigger 'has_many_add:after', [ fieldset ] | ||
|
||
$(document).on 'change','.has_many_container[data-sortable] :input[name$="[_destroy]"]', -> | ||
recompute_positions $(@).closest '.has_many' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, what exactly is the purpose of this? Why would you need to recompute positions when the user clicks a checkbox?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because we don't want to include the ones marked for destruction to be included in the count...
item0
position: 0
item1
position: ''
_destroy: true
item2
position: 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. Ignore me :)
@kirel Thank you! For acts_as_list people wondering why the list is rotating you need to start the sort at 1. i.e. sortable_start: 1 otherwise it bumps the zero to one and then with two positions at 1 it will bump the first one to the bottom. At least I believe that's what was happening to me |
This is a revival of #2614, #881, #2117, #880
Its a still a work in progress, but I wanted to post this early on to make sure I'm on the right path and this doesn't slip through the cracks.
TODO:
force initial orderingadd an indicator icon to show that the fieldsets can be draggedadd css to change the cursor to indicate that the fieldset is draggableadd docsdeal with nested sortable has_many fieldsets