[Python-checkins] r52648 - in tracker/instances/python-dev: detectors/userauditor.py html/_generic.help-empty.html html/_generic.help-list.html html/_generic.help-search.html html/_generic.help-submit.html html/help.html html/help_controls.js html/home.html html/issue.index.html html/issue.item.html html/issue.search.html html/page.html html/style.css html/user.help-search.html html/user.help.html html/user.item.html html/user_utils.js

erik.forsberg python-checkins at python.org
Tue Nov 7 17:36:41 CET 2006


Author: erik.forsberg
Date: Tue Nov  7 17:36:39 2006
New Revision: 52648

Added:
   tracker/instances/python-dev/html/_generic.help-empty.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/_generic.help-empty.html
   tracker/instances/python-dev/html/_generic.help-list.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/_generic.help-list.html
   tracker/instances/python-dev/html/_generic.help-search.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/_generic.help-search.html
   tracker/instances/python-dev/html/_generic.help-submit.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/_generic.help-submit.html
   tracker/instances/python-dev/html/help.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/help.html
   tracker/instances/python-dev/html/user.help-search.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/user.help-search.html
   tracker/instances/python-dev/html/user.help.html
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/user.help.html
   tracker/instances/python-dev/html/user_utils.js
      - copied unchanged from r52638, tracker/vendor/roundup/current/templates/classic/html/user_utils.js
Modified:
   tracker/instances/python-dev/detectors/userauditor.py
   tracker/instances/python-dev/html/help_controls.js
   tracker/instances/python-dev/html/home.html
   tracker/instances/python-dev/html/issue.index.html
   tracker/instances/python-dev/html/issue.item.html
   tracker/instances/python-dev/html/issue.search.html
   tracker/instances/python-dev/html/page.html
   tracker/instances/python-dev/html/style.css
   tracker/instances/python-dev/html/user.item.html
Log:

Merge based on changes between /tracker/vendor/roundup/1.1.2 and
/tracker/vendor/roundup/current (roundup 1.2.1).

Needs roundup 1.2.1 to run.


Modified: tracker/instances/python-dev/detectors/userauditor.py
==============================================================================
--- tracker/instances/python-dev/detectors/userauditor.py	(original)
+++ tracker/instances/python-dev/detectors/userauditor.py	Tue Nov  7 17:36:39 2006
@@ -18,7 +18,7 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 #
-#$Id: userauditor.py,v 1.2 2003/11/11 22:25:37 richard Exp $
+#$Id: userauditor.py,v 1.3 2006/09/18 03:24:38 tobias-herp Exp $
 
 def audit_user_fields(db, cl, nodeid, newvalues):
     ''' Make sure user properties are valid.
@@ -29,7 +29,7 @@
     if newvalues.has_key('address') and ' ' in newvalues['address']:
         raise ValueError, 'Email address must not contain spaces'
 
-    if newvalues.has_key('roles'):
+    if newvalues.has_key('roles') and newvalues['roles']:
         roles = [x.lower().strip() for x in newvalues['roles'].split(',')]
         for rolename in roles:
             if not db.security.role.has_key(rolename):

Modified: tracker/instances/python-dev/html/help_controls.js
==============================================================================
--- tracker/instances/python-dev/html/help_controls.js	(original)
+++ tracker/instances/python-dev/html/help_controls.js	Tue Nov  7 17:36:39 2006
@@ -17,10 +17,10 @@
 function determineList() {
      // generate a comma-separated list of the checked items
      var list = new String('');
- 
+
      // either a checkbox object or an array of checkboxes
      var check = document.frm_help.check;
- 
+
      if ((check.length == undefined) && (check.checked != undefined)) {
          // only one checkbox on page
          if (check.checked) {
@@ -41,7 +41,17 @@
              }
          }
      }
-     return list;  
+     return list;
+}
+
+/**
+ * update the field in the opening window;
+ * the text_field variable must be set in the calling page
+ */
+function updateOpener() {
+  // write back to opener window
+  if (document.frm_help.check==undefined) { return; }
+  form[field].value = text_field.value;
 }
 
 function updateList() {
@@ -64,6 +74,40 @@
   }
 }
 
+function reviseList_framed(form, textfield) {
+  // update the checkboxes based on the preview field
+  // alert('reviseList_framed')
+  // alert(form)
+  if (form.check==undefined)
+      return;
+  // alert(textfield)
+  var to_check;
+  var list = textfield.value.split(",");
+  if (form.check.length==undefined) {
+      check = form.check;
+      to_check = false;
+      for (val in list) {
+          if (check.value==trim(list[val])) {
+              to_check = true;
+              break;
+          }
+      }
+      check.checked = to_check;
+  } else {
+    for (box=0; box < form.check.length; box++) {
+      check = form.check[box];
+      to_check = false;
+      for (val in list) {
+          if (check.value==trim(list[val])) {
+              to_check = true;
+              break;
+          }
+      }
+      check.checked = to_check;
+    }
+  }
+}
+
 function reviseList(vals) {
   // update the checkboxes based on the preview field
   if (document.frm_help.check==undefined) { return; }
@@ -116,8 +160,165 @@
 function selectField(name) {
     for(i=0; i < document.forms.length; ++i) {
       var obj = document.forms[i].elements[name];
-      if (obj && obj.focus){obj.focus();} 
+      if (obj && obj.focus){obj.focus();}
       if (obj && obj.select){obj.select();}
     }
 }
 
+function checkRequiredFields(fields)
+{
+    var bonk='';
+    var res='';
+    var argv = checkRequiredFields.arguments;
+    var argc = argv.length;
+    var input = '';
+    var val='';
+
+    for (var i=0; i < argc; i++) {
+        fi = argv[i];
+        input = document.getElementById(fi);
+        if (input) {
+            val = input.value
+            if (val == '' || val == '-1' || val == -1) {
+                if (res == '') {
+                    res = fi;
+                    bonk = input;
+                } else {
+                    res += ', '+fi;
+                }
+            }
+        } else {
+            alert('Field with id='+fi+' not found!')
+        }
+    }
+    if (res == '') {
+        return submit_once();
+    } else {
+        alert('Missing value here ('+res+')!');
+        if (window.event && window.event.returnvalue) {
+            event.returnValue = 0;    // work-around for IE
+        }
+        bonk.focus();
+        return false;
+    }
+}
+
+/**
+ * seeks the given value (2nd argument)
+ * in the value of the given input element (1st argument),
+ * which is considered a list of values, separated by commas
+ */
+function has_value(input, val)
+{
+    var actval = input.value
+    var arr = feld.value.split(',');
+    var max = arr.length;
+    for (i=0;i<max;i++) {
+        if (trim(arr[i]) == val) {
+            return true
+        }
+    }
+    return false
+}
+
+/**
+ * Switch Value:
+ * change the value of the given input field (might be of type text or hidden),
+ * adding or removing the value of the given checkbox field (might be a radio
+ * button as well)
+ *
+ * This function doesn't care whether or not the checkboxes of all values of
+ * interest are present; but of course it doesn't have total control of the
+ * text field.
+ */
+function switch_val(text, check)
+{
+    var switched_val = check.value
+    var arr = text.value.split(',')
+    var max = arr.length
+    if (check.checked) {
+        for (i=0; i<max; i++) {
+            if (trim(arr[i]) == switched_val) {
+                return
+            }
+        }
+	if (text.value)
+            text.value = text.value+','+switched_val
+	else
+            text.value = switched_val
+    } else {
+        var neu = ''
+	var changed = false
+        for (i=0; i<max; i++) {
+            if (trim(arr[i]) == switched_val) {
+                changed=true
+            } else {
+                neu = neu+','+trim(arr[i])
+            }
+        }
+        if (changed) {
+            text.value = neu.substr(1)
+        }
+    }
+}
+
+/**
+ * append the given value (2nd argument) to an input field
+ * (1st argument) which contains comma-separated values;
+ * see --> remove_val()
+ *
+ * This will work nicely even for batched lists
+ */
+function append_val(name, val)
+{
+    var feld = document.itemSynopsis[name];
+    var actval = feld.value;
+    if (actval == '') {
+        feld.value = val
+    } else {
+        var arr = feld.value.split(',');
+        var max = arr.length;
+        for (i=0;i<max;i++) {
+            if (trim(arr[i]) == val) {
+                return
+            }
+        }
+        feld.value = actval+','+val
+    }
+}
+
+/**
+ * remove the given value (2nd argument) from the comma-separated values
+ * of the given input element (1st argument); see --> append_val()
+ */
+function remove_val(name, val)
+{
+    var feld = document.itemSynopsis[name];
+    var actval = feld.value;
+    var changed=false;
+    if (actval == '') {
+	return
+    } else {
+        var arr = feld.value.split(',');
+        var max = arr.length;
+        var neu = ''
+        for (i=0;i<max;i++) {
+            if (trim(arr[i]) == val) {
+                changed=true
+            } else {
+                neu = neu+','+trim(arr[i])
+            }
+        }
+        if (changed) {
+            feld.value = neu.substr(1)
+        }
+    }
+}
+
+/**
+ * give the focus to the element given by id
+ */
+function focus2id(name)
+{
+    document.getElementById(name).focus();
+}

Modified: tracker/instances/python-dev/html/home.html
==============================================================================
--- tracker/instances/python-dev/html/home.html	(original)
+++ tracker/instances/python-dev/html/home.html	Tue Nov  7 17:36:39 2006
@@ -5,7 +5,7 @@
  whatever. It's a good idea to have the issues on the front page though
 -->
 <span tal:replace="structure python:db.issue.renderWith('index',
-    sort=('-', 'activity'), group=('+', 'priority'), filter=['status'],
+    sort=[('-', 'activity')], group=[('+', 'priority')], filter=['status'],
     columns=['id','activity','title','creator','assignedto', 'status'],
     filterspec={'status':['1','2']})" />
 <!-- SHA: 1fdaa3238149b4381d19a45a81deb6075de7d0e9 -->

Modified: tracker/instances/python-dev/html/issue.index.html
==============================================================================
--- tracker/instances/python-dev/html/issue.index.html	(original)
+++ tracker/instances/python-dev/html/issue.index.html	Tue Nov  7 17:36:39 2006
@@ -1,15 +1,15 @@
-<!-- dollarId: issue.index,v 1.2 2001/07/29 04:07:37 richard Exp dollar-->
+<!-- $Id: issue.index.html,v 1.25 2006/09/18 00:03:02 tobias-herp Exp $ -->
 <tal:block metal:use-macro="templates/page/macros/icing">
-<title metal:fill-slot="head_title" i18n:translate="" >
-	List of issues - 
-	<span tal:condition="request/dispname"
-          tal:replace="python:' %s - '%request.dispname" />
-	<span tal:replace="config/TRACKER_NAME" i18n:name="tracker" />
-	</title>
-<span metal:fill-slot="body_title" tal:omit-tag="python:1"
-	i18n:translate="">List of issues 
-	<span tal:condition="request/dispname"
-          tal:replace="python:' - %s' % request.dispname" />
+<title metal:fill-slot="head_title" >
+  <span tal:omit-tag="true" i18n:translate="" >List of issues</span>
+  <span tal:condition="request/dispname"
+   tal:replace="python:' - %s '%request.dispname"
+  /> - <span tal:replace="config/TRACKER_NAME" />
+</title>
+<span metal:fill-slot="body_title" tal:omit-tag="true">
+  <span tal:omit-tag="true" i18n:translate="" >List of issues</span>
+  <span tal:condition="request/dispname"
+   tal:replace="python:' - %s' % request.dispname" />
 </span>
 <td class="content" metal:fill-slot="content">
 
@@ -30,11 +30,13 @@
    <th tal:condition="request/show/creator" i18n:translate="">Creator</th>
    <th tal:condition="request/show/assignedto" i18n:translate="">Assigned&nbsp;To</th>
   </tr>
- <tal:block tal:repeat="i batch">
-  <tr tal:define="group python:request.group[1]"
-      tal:condition="python:group and batch.propchanged(group)">
-   <th tal:attributes="colspan python:len(request.columns)"
-       tal:content="python:str(i[group]) or '(no %s set)'%group" class="group">
+ <tal:block tal:repeat="i batch" condition=true>
+  <tr tal:define="group python:[r[1] for r in request.group]"
+      tal:condition="python:group and batch.propchanged(*group)">
+   <th tal:attributes="colspan python:len(request.columns)" class="group">
+    <tal:block tal:repeat="g group">
+     <tal:block tal:content="python:str(i[g]) or '(no %s set)'%g"/>
+    </tal:block>
    </th>
   </tr>
 
@@ -100,41 +102,49 @@
 <form method="get" class="index-controls"
     tal:attributes="action request/classname">
 
- <table class="form">
-  <tr tal:condition="batch">
-   <th i18n:translate="">Sort on:</th>
+ <table class="form" tal:define="n_sort python:2">
+  <tal:block tal:repeat="n python:range(n_sort)" tal:condition="batch">
+  <tr tal:define="key python:len(request.sort)>n and request.sort[n]">
+   <th>
+    <tal:block tal:condition="not:n" i18n:translate="">Sort on:</tal:block>
+   </th>
    <td>
-    <select name="@sort">
+    <select tal:attributes="name python:'@sort%d'%n">
      <option value="" i18n:translate="">- nothing -</option>
      <option tal:repeat="col context/properties"
              tal:attributes="value col/_name;
-                             selected python:col._name == request.sort[1]"
+                             selected python:key and col._name == key[1]"
              tal:content="col/_name"
              i18n:translate="">column</option>
     </select>
    </td>
    <th i18n:translate="">Descending:</th>
    <td><input type="checkbox" name="@sortdir"
-              tal:attributes="checked python:request.sort[0] == '-'"/>
+              tal:attributes="checked python:key and key[0] == '-'">
    </td>
   </tr>
-  <tr>
-   <th i18n:translate="">Group on:</th>
+  </tal:block>
+  <tal:block tal:repeat="n python:range(n_sort)" tal:condition="batch">
+  <tr tal:define="key python:len(request.group)>n and request.group[n]">
+   <th>
+    <tal:block tal:condition="not:n" i18n:translate="">Group on:</tal:block>
+   </th>
    <td>
-    <select name="@group">
+    <select tal:attributes="name python:'@group%d'%n">
      <option value="" i18n:translate="">- nothing -</option>
      <option tal:repeat="col context/properties"
              tal:attributes="value col/_name;
-                             selected python:col._name == request.group[1]"
+                             selected python:key and col._name == key[1]"
              tal:content="col/_name"
              i18n:translate="">column</option>
     </select>
    </td>
    <th i18n:translate="">Descending:</th>
    <td><input type="checkbox" name="@groupdir"
-              tal:attributes="checked python:request.group[0] == '-'"/>
+              tal:attributes="checked python:key and key[0] == '-'">
    </td>
   </tr>
+  </tal:block>
   <tr><td colspan="4">
               <input type="submit" value="Redisplay" i18n:attributes="value"/>
               <tal:block tal:replace="structure
@@ -147,4 +157,3 @@
 
 </td>
 </tal:block>
-<!-- SHA: 8a7f0580114904917683796f76dde4da8cc80d3b -->

Modified: tracker/instances/python-dev/html/issue.item.html
==============================================================================
--- tracker/instances/python-dev/html/issue.item.html	(original)
+++ tracker/instances/python-dev/html/issue.item.html	Tue Nov  7 17:36:39 2006
@@ -65,10 +65,12 @@
  <td>
   <span tal:replace="structure python:context.superseder.field(showid=1, size=20)" />
   <span tal:condition="context/is_edit_ok" tal:replace="structure python:db.issue.classhelp('id,title', property='superseder')" />
-  <span tal:condition="context/superseder" tal:repeat="sup context/superseder">
-   <br><span i18n:translate="">View: <a i18n:name="link" tal:content="sup/id"
-     tal:attributes="href string:issue${sup/id};
-                     title sup/title;"></a></span>
+  <span tal:condition="context/superseder">
+   <br><span i18n:translate="">View:</span>
+     <a tal:repeat="sup context/superseder"
+        tal:content="python:sup['id'] + ', '*(not repeat['sup'].end)"
+        tal:attributes="href string:issue${sup/id};
+                        title sup/title;"></a>
   </span>
  </td>
  <th i18n:translate="">Nosy List</th>

Modified: tracker/instances/python-dev/html/issue.search.html
==============================================================================
--- tracker/instances/python-dev/html/issue.search.html	(original)
+++ tracker/instances/python-dev/html/issue.search.html	Tue Nov  7 17:36:39 2006
@@ -7,17 +7,23 @@
 
 <form method="get" name="itemSynopsis"
       tal:attributes="action request/classname">
-
+      
 <table class="form" tal:define="
    cols python:request.columns or 'id activity title status assignedto'.split();
-   sort_on python:request.sort[1] or 'activity';
-   group_on python:request.group[1] or 'priority';
+   sort_on python:request.sort and request.sort[0] or nothing;
+   sort_desc python:sort_on and sort_on[0] == '-';
+   sort_on python:(sort_on and sort_on[1]) or 'activity';
+   group_on python:request.group and request.group[0] or nothing;
+   group_desc python:group_on and group_on[0] == '-';
+   group_on python:(group_on and group_on[1]) or 'priority';
 
    search_input templates/page/macros/search_input;
+   search_date templates/page/macros/search_date;
    column_input templates/page/macros/column_input;
    sort_input templates/page/macros/sort_input;
    group_input templates/page/macros/group_input;
    search_select templates/page/macros/search_select;
+   search_select_translated templates/page/macros/search_select_translated;
    search_multiselect templates/page/macros/search_multiselect;">
 
 <tr>
@@ -64,7 +70,7 @@
 
 <tr tal:define="name string:creation">
   <th i18n:translate="">Creation Date:</th>
-  <td metal:use-macro="search_input"></td>
+  <td metal:use-macro="search_date"></td>
   <td metal:use-macro="column_input"></td>
   <td metal:use-macro="sort_input"></td>
   <td metal:use-macro="group_input"></td>
@@ -86,7 +92,7 @@
 
 <tr tal:define="name string:activity">
   <th i18n:translate="">Activity:</th>
-  <td metal:use-macro="search_input"></td>
+  <td metal:use-macro="search_date"></td>
   <td metal:use-macro="column_input"></td>
   <td metal:use-macro="sort_input"></td>
   <td>&nbsp;</td>
@@ -110,7 +116,7 @@
                 db_klass string:priority;
                 db_content string:name;">
   <th i18n:translate="">Priority:</th>
-  <td metal:use-macro="search_select">
+  <td metal:use-macro="search_select_translated">
     <option metal:fill-slot="extra_options" value="-1" i18n:translate=""
             tal:attributes="selected python:value == '-1'">not selected</option>
   </td>
@@ -123,7 +129,7 @@
                 db_klass string:status;
                 db_content string:name;">
   <th i18n:translate="">Status:</th>
-  <td metal:use-macro="search_select">
+  <td metal:use-macro="search_select_translated">
     <tal:block metal:fill-slot="extra_options">
       <option value="-1,1,2" i18n:translate=""
               tal:attributes="selected python:value == '-1,1,2'">not closed</option>
@@ -177,14 +183,14 @@
 <tr>
 <th i18n:translate="">Sort Descending:</th>
 <td><input type="checkbox" name="@sortdir"
-           tal:attributes="checked python:request.sort[0] == '-' or request.sort[0] is None"/>
+           tal:attributes="checked sort_desc">
 </td>
 </tr>
 
 <tr>
 <th i18n:translate="">Group Descending:</th>
 <td><input type="checkbox" name="@groupdir"
-           tal:attributes="checked python:request.group[0] == '-'"/>
+           tal:attributes="checked group_desc">
 </td>
 </tr>
 

Modified: tracker/instances/python-dev/html/page.html
==============================================================================
--- tracker/instances/python-dev/html/page.html	(original)
+++ tracker/instances/python-dev/html/page.html	Tue Nov  7 17:36:39 2006
@@ -13,6 +13,7 @@
  tal:attributes="content string:text/html;; charset=${request/client/charset}" />
 <script tal:replace="structure request/base_javascript">
 </script>
+<metal:x define-slot="more-javascript" />
 
 </head>
 <body>
@@ -195,9 +196,27 @@
 
 See issue.search.html in the classic template for examples.
 -->
+
+<!-- creates a th and a label: -->
+<th metal:define-macro="th_label"
+    tal:define="required required | python:[]"
+    tal:attributes="class python:(name in required) and 'required' or nothing">
+  <label tal:attributes="for name" tal:content="label" i18n:translate="">text</label>
+	<metal:x define-slot="behind_the_label" />
+</th>
+
 <td metal:define-macro="search_input">
   <input tal:attributes="value python:request.form.getvalue(name) or nothing;
-                         name name"/>
+                         name name;
+                         id name">
+</td>
+
+<td metal:define-macro="search_date">
+  <input tal:attributes="value python:request.form.getvalue(name) or nothing;
+                         name name;
+                         id name">
+  <a class="classhelp"
+	 tal:attributes="href python:'''javascript:help_window('issue?@template=calendar&property=%s&form=itemSynopsis', 300, 200)'''%name">(cal)</a>
 </td>
 
 <td metal:define-macro="search_popup">
@@ -206,26 +225,56 @@
     string (eg. "id,title" or "id,name,description") as well as name
   -->
   <input tal:attributes="value python:request.form.getvalue(name) or nothing;
-                         name name"/>
+                         name name;
+                         id name">
   <span tal:replace="structure python:db.issue.classhelp(columns,
                                       property=name)" />
 </td>
 
 <td metal:define-macro="search_select">
-  <select tal:attributes="name name"
+  <select tal:attributes="name name; id name"
           tal:define="value python:request.form.getvalue(name)">
     <option value="" i18n:translate="">don't care</option>
-    <tal:block metal:define-slot="extra_options"></tal:block>
-    <option value="" i18n:translate="">------------</option>
+    <metal:slot define-slot="extra_options" />
+    <option value="" i18n:translate="" disabled="disabled">------------</option>
     <option tal:repeat="s python:db[db_klass].list()"
             tal:attributes="value s/id; selected python:value == s.id"
             tal:content="python:s[db_content]"></option>
   </select>
 </td>
 
+<!-- like search_select, but translates the further values.
+Could extend it (METAL 1.1 attribute "extend-macro")
+-->
+<td metal:define-macro="search_select_translated">
+  <select tal:attributes="name name; id name"
+          tal:define="value python:request.form.getvalue(name)">
+    <option value="" i18n:translate="">don't care</option>
+    <metal:slot define-slot="extra_options" />
+    <option value="" i18n:translate="" disabled="disabled">------------</option>
+    <option tal:repeat="s python:db[db_klass].list()"
+            tal:attributes="value s/id; selected python:value == s.id"
+						tal:content="python:s[db_content]"
+						i18n:translate=""></option>
+  </select>
+</td>
+
+<!-- currently, there is no convenient API to get a list of all roles -->
+<td metal:define-macro="search_select_roles"
+	  tal:define="onchange onchange | nothing">
+  <select name=roles id=roles tal:attributes="onchange onchange">
+    <option value="" i18n:translate="">don't care</option>
+    <option value="" i18n:translate="" disabled="disabled">------------</option>
+    <option value="User">User</option>
+    <option value="Admin">Admin</option>
+    <option value="Anonymous">Anonymous</option>
+  </select>
+</td>
+
 <td metal:define-macro="search_multiselect">
   <input tal:attributes="value python:request.form.getvalue(name) or nothing;
-                         name name"/>
+                         name name;
+                         id name">
   <span tal:replace="structure python:db[db_klass].classhelp(db_content,
                                         property=name, width='600')" />
 </td>
@@ -265,3 +314,30 @@
          tal:attributes="value name;
                          checked python:name == group_on"/>
 </td>
+
+<!--
+The following macros are intended for user editing.
+
+The invoking context must define a "name" variable which names the
+property being searched; the "edit_ok" variable tells whether the
+current user is allowed to edit.
+
+See user.item.html in the classic template for examples.
+-->
+<script metal:define-macro="user_utils" type="text/javascript" src="@@file/user_utils.js"></script>
+
+<!-- src: value will be re-used for other input fields -->
+<input metal:define-macro="user_src_input"
+    type="text" tal:attributes="onblur python:edit_ok and 'split_name(this)';
+    id name; name name; value value; readonly not:edit_ok"
+    value="heinz.kunz">
+<!-- normal: no re-using -->
+<input metal:define-macro="user_normal_input" type="text"
+    tal:attributes="id name; name name; value value; readonly not:edit_ok"
+    value="heinz">
+<!-- password: type; no initial value -->
+    <input metal:define-macro="user_pw_input" type="password"
+    tal:attributes="id name; name name; readonly not:edit_ok" value="">
+    <input metal:define-macro="user_confirm_input" type="password"
+    tal:attributes="id name; name string:@confirm@$name; readonly not:edit_ok" value="">
+

Modified: tracker/instances/python-dev/html/style.css
==============================================================================
--- tracker/instances/python-dev/html/style.css	(original)
+++ tracker/instances/python-dev/html/style.css	Tue Nov  7 17:36:39 2006
@@ -116,7 +116,7 @@
 /* style for search forms */
 ul.search-checkboxes {
     display: inline;
-    padding: none;
+    padding: 0;
     list-style: none;
 }
 ul.search-checkboxes > li {
@@ -413,4 +413,13 @@
   font-weight: bold;
   text-align: left;
 }
-/* SHA: a055019fd4171164d8b3651575c38a33ef90511a */
+
+input[type="text"]:focus,
+input[type="checkbox"]:focus,
+input[type="radio"]:focus,
+input[type="password"]:focus,
+textarea:focus, select:focus {
+  background-color: #ffffc0;
+}
+
+

Modified: tracker/instances/python-dev/html/user.item.html
==============================================================================
--- tracker/instances/python-dev/html/user.item.html	(original)
+++ tracker/instances/python-dev/html/user.item.html	Tue Nov  7 17:36:39 2006
@@ -1,24 +1,31 @@
 <!-- dollarId: user.item,v 1.7 2002/08/16 04:29:04 richard Exp dollar-->
-<tal:block metal:use-macro="templates/page/macros/icing">
+<tal:doc metal:use-macro="templates/page/macros/icing"
+define="edit_ok context/is_edit_ok"
+>
 <title metal:fill-slot="head_title">
-<tal:block condition="context/id" i18n:translate=""
+<tal:if condition="context/id" i18n:translate=""
  >User <span tal:replace="context/id" i18n:name="id"
  />: <span tal:replace="context/username" i18n:name="title"
  /> - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker"
-/></tal:block>
-<tal:block condition="not:context/id" i18n:translate=""
+/></tal:if>
+<tal:if condition="not:context/id" i18n:translate=""
  >New User - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker"
-/></tal:block>
+/></tal:if>
 </title>
-<tal:block metal:fill-slot="body_title">
- <span tal:condition="python: not (context.id or context.is_edit_ok())"
+<metal:slot fill-slot="more-javascript">
+<script metal:use-macro="templates/page/macros/user_utils"></script>
+<script type="text/javascript" src="@@file/help_controls.js"></script>
+</metal:slot>
+<tal:block metal:fill-slot="body_title"
+  define="edit_ok context/is_edit_ok">
+ <span tal:condition="python: not (context.id or edit_ok)"
   tal:omit-tag="python:1" i18n:translate="">New User</span>
- <span tal:condition="python: not context.id and context.is_edit_ok()"
+ <span tal:condition="python: not context.id and edit_ok"
   tal:omit-tag="python:1" i18n:translate="">New User Editing</span>
- <span tal:condition="python: context.id and not context.is_edit_ok()"
+ <span tal:condition="python: context.id and not edit_ok"
   tal:omit-tag="python:1" i18n:translate="">User<tal:x
   replace="context/id" i18n:name="id" /></span>
- <span tal:condition="python: context.id and context.is_edit_ok()"
+ <span tal:condition="python: context.id and edit_ok"
   tal:omit-tag="python:1" i18n:translate="">User<tal:x
   replace="context/id" i18n:name="id" /> Editing</span>
 </tal:block>
@@ -30,75 +37,109 @@
 
 <div tal:condition="context/is_view_ok">
 
-<form method="POST" onSubmit="return submit_once()"
+<form method="POST"
+      tal:define="required python:'username address'.split()"
       enctype="multipart/form-data"
-      tal:attributes="action context/designator">
-
-<table class="form">
- <tr>
-  <th i18n:translate="">Name</th>
-  <td tal:content="structure context/realname/field">realname</td>
- </tr>
- <tr>
-  <th class="required" i18n:translate="">Login Name</th>
-  <td tal:content="structure context/username/field">username</td>
- </tr>
- <tr tal:condition="context/is_edit_ok">
-  <th i18n:translate="">Login Password</th>
-  <td tal:content="structure context/password/field">password</td>
- </tr>
- <tr tal:condition="context/is_edit_ok">
-  <th i18n:translate="">Confirm Password</th>
-  <td tal:content="structure context/password/confirm">password</td>
- </tr>
- <tr tal:condition="python:request.user.hasPermission('Web Roles')">
-  <th i18n:translate="">Roles</th>
-  <td>
-   <input tal:condition="context/id"
-          tal:replace="structure context/roles/field">
-   <input name="roles" tal:condition="not:context/id"
-          tal:attributes="value db/config/NEW_WEB_USER_ROLES">
+      tal:attributes="action context/designator;
+      onSubmit python:'return checkRequiredFields(\'%s\')'%'\', \''.join(required);
+      ">
+<table class="form" tal:define="
+  th_label templates/page/macros/th_label;
+  src_input templates/page/macros/user_src_input;
+  normal_input templates/page/macros/user_normal_input;
+  pw_input templates/page/macros/user_pw_input;
+  confirm_input templates/page/macros/user_confirm_input;
+  edit_ok context/is_edit_ok;
+  ">
+ <tr tal:define="name string:realname; label string:Name; value context/realname; edit_ok edit_ok">
+  <th metal:use-macro="th_label">Name</th>
+  <td><input name="realname" metal:use-macro="src_input"></td>
+ </tr>
+ <tr tal:define="name string:username; label string:Login Name; value context/username">
+   <th metal:use-macro="th_label">Login Name</th>
+   <td><input metal:use-macro="src_input"></td>
+ </tr>
+ <tal:if condition="edit_ok">
+ <tr tal:define="name string:password; label string:Login Password">
+  <th metal:use-macro="th_label">Login Password</th>
+  <td><input metal:use-macro="pw_input" type="password"></td>
+ </tr>
+ <tr tal:define="name string:password; label string:Confirm Password">
+  <th metal:use-macro="th_label">Confirm Password</th>
+  <td><input metal:use-macro="confirm_input" type="password"></td>
+ </tr>
+ </tal:if>
+ <tal:if condition="python:request.user.hasPermission('Web Roles')">
+ <tr tal:define="name string:roles; label string:Roles;">
+  <th><label for="roles" i18n:translate="">Roles</label></th>
+  <td tal:define="gips context/id">
+    <tal:subif condition=gips define="value context/roles">
+      <input metal:use-macro="normal_input">
+    </tal:subif>
+    <tal:subif condition="not:gips" define="value db/config/NEW_WEB_USER_ROLES">
+      <input metal:use-macro="normal_input">
+    </tal:subif>
    <tal:block i18n:translate="">(to give the user more than one role,
     enter a comma,separated,list)</tal:block>
   </td>
  </tr>
- <tr>
-  <th i18n:translate="">Phone</th>
-  <td tal:content="structure context/phone/field">phone</td>
+ </tal:if>
+
+ <tr tal:define="name string:phone; label string:Phone; value context/phone">
+  <th metal:use-macro="th_label">Phone</th>
+  <td><input name="phone" metal:use-macro="normal_input"></td>
  </tr>
- <tr>
-  <th i18n:translate="">Organisation</th>
-  <td tal:content="structure context/organisation/field">organisation</td>
+
+ <tr tal:define="name string:organisation; label string:Organisation; value context/organisation">
+  <th metal:use-macro="th_label">Organisation</th>
+  <td><input name="organisation" metal:use-macro="normal_input"></td>
  </tr>
- <tr>
-  <th i18n:translate="">Timezone</th>
-  <td>
-   <input tal:replace="structure context/timezone/field">
-   <tal:block i18n:translate="">(this is a numeric hour offset, the default is
+
+ <tr tal:condition="python:edit_ok or context.timezone"
+     tal:define="name string:timezone; label string:Timezone; value context/timezone">
+  <th metal:use-macro="th_label">Timezone</th>
+  <td><input name="timezone" metal:use-macro="normal_input">
+   <tal:block tal:condition="edit_ok" i18n:translate="">(this is a numeric hour offset, the default is
     <span tal:replace="db/config/DEFAULT_TIMEZONE" i18n:name="zone"
     />)</tal:block>
   </td>
  </tr>
- <tr>
-  <th class="required" i18n:translate="">E-mail address</th>
-  <td tal:define="mailto context/address/field">
-   <a tal:condition="not:context/is_edit_ok"
-    tal:attributes="href string:mailto:${mailto}" tal:content="mailto"
-   /><span tal:condition="context/is_edit_ok" tal:replace="structure mailto" />
+
+ <tr tal:define="name string:address; label string:E-mail address; value context/address">
+  <th metal:use-macro="th_label">E-mail address</th>
+  <td tal:define="mailto python:context.address.field(id='address');
+	  mklink python:mailto and not edit_ok">
+      <a href="mailto:calvin at the-z.org"
+		  tal:attributes="href string:mailto:$value"
+		  tal:content="value"
+          tal:condition="python:mklink">calvin at the-z.org</a>
+      <tal:if condition=edit_ok>
+      <input metal:use-macro="src_input" value="calvin at the-z.org">
+      </tal:if>
+      &nbsp;
   </td>
  </tr>
+
  <tr>
-  <th i18n:translate="">Alternate E-mail addresses<br>One address per line</th>
-  <td tal:content="structure context/alternate_addresses/multiline">alternate_addresses</td>
+  <th><label for="alternate_addresses" i18n:translate="">Alternate E-mail addresses<br>One address per line</label></th>
+  <td>
+    <textarea rows=5 cols=40 tal:replace="structure context/alternate_addresses/multiline">nobody at nowhere.org
+anybody at everywhere.net
+(alternate_addresses)
+    </textarea>
+  </td>
  </tr>
 
- <tr tal:condition="context/is_edit_ok">
+ <tr tal:condition="edit_ok">
   <td>
    &nbsp;
    <input type="hidden" name="@template" value="item">
-   <input type="hidden" name="@required" value="username,address">
+   <input type="hidden" name="@required" value="username,address"
+          tal:attributes="value python:','.join(required)">
+  </td>
+  <td><input type="submit" value="save" tal:replace="structure context/submit"><!--submit button here-->
+    <input type=reset>
   </td>
-  <td tal:content="structure context/submit">submit button here</td>
  </tr>
 </table>
 </form>
@@ -119,4 +160,4 @@
 
 </td>
 
-</tal:block>
+</tal:doc>


More information about the Python-checkins mailing list