Edgewall Software

Ticket #899: 899-custom-field-hints-r7495.2.patch

File 899-custom-field-hints-r7495.2.patch, 6.7 KB (added by rblank, 3 months ago)

Complete patch including unit tests

  • trac/ticket/api.py

    diff --git a/trac/ticket/api.py b/trac/ticket/api.py
    a b  
    264264                'type': config.get(name), 
    265265                'order': config.getint(name + '.order', 0), 
    266266                'label': config.get(name + '.label') or name.capitalize(), 
     267                'hint': config.get(name + '.hint') or None, 
    267268                'value': config.get(name + '.value', '') 
    268269            } 
    269270            if field['type'] == 'select' or field['type'] == 'radio': 
  • trac/ticket/templates/ticket.html

    diff --git a/trac/ticket/templates/ticket.html b/trac/ticket/templates/ticket.html
    a b  
    303303              <py:for each="idx, field in enumerate(row)" 
    304304                      py:with="value = ticket.get_value_or_default(field.name)"> 
    305305                <th class="col${idx + 1}" py:if="idx == 0 or not fullrow"> 
    306                   <label for="field-${field.name}" py:if="field" 
    307                          py:strip="field.type == 'radio'">${field.edit_label or field.label or field.name}:</label> 
     306                  <label for="${field.type != 'radio' and ('field-' + field.name) or None}" 
     307                         py:if="field">${field.edit_label or field.label or field.name}:</label> 
    308308                </th> 
    309309                <td class="col${idx + 1}" py:if="idx == 0 or not fullrow" 
    310310                    colspan="${fullrow and 3 or None}"> 
    311311                  <py:choose test="field.type" py:if="field"> 
    312                     <select py:when="'select'" id="field-${field.name}" name="field_${field.name}"> 
     312                    <select py:when="'select'" id="field-${field.name}" name="field_${field.name}" title="${field.hint}"> 
    313313                      <option py:if="field.optional"></option> 
    314314                      <option py:for="option in field.options" 
    315315                              selected="${value == option or None}" 
     
    323323                      </optgroup> 
    324324                    </select> 
    325325                    <textarea py:when="'textarea'" id="field-${field.name}" name="field_${field.name}" 
    326                               cols="${field.width}" rows="${field.height}" 
     326                              cols="${field.width}" rows="${field.height}" title="${field.hint}" 
    327327                              py:content="value"></textarea> 
    328328                    <span py:when="'checkbox'"> 
    329329                      <input type="checkbox" id="field-${field.name}" name="field_${field.name}" 
    330                              checked="${value == '1' and 'checked' or None}" value="1" /> 
     330                             checked="${value == '1' and 'checked' or None}" value="1" title="${field.hint}" /> 
    331331                      <input type="hidden" name="field_checkbox_${field.name}" value="1" /> 
    332332                    </span> 
    333                     <label py:when="'radio'" 
    334                            py:for="idx, option in enumerate(field.options)"> 
    335                       <input type="radio" name="field_${field.name}" value="${option}" 
    336                              checked="${value == option or None}" /> 
    337                       ${option} 
    338                     </label> 
     333                    <span py:when="'radio'" title="${field.hint}"> 
     334                      <label py:for="option in field.options"> 
     335                        <input type="radio" name="field_${field.name}" value="${option}" 
     336                               checked="${value == option or None}" /> 
     337                        ${option} 
     338                      </label> 
     339                    </span> 
    339340                    <py:otherwise><!--! Text input fields --> 
    340341                      <py:choose> 
    341342                        <span py:when="field.cc_entry"><!--! Special case for Cc: field --> 
     
    352353                        </span> 
    353354                        <!--! All the other text input fields --> 
    354355                        <input py:otherwise="" type="text" id="field-${field.name}" 
    355                           name="field_${field.name}" value="${value}" /> 
     356                          name="field_${field.name}" value="${value}" title="${field.hint}" /> 
    356357                      </py:choose> 
    357358                    </py:otherwise> 
    358359                  </py:choose> 
  • trac/ticket/tests/api.py

    diff --git a/trac/ticket/tests/api.py b/trac/ticket/tests/api.py
    a b  
    2424        self.env.config.set('ticket-custom', 'test', 'text') 
    2525        self.env.config.set('ticket-custom', 'test.label', 'Test') 
    2626        self.env.config.set('ticket-custom', 'test.value', 'Foo bar') 
     27        self.env.config.set('ticket-custom', 'test.hint', 'An explanation') 
    2728        fields = TicketSystem(self.env).get_custom_fields() 
    2829        self.assertEqual({'name': 'test', 'type': 'text', 'label': 'Test', 
    29                           'value': 'Foo bar', 'order': 0}, 
     30                          'value': 'Foo bar', 'order': 0, 'hint': 'An explanation'}, 
    3031                         fields[0]) 
    3132 
    3233    def test_custom_field_select(self): 
     
    3435        self.env.config.set('ticket-custom', 'test.label', 'Test') 
    3536        self.env.config.set('ticket-custom', 'test.value', '1') 
    3637        self.env.config.set('ticket-custom', 'test.options', 'option1|option2') 
     38        self.env.config.set('ticket-custom', 'test.hint', 'An explanation') 
    3739        fields = TicketSystem(self.env).get_custom_fields() 
    3840        self.assertEqual({'name': 'test', 'type': 'select', 'label': 'Test', 
    3941                          'value': '1', 'options': ['option1', 'option2'], 
    40                           'order': 0}, 
     42                          'order': 0, 'hint': 'An explanation'}, 
    4143                         fields[0]) 
    4244 
    4345    def test_custom_field_optional_select(self): 
     
    4850        fields = TicketSystem(self.env).get_custom_fields() 
    4951        self.assertEqual({'name': 'test', 'type': 'select', 'label': 'Test', 
    5052                          'value': '1', 'options': ['option1', 'option2'], 
    51                           'order': 0, 'optional': True}, 
     53                          'order': 0, 'optional': True, 'hint': None}, 
    5254                         fields[0]) 
    5355 
    5456    def test_custom_field_textarea(self): 
     
    5759        self.env.config.set('ticket-custom', 'test.value', 'Foo bar') 
    5860        self.env.config.set('ticket-custom', 'test.cols', '60') 
    5961        self.env.config.set('ticket-custom', 'test.rows', '4') 
     62        self.env.config.set('ticket-custom', 'test.hint', 'An explanation') 
    6063        fields = TicketSystem(self.env).get_custom_fields() 
    6164        self.assertEqual({'name': 'test', 'type': 'textarea', 'label': 'Test', 
    6265                          'value': 'Foo bar', 'width': 60, 'height': 4, 
    63                           'order': 0}, 
     66                          'order': 0, 'hint': 'An explanation'}, 
    6467                         fields[0]) 
    6568 
    6669    def test_custom_field_order(self):