Closed GoogleCodeExporter closed 9 years ago
Original comment by sehmaschine
on 15 Sep 2010 at 3:26
This issue was closed by revision r1152.
Original comment by klemens.mantzos
on 20 Sep 2010 at 3:33
reopen:
a) testing is needed.
b) rename sort-field.
c) documentation is missing.
Original comment by sehmaschine
on 20 Sep 2010 at 3:45
styles are needed as well.
Original comment by sehmaschine
on 20 Sep 2010 at 3:46
* sortable feature for existing inlines only (django.contib.admin throws
exception if you sort a new inline within the existing ones)
* added basic placeholder (styling still needed)
what should be the correct/new name for the "sort_field_name" property?
Original comment by klemens.mantzos
on 20 Sep 2010 at 4:52
first, I think we shouldn´t commmit half-baked stuff (styling is not a
blocker, but not being able to add new items is definitely one) - so, that code
shouldn´t land in trunk.
still have to think about the naming ...
Original comment by sehmaschine
on 20 Sep 2010 at 5:00
I have a drag-n-drop sorting implementation that allows for sorting new inlines
(once they have at least one field filled in), running in a customized
Grappelli. Would you like to have a look? (It's much simpler, and it doesn't
currently permit the use of any field as the sort order field, but maybe it
could serve as a reference to figure out how to make Grappelli's implementation
work.)
Original comment by ringe...@gmail.com
on 20 Sep 2010 at 5:30
@ringmeup: how can you (re)order without an order-field? there has to be a
db-field storing the order, right? anyway ... yes, I´d like to have a look.
Original comment by sehmaschine
on 20 Sep 2010 at 5:36
@ringmeup – additional question: with your implementation, the ordering is
preserved in case of errors, right?
Original comment by sehmaschine
on 20 Sep 2010 at 5:40
It does use a DB field for the order, just assumes that it has a particular
name. Basically, I had implemented this for private use, and figured I could
use the same field name for all sortable inlines in my own projects. For the
same reason,
I haven't tested it yet with date, RelatedLookup, or TinyMCE fields, although
I'm sure it could be adapted to those. And the code is ugly in places, but it
works.
Currently it preserves the new order numbers after an error, but not actual
ordering. It shouldn't be too hard to add something to re-sort on page load,
though.
Here's the code. It depends on the following jQuery UI modules:
jquery.ui.core
jquery.ui.widget
jquery.ui.mouse
jquery.ui.sortable
#Start code
##############
django.jQuery(function($) {
$("div.inline-group").sortable({
//axis: 'y',
placeholder: 'ui-state-highlight',
forcePlaceholderSize: 'true',
items: 'div.inline-related',
update: function() {
$('div.inline-related', this).each(function(i) {
// Only update the position for inlines that actually have data; otherwise we'll throw errors for any inlines that the user left empty
if (
!isNaN(parseInt($('input[id$=position]', this).eq(0).val()))
&& (
$('input[type!="hidden"][value!=""]:not([id$=position]):not([id$=DELETE])', this).length
|| $('textarea[value!=""]', this).length
|| $('select[value!=""]', this).length
)
)
{ // the inline does have data, so set position to the new number
$('input[id$=position]', this).eq(0).val(i+1);
}
});
}
});
$("div.inline-group").disableSelection();
});
// use different cursor for draggables
django.jQuery(document).ready(function($){
$('input[id$=position]').parent('div').parent('div').parent('div.inline-related').css('cursor','move');
});
Original comment by ringe...@gmail.com
on 20 Sep 2010 at 5:57
thanks a lot - we´ll take a closer look at your script. that being said,
preserving the order in case of errors is _very_ important to us (and we don´t
want to re-sort on page-load).
Original comment by sehmaschine
on 20 Sep 2010 at 6:24
How are you currently handling order preservation? (I can't make it out from
the changeset.) Would it make sense to sort the forms of the formset on either
the view or template level before outputting them? The ordering data is
transmitted with the form submission, so it's there to use.
Original comment by ringe...@gmail.com
on 20 Sep 2010 at 6:39
preserving the order is done by (re)setting the form-prefixes within the
formset.
problem is, that django should return ordered forms anyway (at least when I set
can_order). unfortunately, that´s not the case.
Original comment by sehmaschine
on 21 Sep 2010 at 10:05
@ringemup: and you can actually add an inline and order it on top off the
existing ones - save - and not getting an python error (because the id field of
the new inline is empty)?
what django version are you using?
(your code looks like it works if you have 1 inline in your changeform only,
right?)
Original comment by klemens.mantzos
on 21 Sep 2010 at 11:39
Ah, that's the Django bug that's holding this up?
I haven't done a whole lot of work with formsets, but is that something we can
fix by subclassing the admin inline classes or ModelFormset?
Original comment by ringe...@gmail.com
on 21 Sep 2010 at 11:40
> Ah, that's the Django bug that's holding this up?
kind of. so you didn't fixed that "sort new inlines on top of existing
ones"-issue either? thx anyway
Original comment by klemens.mantzos
on 21 Sep 2010 at 11:45
> so you didn't fixed that "sort new inlines on top of existing ones"-issue
either?
I'm not understanding what that issue is. The code I posted allows you to
drag-and-drop sort any inlines, including ones that were blank when the form
was loaded, or that were created on the fly using the "Add another <whatever>"
link.
Oops, missed your other comment...
>You can actually add an inline and order it on top off the existing ones -
save - and not getting an python error (because the id field of the new inline
is empty)?
Yes, absolutely, and I do it all the time. It just won't set the order field
on an inline unless there's already another field in the inline that has a
value. (If you set the order field on all inlines in the formset, then any
intentionally empty inlines at the bottom of the formset would be given a
non-empty field and would cause validation to throw errors on any other
required fields in the model). Ideally, it would be able to use the same logic
to tell which inlines are empty as the formset itself does after submission,
but I never bothered looking that up -- however, it looks like you have a way
to do that with a single function call in your code.
> what django version are you using?
1.2
> (your code looks like it works if you have 1 inline in your changeform only,
right?)
It works with as many inlines as you like. I have it on one admin screen that
takes three different inlines -- two tabular and one stacked.
Original comment by ringe...@gmail.com
on 21 Sep 2010 at 11:57
@ringemup: so the only drawback on your version is that the inlines loose the
order (after submit) if you have an error in your change_form?
i.e.:
1) sort inlines as i like.
2) leave a required field empty (not necessarily in the inlines)
3) submit
=> get an error message, and inlines have the old order
Original comment by klemens.mantzos
on 21 Sep 2010 at 1:06
Correct. And after error they actually still have the correct value in the
order field, just the wrong display order -- which is something that could be
fixed by either sorting before output, or sorting via javascript.
I'd also want to fix the following issues in my code before releasing it to a
wider audience:
1) expects the field that stores the order to be called "position"
2) code to determine which inlines are empty is a fairly ugly hack, and may not
work with all field types, fields with initial values, etc. at present
BTW, credit where credit is due, my code is adapted from:
http://djangosnippets.org/snippets/1053/ and its comments
Original comment by ringe...@gmail.com
on 21 Sep 2010 at 1:15
made an update in trunk r1156:
improved sortable inlines feature:
* works with new inlines
* keeps order if error occurs
* improved check is_form_filled()
Original comment by klemens.mantzos
on 22 Sep 2010 at 1:19
set axis to 'y'.
Original comment by sehmaschine
on 22 Sep 2010 at 3:16
Is this now implemented in trunk? Is it possible to document how to get it
working? I currently have a model with a field called "order". How do I
activate the drag and drop? Setting "sortable=True" in the admin doesn't seem
to work. Nor does creating a model form that calls in "ordering.js".
Sorry if this is premature, but I'd love to get this working with my
installation.
Thanks.
Original comment by dmee...@gmail.com
on 26 Sep 2010 at 5:17
implemented in trunk.
take a look at this:
http://code.google.com/p/django-grappelli/wiki/Upgrade_2_2
and here is how you add the sortable feature to you inlines:
http://code.google.com/p/django-grappelli/wiki/inlinemodeladminoptions_2_2#sorta
ble_inlines
Original comment by klemens.mantzos
on 2 Oct 2010 at 11:23
Might be working for Stacked and tabularinlines, but what about
GenericTabularInline?
Original comment by sertech...@gmail.com
on 14 Oct 2010 at 10:13
@sertechaun: drag/drop with GenericTabularInline works for me ... what exactly
doesn´t work for you?
Original comment by sehmaschine
on 14 Oct 2010 at 10:30
Original issue reported on code.google.com by
sehmaschine
on 9 Sep 2010 at 11:14