Index: trunk/phase3/includes/HTMLForm.php |
— | — | @@ -69,6 +69,7 @@ |
70 | 70 | 'float' => 'HTMLFloatField', |
71 | 71 | 'info' => 'HTMLInfoField', |
72 | 72 | 'selectorother' => 'HTMLSelectOrOtherField', |
| 73 | + 'selectandother' => 'HTMLSelectAndOtherField', |
73 | 74 | 'submit' => 'HTMLSubmitField', |
74 | 75 | 'hidden' => 'HTMLHiddenField', |
75 | 76 | 'edittools' => 'HTMLEditTools', |
— | — | @@ -1457,6 +1458,152 @@ |
1458 | 1459 | } |
1459 | 1460 | |
1460 | 1461 | /** |
| 1462 | + * Double field with a dropdown list constructed from a system message in the format |
| 1463 | + * * Optgroup header |
| 1464 | + * ** <option value>|<option name> |
| 1465 | + * ** <option value == option name> |
| 1466 | + * * New Optgroup header |
| 1467 | + * Plus a text field underneath for an additional reason. The 'value' of the field is |
| 1468 | + * ""<select>: <extra reason>"", or "<extra reason>" if nothing has been selected in the |
| 1469 | + * select dropdown. |
| 1470 | + * FIXME: If made 'required', only the text field should be compulsory. |
| 1471 | + */ |
| 1472 | +class HTMLSelectAndOtherField extends HTMLSelectField { |
| 1473 | + |
| 1474 | + function __construct( $params ) { |
| 1475 | + if ( array_key_exists( 'other', $params ) ) { |
| 1476 | + } elseif( array_key_exists( 'other-message', $params ) ){ |
| 1477 | + $params['other'] = wfMsg( $params['other-message'] ); |
| 1478 | + } else { |
| 1479 | + $params['other'] = wfMsg( 'htmlform-selectorother-other' ); |
| 1480 | + } |
| 1481 | + |
| 1482 | + if ( array_key_exists( 'options', $params ) ) { |
| 1483 | + # Options array already specified |
| 1484 | + } elseif( array_key_exists( 'options-message', $params ) ){ |
| 1485 | + # Generate options array from a system message |
| 1486 | + $params['options'] = self::parseMessage( wfMsg( $params['options-message'], $params['other'] ) ); |
| 1487 | + } else { |
| 1488 | + # Sulk |
| 1489 | + throw new MWException( 'HTMLSelectAndOtherField called without any options' ); |
| 1490 | + } |
| 1491 | + $this->mFlatOptions = self::flattenOptions( $params['options'] ); |
| 1492 | + |
| 1493 | + parent::__construct( $params ); |
| 1494 | + } |
| 1495 | + |
| 1496 | + /** |
| 1497 | + * Build a drop-down box from a textual list. |
| 1498 | + * @param $string String message text |
| 1499 | + * @param $otherName String name of "other reason" option |
| 1500 | + * @return Array |
| 1501 | + * TODO: this is copied from Xml::listDropDown(), deprecate/avoid duplication? |
| 1502 | + */ |
| 1503 | + public static function parseMessage( $string, $otherName=null ) { |
| 1504 | + if( $otherName === null ){ |
| 1505 | + $otherName = wfMsg( 'htmlform-selectorother-other' ); |
| 1506 | + } |
| 1507 | + |
| 1508 | + $optgroup = false; |
| 1509 | + $options = array( $otherName => 'other' ); |
| 1510 | + |
| 1511 | + foreach ( explode( "\n", $string ) as $option ) { |
| 1512 | + $value = trim( $option ); |
| 1513 | + if ( $value == '' ) { |
| 1514 | + continue; |
| 1515 | + } elseif ( substr( $value, 0, 1) == '*' && substr( $value, 1, 1) != '*' ) { |
| 1516 | + # A new group is starting... |
| 1517 | + $value = trim( substr( $value, 1 ) ); |
| 1518 | + $optgroup = $value; |
| 1519 | + } elseif ( substr( $value, 0, 2) == '**' ) { |
| 1520 | + # groupmember |
| 1521 | + $opt = trim( substr( $value, 2 ) ); |
| 1522 | + $parts = array_map( 'trim', explode( '|', $opt, 2 ) ); |
| 1523 | + if( count( $parts ) === 1 ){ |
| 1524 | + $parts[1] = $parts[0]; |
| 1525 | + } |
| 1526 | + if( $optgroup === false ){ |
| 1527 | + $options[$parts[1]] = $parts[0]; |
| 1528 | + } else { |
| 1529 | + $options[$optgroup][$parts[1]] = $parts[0]; |
| 1530 | + } |
| 1531 | + } else { |
| 1532 | + # groupless reason list |
| 1533 | + $optgroup = false; |
| 1534 | + $parts = array_map( 'trim', explode( '|', $opt, 2 ) ); |
| 1535 | + if( count( $parts ) === 1 ){ |
| 1536 | + $parts[1] = $parts[0]; |
| 1537 | + } |
| 1538 | + $options[$parts[1]] = $parts[0]; |
| 1539 | + } |
| 1540 | + } |
| 1541 | + |
| 1542 | + return $options; |
| 1543 | + } |
| 1544 | + |
| 1545 | + function getInputHTML( $value ) { |
| 1546 | + |
| 1547 | + $select = parent::getInputHTML( $value ); |
| 1548 | + |
| 1549 | + $textAttribs = array( |
| 1550 | + 'id' => $this->mID . '-other', |
| 1551 | + 'size' => $this->getSize(), |
| 1552 | + ); |
| 1553 | + |
| 1554 | + foreach ( array( 'required', 'autofocus', 'multiple', 'disabled' ) as $param ) { |
| 1555 | + if ( isset( $this->mParams[$param] ) ) { |
| 1556 | + $textAttribs[$param] = ''; |
| 1557 | + } |
| 1558 | + } |
| 1559 | + |
| 1560 | + $textbox = Html::input( |
| 1561 | + $this->mName . '-other', |
| 1562 | + '', |
| 1563 | + 'text', |
| 1564 | + $textAttribs |
| 1565 | + ); |
| 1566 | + |
| 1567 | + return "$select<br />\n$textbox"; |
| 1568 | + } |
| 1569 | + |
| 1570 | + function loadDataFromRequest( $request ) { |
| 1571 | + if ( $request->getCheck( $this->mName ) ) { |
| 1572 | + |
| 1573 | + $list = $request->getText( $this->mName ); |
| 1574 | + $text = $request->getText( $this->mName . '-other' ); |
| 1575 | + |
| 1576 | + if ( $list == 'other' ) { |
| 1577 | + return $text; |
| 1578 | + } else { |
| 1579 | + # Need to get the value from the key |
| 1580 | + if( in_array( $list, $this->mFlatOptions ) ){ |
| 1581 | + $list = $this->mFlatOptions[$list]; |
| 1582 | + } else { |
| 1583 | + # User has spoofed the select form to give an option which wasn't |
| 1584 | + # in the original offer. Sulk... |
| 1585 | + return $text; |
| 1586 | + } |
| 1587 | + } |
| 1588 | + |
| 1589 | + if( $text == '' ) { |
| 1590 | + return $list; |
| 1591 | + } else { |
| 1592 | + return $list . wfMsgForContent( 'colon-separator' ) . $text; |
| 1593 | + } |
| 1594 | + |
| 1595 | + } else { |
| 1596 | + return $this->getDefault(); |
| 1597 | + } |
| 1598 | + } |
| 1599 | + |
| 1600 | + function getSize() { |
| 1601 | + return isset( $this->mParams['size'] ) |
| 1602 | + ? $this->mParams['size'] |
| 1603 | + : 45; |
| 1604 | + } |
| 1605 | +} |
| 1606 | + |
| 1607 | +/** |
1461 | 1608 | * Radio checkbox fields. |
1462 | 1609 | */ |
1463 | 1610 | class HTMLRadioField extends HTMLFormField { |