Page 1 of 1

JHtml::('calendar... format and value fix

Posted: Mon Dec 12, 2011 4:39 pm
by kelsangpagchen
Hi,
The calendar code is mistaken in the JHTML class.

Problem is within the return code
Now:
return <input type="text" title="'.(0!==(int)$value ? JHtml::_('date', $value):'').'" name="'.$name.'" id="'.$id.'" value="'.htmlspecialchars($value, ENT_COMPAT, 'UTF-8').'" '.$attribs.' />'.
($readonly ? '' : JHtml::_('image', 'system/calendar.png', JText::_('JLIB_HTML_CALENDAR'), array( 'class' => 'calendar', 'id' => $id.'_img'), true));
This leads to a value that doesn't take into account the date format (in both the value and title attribute).
Fixed code :

Code: Select all

$value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
return '<input type="text" title="'.(0!==(int)$value ? JHtml::_('date', $value,$format):'').'" name="'.$name.'" id="'.$id.'" value="'.(0!==(int)$value ? JHtml::_('date', $value,$format):'').'" '.$attribs.' />'.
			($readonly ? '' : JHtml::_('image', 'system/calendar.png', JText::_('JLIB_HTML_CALENDAR'), array( 'class' => 'calendar', 'id' => $id.'_img'), true));
	}
As I am not sure if it was safe to get rid of the htmlspecialchars function, I added the extra value sanitization, but it maybe not necessary.

cheers,

***** EDIT *****
Actually this change breaks the calendar function in the joomla site as the calendar.js file don't take into account yet the new date format (Y-m-d instead of %Y-%m-%d).
Leading to broken calendar javascript if new format is used and wrong existing date display if old format is used.

But this calendar function definitely needs some refactoring to take into account the format from the .xml file.

I'll post more if I find any solutions.

**** end edit *****

Re: JHtml::('calendar... format and value fix

Posted: Mon Dec 12, 2011 7:50 pm
by kelsangpagchen
I finally came up with a way to have the calendar value set to proper format:
in the JHtml class (libaries/joomla/html/html.php), method calendar() :

change the following lines:

Code: Select all

return '<input type="text" title="'.(0!==(int)$value ? JHtml::_('date', $value):'').'" name="'.$name.'" id="'.$id.'" value="'.htmlspecialchars($value, ENT_COMPAT, 'UTF-8').'" '.$attribs.' />'.
//			($readonly ? '' : JHtml::_('image', 'system/calendar.png', JText::_('JLIB_HTML_CALENDAR'), array( 'class' => 'calendar', 'id' => $id.'_img'), true));
//	}
with:

Code: Select all

		// pass new format standard - no% sign and %M -> i and %S -> s
		$format = str_replace("%M", "i", $format);
		$format = str_replace("%S", "s", $format);
		$format = str_replace("%", "", $format);
		return '<input type="text" title="'.(0!==(int)$value ? JHtml::_('date', $value, $format, null):'').'" name="'.$name.'" id="'.$id.'" value="'.(0!==(int)$value ? JHtml::_('date', $value, $format, null):'').'" '.$attribs.' />'.
			($readonly ? '' : JHtml::_('image', 'system/calendar.png', JText::_('JLIB_HTML_CALENDAR'), array( 'class' => 'calendar', 'id' => $id.'_img'), true));
	}
Meanwhile, you can setup a custom JHtml class and create a calendar() method with the changes and use this one instead in your application.
cheers,

Re: JHtml::('calendar... format and value fix

Posted: Wed Mar 13, 2013 11:00 am
by Tredde
This is truly a bug in the HTML class.
I altered the function to accept the format. See included code.

Code: Select all

	public static function calendar($value, $name, $id, $format = '%Y-%m-%d', $attribs = null)
	{
		static $done;

		if ($done === null)
		{
			$done = array();
		}

		$readonly = isset($attribs['readonly']) && $attribs['readonly'] == 'readonly';
		$disabled = isset($attribs['disabled']) && $attribs['disabled'] == 'disabled';
		if (is_array($attribs))
		{
			$attribs = JArrayHelper::toString($attribs);
		}

		if (0 !== (int) $value) {
			$date = JFactory::getDate($value);
			$formatValue = $date->toFormat($format);
		} else {
			$formatValue = '';
		}
		
		if (!$readonly && !$disabled)
		{
			// Load the calendar behavior
			self::_('behavior.calendar');
			self::_('behavior.tooltip');

			// Only display the triggers once for each control.
			if (!in_array($id, $done))
			{
				$document = JFactory::getDocument();
				$document
					->addScriptDeclaration(
					'window.addEvent(\'domready\', function() {Calendar.setup({
				// Id of the input field
				inputField: "' . $id . '",
				// Format of the input field
				ifFormat: "' . $format . '",
				// Trigger for the calendar (button ID)
				button: "' . $id . '_img",
				// Alignment (defaults to "Bl")
				align: "Tl",
				singleClick: true,
				firstDay: ' . JFactory::getLanguage()->getFirstDay() . '
				});});'
				);
				$done[] = $id;
			}
			return '<input type="text" title="' . (0 !== (int) $value ? self::_('date', $value, null, null) : '') . '" name="' . $name . '" id="' . $id
				. '" value="' . htmlspecialchars($formatValue, ENT_COMPAT, 'UTF-8') . '" ' . $attribs . ' />'
				. self::_('image', 'system/calendar.png', JText::_('JLIB_HTML_CALENDAR'), array('class' => 'calendar', 'id' => $id . '_img'), true);
		}
		else
		{
			return '<input type="text" title="' . (0 !== (int) $value ? self::_('date', $value, null, null) : '')
				. '" value="' . htmlspecialchars($formatValue, ENT_COMPAT, 'UTF-8') . '" ' . $attribs
				. ' /><input type="hidden" name="' . $name . '" id="' . $id . '" value="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '" />';
		}
	}