#10994 closed enhancement (fixed)
Add drag and drop and other dynamic behavior to the admin panels containing enum lists
Reported by: | Owned by: | Ryan J Ollos | |
---|---|---|---|
Priority: | normal | Milestone: | 1.1.2 |
Component: | admin/web | Version: | |
Severity: | normal | Keywords: | |
Cc: | leho@… | Branch: | |
Release Notes: |
Added Select All checkboxes to the admin Components, Milestones, Priorities, Repositories, Resolutions, Severities, Ticket Types and Versions tables. |
||
API Changes: |
The function |
||
Internal Changes: |
Description (last modified by )
A reworked version of th:AdminEnumListPlugin will be provided as a patch to Trac. The primary behavior will apply to the Priorities, Resolutions, Ticket Types and Severities panels, but behaviors will be implemented for almost every admin panel.
The following behaviors will be provided in the initial version of the patch:
The enum lists can be sorted by drag and drop of the items.⇒ #11682- The Order column of select elements is hidden.
- A Revert changes button is added. The button is disabled until the list is reordered.
The Save changes button is disabled until a change is made.The Remove selected items button is disabled until a checkbox is selected.⇒ #11056- Addition of a Select All checkbox in the table header.
Allow the Components, Milestones and Versions tables to be sorted (in jQuery?: th:#10876). For inspiration, see th:TableSorterPlugin.#11683
Similar behavior will be applied to other admin pages for consistency, where applicable.
Attachments (1)
Change History (26)
comment:1 by , 12 years ago
comment:2 by , 12 years ago
I'm not planning to change the templates or Python code at all, so it should work the same when JavaScript is disabled. For example, the select elements are left in place and hidden by the Javascript. I took the same approach in #9609.
The latest version of the th:AdminEnumListPlugin has all the functionality I have in mind. It is basically just a piece of javascript that should be reworked to make use of jQuery UI's Sortable widget, and all of the backward compatibility stuff can be dropped. It currently works in Trac 0.11, which required a significant number of workarounds.
comment:3 by , 12 years ago
Cc: | added |
---|
follow-up: 5 comment:4 by , 12 years ago
Description: | modified (diff) |
---|
Updated description with my current thinking on what the final patch will contain.
I've implemented the portion of the patch that enables buttons when checkboxes or a file have been selected. I still have a bit of work to do on the other features, but wanted to post this version of the patch to ask a few questions that will help me complete the implementation. I'll highlight a few parts of the patch that I'm uncertain about and looking for early feedback on:
- I've put the
disableIfNoneChecked
function intrac.js
with the idea that it could be useful outside of the administration panels. Specifically, I'm thinking we could use it for the Change tickets button on the batch modify form, and for the Add attachment button on the attachment page. - I'm confused about where I should be placing the
CDATA
section tags. I don't see any reason to not just place them within everyscript text=text/javascript
element, but I see them very selectively placed in some files. - I've used this pattern
change(function() {...}).eq(0).change()
(in this caseclick(function() {...}).eq(0).click()
would probably be the same), rather than.click(someFunction); someFunction();
(i.e. passing a function toclick
and then calling that function directly). Usingchange
seems a bit cleaner and both patterns are present throughout the Trac codebase.
follow-ups: 6 12 comment:5 by , 12 years ago
Replying to Ryan J Ollos <ryan.j.ollos@…>:
- I've put the
disableIfNoneChecked
function intrac.js
with the idea that it could be useful outside of the administration panels. Specifically, I'm thinking we could use it for the Change tickets button on the batch modify form, and for the Add attachment button on the attachment page.
Sounds good (for the attachment use case, I suppose there will be some additional check, for the file input).
- I'm confused about where I should be placing the
CDATA
section tags.
We apparently do it only when needed (i.e. when using plain '<', '&' or '>' characters in the Javascript code), but I wouldn't object using it everywhere for consistency (and for not having to think about it!).
- I've used this pattern
change(function() {...}).eq(0).change()
(in this caseclick(function() {...}).eq(0).click()
would probably be the same), rather than.click(someFunction); someFunction();
(i.e. passing a function toclick
and then calling that function directly). Usingchange
seems a bit cleaner and both patterns are present throughout the Trac codebase.
I suppose it all depends on whether there's a side-effect or not, and if yes, if the side-effect it predictable, or not (e.g. what would happen if there would be other event handlers?). The second pattern ensure you have a strict control over what you force during this initial call.
comment:6 by , 12 years ago
Replying to cboos:
Sounds good (for the attachment use case, I suppose there will be some additional check, for the file input).
I didn't describe it well, but I was thinking of putting a second function in trac.js
that would be used for file / button pairs, such as Add attachment. Although, it might not be necessary since it seems possible to accomplish this in just 3 lines.
- I'm confused about where I should be placing the
CDATA
section tags.We apparently do it only when needed (i.e. when using plain '<', '&' or '>' characters in the Javascript code), but I wouldn't object using it everywhere for consistency (and for not having to think about it!).
Not having to think about it sounds good to me. Also, the code is a bit cleaner when the tags aren't interleaved.
It looks like I was responsible for confusing myself on this issue. The only cases that I see the tags being present when they are not required is due to a changeset from one of my patches [t 11104].
comment:7 by , 12 years ago
Milestone: | → 1.0.2 |
---|---|
Owner: | set to |
Status: | new → assigned |
comment:8 by , 12 years ago
follow-up: 11 comment:9 by , 12 years ago
Milestone: | 1.0.2 → next-dev-1.1.x |
---|
Ah, I was just thinking about the current patch t10994-r11508-1.patch which doesn't contain anything potentially disruptive for 1.0.x. I suppose that part could be added to 1.0.x and the more ambitious change which this ticket is really about would better be suited for 1.1.x indeed.
comment:10 by , 12 years ago
I like the idea of committing the existing patch separately. The existing patch is actually a bit of a deviation from the key things in mind that I had for this ticket anyway. I'll touch-up that patch and create a new ticket for it, before continuing with the other changes described for this ticket.
comment:11 by , 12 years ago
comment:12 by , 12 years ago
Description: | modified (diff) |
---|
Replying to cboos:
- I'm confused about where I should be placing the
CDATA
section tags.We apparently do it only when needed (i.e. when using plain '<', '&' or '>' characters in the Javascript code), but I wouldn't object using it everywhere for consistency (and for not having to think about it!).
In the latest patch for #11056, I've included CDATA
tags for almost all of the changed code in script
elements. The one case I've found where this shouldn't be done is if there is embedded Genshi in the script, such as <py:if test="preview">...</py:if>
. I guess that's obvious in retrospect since we need that Genshi to be parsed!
- I've used this pattern
change(function() {...}).eq(0).change()
(in this caseclick(function() {...}).eq(0).click()
would probably be the same), rather than.click(someFunction); someFunction();
(i.e. passing a function toclick
and then calling that function directly). Usingchange
seems a bit cleaner and both patterns are present throughout the Trac codebase.I suppose it all depends on whether there's a side-effect or not, and if yes, if the side-effect it predictable, or not (e.g. what would happen if there would be other event handlers?). The second pattern ensure you have a strict control over what you force during this initial call.
The strict control sounds better for long-term maintainability. Thanks for giving it some thought and explaining the trade-off.
I'll put further comments on #11056, but just wanted to follow-up on this earlier discussion here.
comment:13 by , 12 years ago
Description: | modified (diff) |
---|
comment:14 by , 11 years ago
Milestone: | next-dev-1.1.x → 1.1.3 |
---|
comment:15 by , 11 years ago
Milestone: | 1.1.3 → 1.1.2 |
---|---|
Owner: | changed from | to
comment:16 by , 11 years ago
Description: | modified (diff) |
---|
comment:17 by , 10 years ago
Description: | modified (diff) |
---|
follow-up: 20 comment:18 by , 10 years ago
Replying to Ryan J Ollos <ryan.j.ollos@…>:
- Addition of a Select All checkbox in the table header.
Proposed changes in log:rjollos.git:t10994.2.
I've prefixed variable names containing jQuery objects with $
(SO:553734/121694). I find the convention to be useful and fairly common in practice, but it should be discussed as to whether it might be adopted in TracDev/CodingStyle#JavaScript.
comment:19 by , 10 years ago
Change from comment:18 committed to trunk in [12954:12955]. Next I'll prepare changes to integrate the drag and drop functionality of the AdminEnumListPlugin.
comment:20 by , 10 years ago
Replying to rjollos:
I've prefixed variable names containing jQuery objects with
$
(SO:553734/121694). I find the convention to be useful and fairly common in practice, but it should be discussed as to whether it might be adopted in TracDev/CodingStyle#JavaScript.
I noticed two small things:
- I didn't follow the above convention everywhere in the changeset.
this
is a jQuery object, so we don't need to wrap it in$()
. In fact,var $table = this;
isn't needed at all, and is just present for code clarity.-
trac/htdocs/js/trac.js
diff --git a/trac/htdocs/js/trac.js b/trac/htdocs/js/trac.js index 3029392..538334c 100644
a b 24 24 25 25 // Add a Select All group toggler to each thead in the table. 26 26 $.fn.addSelectAllTogglers = function() { 27 var $table = $(this);27 var $table = this; 28 28 if ($("tr td.sel", $table).length > 0) { 29 29 $("tr th.sel", $table).append( 30 30 $('<input type="checkbox" name="toggle_group" />').attr({ … … 36 36 }) 37 37 ); 38 38 $("tr td.sel", $table).click(function() { 39 var tbody = $(this).closest("tbody");40 var checkboxes = $("tr td.sel input",tbody);41 var numSelected = checkboxes.filter(":checked").length;39 var $tbody = $(this).closest("tbody"); 40 var $checkboxes = $("tr td.sel input", $tbody); 41 var numSelected = $checkboxes.filter(":checked").length; 42 42 var noneSelected = numSelected === 0; 43 var allSelected = numSelected === checkboxes.length;44 $("tr th.sel input", tbody.prev())43 var allSelected = numSelected === $checkboxes.length; 44 $("tr th.sel input", $tbody.prev()) 45 45 .prop({"checked": allSelected, 46 46 "indeterminate": !(noneSelected || allSelected)}); 47 47 });
-
follow-up: 22 comment:21 by , 10 years ago
Coding guideline added in TracDev/CodingStyle, but always open for further discussion of course.
comment:22 by , 10 years ago
Replying to rjollos:
Coding guideline added in TracDev/CodingStyle, but always open for further discussion of course.
I agree, it's useful.
comment:23 by , 10 years ago
Description: | modified (diff) |
---|
comment:24 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Changes from comment:20 committed in [12963].
comment:25 by , 10 years ago
API Changes: | modified (diff) |
---|
Sounds like a nice idea. Are you going to replace the current implementation completely, or are you going to build on the current (non-dynamic) functionality? That is, will the pages still work with JavaScript disabled?
We have always had a tradition in Trac to have static fallbacks for dynamic behavior. I'm not saying we should continue this forever (actually, I would rather advocate the opposite), just curious about your plan.