[Rt-commit] r2686 - in rt/branches/PLATANO-EXPERIMENTAL-CSS: .
html/NoAuth html/Prefs html/Widgets
jesse at bestpractical.com
jesse at bestpractical.com
Sat Apr 16 04:13:51 EDT 2005
Author: jesse
Date: Sat Apr 16 04:13:51 2005
New Revision: 2686
Added:
rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Widgets/SelectionBox
Modified:
rt/branches/PLATANO-EXPERIMENTAL-CSS/ (props changed)
rt/branches/PLATANO-EXPERIMENTAL-CSS/html/NoAuth/list.js
rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Prefs/MyRT.html
Log:
r13075 at hualien: jesse | 2005-04-16 03:00:50 -0400
r12969 at hualien: jesse | 2005-04-16 02:16:02 -0400
r6494 at hualien: jesse | 2005-03-06 17:46:01 -0500
r6411 at hualien (orig r2293): clkao | 2005-03-06 10:10:26 -0500
Land SelectionBox Widget, which works for both js and cgi.
Make the frontpage customization UI use SelectionBox.
Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/NoAuth/list.js
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/NoAuth/list.js (original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/NoAuth/list.js Sat Apr 16 04:13:51 2005
@@ -7,63 +7,76 @@
sels : null,
list : function (src, esrc, name) { this.init(src, esrc, name); },
read : function () {
- var i = 0;
- if(this.xml.readyState!=4) { setTimeout(this.name+".read()", 100); }
- else if(this.xml.status!=200) alert("Document not available.");
- else {
- var doc = this.xml.responseXML;
- var nNode = null;
- if(doc.childNodes[0].nodeName=="parseerror") alert("Parse Error.");
- doc = doc.getElementsByTagName("list")[0];
- for(i=0;i<doc.childNodes.length;i++) {
- if(doc.childNodes[i].childNodes.length>0) {
- nNode = document.createElement("option");
- nNode.appendChild(document.createTextNode(doc.childNodes[i].childNodes[0].nodeValue));
- this.sels[0].appendChild(nNode);
- }
- }
- }
+ var i = 0;
+ if(this.xml.readyState!=4) { setTimeout(this.name+".read()", 100); }
+ else if(this.xml.status!=200) alert("Document not available.");
+ else {
+ var doc = this.xml.responseXML;
+ var nNode = null;
+ if(doc.childNodes[0].nodeName=="parseerror") alert("Parse Error.");
+ doc = doc.getElementsByTagName("list")[0];
+ for(i=0;i<doc.childNodes.length;i++) {
+ if(doc.childNodes[i].childNodes.length>0) {
+ nNode = document.createElement("option");
+ nNode.appendChild(document.createTextNode(doc.childNodes[i].childNodes[0].nodeValue));
+ this.sels[0].appendChild(nNode);
+ }
+ }
+ }
},
-
+
init : function (src,esrc,name) {
- if(!src) return;
- this.name = name;
- this.sels = new Array();
- var i = 0;
- for(i=0;i<src.childNodes.length;i++) {
- if(src.childNodes[i].nodeName=="select" || src.childNodes[i].nodeName=="SELECT") {
- this.sels.push(src.childNodes[i]);
- } if((src.childNodes[i].nodeName=="input" || src.childNodes[i].nodeName=="INPUT")
- && (src.childNodes[i].type=="button" || src.childNodes[i].type=="BUTTON")) {
- if(src.childNodes[i].name=="add") src.childNodes[i].onclick = new Function(this.name+".add();");
- if(src.childNodes[i].name=="remove")
- src.childNodes[i].onclick = new Function(this.name+".remove();");
- if(src.childNodes[i].name=="moveup")
- src.childNodes[i].onclick = new Function(this.name+".moveup();");
- if(src.childNodes[i].name=="movedown")
- src.childNodes[i].onclick = new Function(this.name+".movedown();");
- } if((src.childNodes[i].nodeName=="input" || src.childNodes[i].nodeName=="INPUT")
- && (src.childNodes[i].type=="submit" || src.childNodes[i].type=="SUBMIT")) {
- src.childNodes[i].onclick = new Function(this.name+".selectAll();");
- }
- }
- if (esrc) {
- this.xml = (window.navigator.appName!="Microsoft Internet Explorer"
- ?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"));
- this.xml.open("GET", esrc);
- this.xml.send("");
- setTimeout(this.name+".read()", 100);
- }
+ if(!src) return;
+ this.name = name;
+ this.sels = new Array();
+ var i = 0;
+ for(i=0;i<src.childNodes.length;i++) {
+ if(src.childNodes[i].nodeName=="select" || src.childNodes[i].nodeName=="SELECT") {
+ this.sels.push(src.childNodes[i]);
+ }
+
+ if((src.childNodes[i].nodeName=="input" || src.childNodes[i].nodeName=="INPUT")
+ && (src.childNodes[i].name=="fromjs")) {
+ src.childNodes[i].value = 1;
+ }
+
+ if((src.childNodes[i].nodeName=="input" || src.childNodes[i].nodeName=="INPUT")
+ && (src.childNodes[i].type=="submit" || src.childNodes[i].type=="SUBMIT")) {
+
+ if(src.childNodes[i].name != "submit")
+ src.childNodes[i].type = "button";
+
+ if(src.childNodes[i].name=="add")
+ src.childNodes[i].onclick = new Function(this.name+".add();");
+ if(src.childNodes[i].name=="remove")
+ src.childNodes[i].onclick = new Function(this.name+".remove();");
+ if(src.childNodes[i].name=="moveup")
+ src.childNodes[i].onclick = new Function(this.name+".moveup();");
+ if(src.childNodes[i].name=="movedown")
+ src.childNodes[i].onclick = new Function(this.name+".movedown();");
+ if(src.childNodes[i].type=="submit") {
+ src.childNodes[i].onclick = new Function(this.name+".selectAll();");
+ }
+
+ }
+ }
+ if (esrc) {
+ this.xml = (window.navigator.appName!="Microsoft Internet Explorer"
+ ?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"));
+ this.xml.open("GET", esrc);
+ this.xml.send("");
+ setTimeout(this.name+".read()", 100);
+ }
},
-
+
add : function() {
- var i, j = 0;
- var dNode = null;
- for(i=0;i<this.sels[0].length;i++) if(this.sels[0][i].selected) {
- for(j=0;j<this.sels[1].length;j++) if(this.sels[1][j].value==this.sels[0][i].value) break;
- if(j==this.sels[1].length) dNode = this.sels[0][i].cloneNode(true),
- this.sels[1].appendChild(dNode);
- }
+ var i, j = 0;
+ var dNode = null;
+ for(i=0;i<this.sels[0].length;i++) if(this.sels[0][i].selected) {
+ for(j=0;j<this.sels[1].length;j++) if(this.sels[1][j].value==this.sels[0][i].value) break;
+ if(j==this.sels[1].length) dNode = this.sels[0][i].cloneNode(true),
+ this.sels[1].appendChild(dNode);
+ }
},
moveup : function() { this.move(-1); },
Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Prefs/MyRT.html
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Prefs/MyRT.html (original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Prefs/MyRT.html Sat Apr 16 04:13:51 2005
@@ -49,48 +49,20 @@
Title => $title
&>
-<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/class.js"></script>
-<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/list.js"></script>
+<& /Widgets/SelectionBox:header &>
<& /Elements/ListActions, actions => \@actions &>
<a href="<% $ARGS{'referer'} %>"><&|/l&>Go back</&></a><br>
% for my $pane (@panes) {
-<h2><% $pane %></h2>
-<FORM METHOD="POST" ACTION="MyRT.html" name="MyRT-<% $pane %>" id="MyRT-<% $pane %>">
-<input type="hidden" name="referer" value="<%$ARGS{'referer'}%>">
-List of available items:<br>
-<select name="PortletList" multiple >
-% for (@items) {
-<option value="<% $_->[0] %>"><% $_->[1] %></option>
+<& /Widgets/SelectionBox:show, self => $pane &>
% }
-</select>
-<input name="add" type="button" value="->"/>
-<select name="PortletList-<%$pane%>" multiple>
-% for (@{$current_portlets->{$pane}}) {
-<option value="<% $_ %>"><% $item_map{$_} %></option>
-% }
-</select>
- <input name="moveup" type="button" value="^"/>
- <input name="movedown" type="button" value="v"/>
- <input name="remove" type="button" value="X"/>
- <input name="submit" type="submit" value="submit"/>
-%#<& /Elements/Submit, Caption => loc("Save"), Label => loc('Save'), Name => 'Save' &>
-
-</form>
-% }
-<script type="text/javascript">
-% my $i = 1;
-% for my $pane (@panes) {
-var list<%$i%> = new list(document.getElementById("MyRT-<% $pane %>"), 0, "list<%$i%>");
-% ++$i;
-% }
-</script>
<%INIT>
my @actions;
-$ARGS{'referer'} ||= $ENV{'HTTP_REFERER'};
+
my $title = loc("Customize").' '.loc("My RT");
my $user = $session{'CurrentUser'}->UserObj;
+$ARGS{'referer'} ||= $ENV{'HTTP_REFERER'};
unless (exists $session{'my_rt_portlets'}) {
my ($d_portlets) = RT::System->new($session{'CurrentUser'})->Attributes->Named('My RT');
@@ -130,33 +102,28 @@
}
my %item_map = map {$_->[0] => $_->[1]} @items;
+my @panes;
+for my $pane ('main', 'right') {
+ push @panes,
+ $m->comp ('/Widgets/SelectionBox:new',
+ Action => 'MyRT.html',
+ Name => $pane,
+ Available => \@items,
+ OnSubmit =>
+ sub { my $sel = shift;
+ $portlets->{$pane} =
+ [map { m/(\w+)-(.*)$}/;
+ { type => $1,
+ name => $2,
+ }} @{$sel->{Current}}];
+ $user->SetPreferences('My RT', $portlets);
+ push @actions, loc ('Preferences saved for [_1].', $pane);
+ delete $session{'my_rt_portlets'};
-my @panes = ('main', 'right');
-
-# build
-#if ($ARGS{'Save'}) {
-if ($ARGS{'submit'}) {
- for my $pane (@panes) {
- my $this = $ARGS{'PortletList-'.$pane};
- $this = [$this] unless ref ($this);
- next unless $ARGS{'PortletList-'.$pane};
- $portlets->{$pane} =
- [map { m/(\w+)-(.*)$}/;
- # XXX: CHECK!
- { type => $1,
- name => $2,
- }} @$this];
- }
-
- $user->SetPreferences('My RT', $portlets);
- push @actions, loc ('Preferences saved.');
- delete $session{'my_rt_portlets'};
+ },
+ Selected => [map {join('-',@{$_}{qw/type name/})} @{$portlets->{$pane}}]);
}
-my $current_portlets;
-for my $pane (@panes) {
- $current_portlets->{$pane}
- = [map {join('-',@{$_}{qw/type name/})} @{$portlets->{$pane}}];
-}
+$m->comp ('/Widgets/SelectionBox:process', %ARGS, self => $_) for @panes;
</%INIT>
Added: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Widgets/SelectionBox
==============================================================================
--- (empty file)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Widgets/SelectionBox Sat Apr 16 04:13:51 2005
@@ -0,0 +1,218 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+
+%# The SelectionBox Widget
+%#
+%# SYNOPSIS
+%#
+%# include javascript:
+%# <& /Widgets/SelectionBox:header &>
+%#
+%# <%init>:
+%# my $sel = $m->comp ('/Widgets/SelectionBox:new',
+%# Action => me.html',
+%# Name => 'my-selection',
+%# Available => \@items,
+%# # you can do things with @{$sel->{Current}} in the
+%# # OnSubmit callback
+%# OnSubmit => sub { my $sel = shift; },
+%# Selected => \@selected);
+%#
+%# $m->comp ('/Widgets/SelectionBox:process', %ARGS, self => $sel)
+%#
+%# where @items is an arrayref, each element is [value, label],
+%# and selected is an arrayref of selected values from @items.
+%#
+%# and in html:
+%# <& /Widgets/SelectionBox:show, self => $sel &>
+%#
+<%method header>
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/class.js"></script>
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/list.js"></script>
+</%method>
+
+<%method new>
+
+<%init>
+return \%ARGS;
+</%init>
+</%method>
+
+<%method process>
+<%init>
+unless ($ARGS{$self->{Name}.'-Submit'}) {
+ # init
+ $self->{Current} = $self->{Selected};
+ $self->{Selected} = [];
+ return;
+}
+
+$self->{Selected} = $ARGS{$self->{Name}.'-Selected'};
+$self->{Selected} = [$self->{Selected}] unless ref ($self->{Selected});
+
+if ($ARGS{fromjs}) {
+ $self->{Current} = $self->{Selected};
+}
+else {
+ my $current = $self->{Current} = $ARGS{$self->{Name}.'-Current'};
+ ++$self->{Modified};
+ if ($current && !ref ($current)) {
+ $current = [$current];
+ }
+
+ if ($ARGS{add}) {
+ my $choosed = $ARGS{$self->{Name}.'-Available'};
+ for my $add (ref($choosed) ? @$choosed : $choosed) {
+ next if grep { $_ eq $add } @$current;
+ push @$current, $add;
+ }
+ }
+
+ if ($ARGS{remove}) {
+ my $choosed = $ARGS{$self->{Name}.'-Selected'};
+ for my $del (ref($choosed) ? @$choosed : $choosed) {
+ @$current = map { $_ eq $del ? () : $_ } @$current;
+ }
+ }
+
+ if ($ARGS{moveup} or $ARGS{movedown}) {
+ my $offset = $ARGS{moveup} ? 1 : 0;
+ my $choosed = $ARGS{$self->{Name}.'-Selected'};
+ $choosed = [$choosed] unless ref ($choosed);
+ my $canmove = 0; # not in the cornor
+ for my $i ($ARGS{moveup} ? 0..$#{$current} : reverse 0..$#{$current}) {
+ if (grep {$_ eq $current->[$i]} @$choosed) {
+ if ($canmove) {
+ splice (@$current, $i-$offset, 2,
+ @{$current}[$i+1-$offset,$i-$offset]);
+ }
+ }
+ else {
+ ++$canmove;
+ }
+ }
+ }
+
+ $self->{Current} = $current;
+}
+
+# XXX: Verify Current are within $self->{Available} here
+
+if ($ARGS{submit}) {
+ $self->{OnSubmit}->($self);
+ delete $self->{Modified};
+}
+
+</%init>
+<%ARGS>
+$self => undef
+</%ARGS>
+
+</%method>
+
+<%method current>
+% for (@{$self->{Current}}) {
+<input type="hidden" name="<% $self->{Name} %>-Current" value="<%$_%>">
+% }
+<%INIT>
+</%INIT>
+<%ARGS>
+$self => undef
+</%ARGS>
+
+</%method>
+
+<%method show>
+<h2><% $name %></h2>
+<FORM METHOD="POST" ACTION="<%$self->{Action}%>" name="SelectionBox-<% $name %>" id="SelectionBox-<% $name %>">
+<input type="hidden" name="<% $self->{Name} %>-Submit" value="1">
+<& SelectionBox:current, self => $self &>
+<input type="hidden" name="referer" value="<%$ARGS{'referer'}%>">
+<input type="hidden" name="fromjs" value="0">
+Available:
+% if ($self->{Modified}) {
+<b>(Modified, Please save)</b>
+% }
+<br>
+<select name="<%$name%>-Available" multiple >
+% for (@{$self->{Available}}) {
+<option value="<% $_->[0] %>"><% $_->[1] %></option>
+% }
+</select>
+<input name="add" type="submit" value="->"/>
+<select name="<%$name%>-Selected" multiple>
+% for (@{$self->{Current}}) {
+<option value="<% $_ %>"
+% if (exists $selected{$_}) {
+SELECTED
+% }
+><% $item_map{$_} %></option>
+% }
+</select>
+ <input name="moveup" type="submit" value="^"/>
+ <input name="movedown" type="submit" value="v"/>
+ <input name="remove" type="submit" value="X"/>
+ <input name="submit" type="submit" value="Save"/>
+
+%# the save button does not work because it's not direct child of the form element
+%#<& /Elements/Submit, Caption => loc("Save"), Label => loc('Save'), Name => $name.'-Save' &>
+
+</form>
+
+<script type="text/javascript">
+var list_<%$name%> = new list(document.getElementById("SelectionBox-<% $name %>"), 0, "list_<%$name%>");
+</script>
+<%ARGS>
+$self => undef
+</%ARGS>
+<%INIT>
+my $name = $self->{Name};
+my %selected = map {$_ => 1} @{$self->{Selected}};
+my %item_map = map {$_->[0] => $_->[1]} @{$self->{Available}};
+$ARGS{'referer'} ||= $ENV{'HTTP_REFERER'};
+</%INIT>
+
+</%method>
More information about the Rt-commit
mailing list