2

In a form I have a date/time-field. It works correctly, but the format of the date isn't right -- I require Dutch date notation (d-m-Y).

Instead of day-month-year it displays and saves it as year-month-day.

My calendar() method call looks like this:

JHTML::calendar($formattedDate, 'jform[created]', 'jform_created', "%Y-%m-%d %H:%M", array('showTime' => 'showTime', 'class' => 'inputbox'))

Where $formattedDate is a string like 26-04-2019 08:45.

When I change the fourth parameter from "%Y-%m-%d %H:%M" to "%d-%m-%Y %H:%M" the form field is empty after saving.

What is the correct way to display and save the date as d-m-y?

The Joomla version is 3.9.4 and PHP version is 7.1.

The data type of created column in the table #__content is datetime, default value is 0000-00-00 00:00:00. The other form values are being saved, only this custom one is not. This date column is not the only field I added to the override. I've tried $this->form->renderField('created') at first, but it only displays the date, not the time. There are no warning, notices errors, or other hints generated.

This is my override in the frontend management of /components/com_content/form/edit.php:

<?php    
/**
 * @package     Joomla.Site
 * @subpackage  com_content
 *
 * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

JHtml::_('behavior.tabstate');
JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidator');
JHtml::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0));
JHtml::_('formbehavior.chosen', 'select');
$this->tab_name = 'com-content-form';
$this->ignore_fieldsets = array('image-intro', 'image-full', 'jmetadata', 'item_associations');

// Create shortcut to parameters.
$params = $this->state->get('params');

// This checks if the editor config options have ever been saved. If they haven't they will fall back to the original settings.
$editoroptions = isset($params->show_publishing_options);

if (!$editoroptions)
{
    $params->show_urls_images_frontend = '0';
}

JFactory::getDocument()->addScriptDeclaration("
    Joomla.submitbutton = function(task)
    {
        if (task == 'article.cancel' || document.formvalidator.isValid(document.getElementById('adminForm')))
        {
            " . $this->form->getField('articletext')->save() . "
            Joomla.submitform(task);
        }
    }
");
?>
<div class="edit item-page<?php echo $this->pageclass_sfx; ?>">
    <?php if ($params->get('show_page_heading')) : ?>
    <div class="page-header">
        <h1>
            <?php echo $this->escape($params->get('page_heading')); ?>
        </h1>
    </div>
    <?php endif; ?>

    <form action="<?php echo JRoute::_('index.php?option=com_content&a_id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="adminForm" class="form-validate form-vertical">
        <div class="btn-toolbar">
            <div class="btn-group">
                <button type="button" class="btn btn-primary" onclick="Joomla.submitbutton('article.save')">
                    <span class="icon-ok"></span><?php echo JText::_('JSAVE') ?>
                </button>
            </div>
            <div class="btn-group">
                <button type="button" class="btn" onclick="Joomla.submitbutton('article.cancel')">
                    <span class="icon-cancel"></span><?php echo JText::_('JCANCEL') ?>
                </button>
            </div>
            <?php if ($params->get('save_history', 0) && $this->item->id) : ?>
            <div class="btn-group">
                <?php echo $this->form->getInput('contenthistory'); ?>
            </div>
            <?php endif; ?>
        </div>
        <fieldset>
            <?php echo JHtml::_('bootstrap.startTabSet', $this->tab_name, array('active' => 'editor')); ?>

            <?php echo JHtml::_('bootstrap.addTab', $this->tab_name, 'editor', JText::_('COM_CONTENT_ARTICLE_CONTENT')); ?>
                <?php echo $this->form->renderField('title'); ?>

                <?php if (is_null($this->item->id)) : ?>
                    <?php echo $this->form->renderField('alias'); ?>
                <?php endif; ?>

                <?php echo $this->form->getInput('articletext'); ?>

                <?php if ($this->captchaEnabled) : ?>
                    <?php echo $this->form->renderField('captcha'); ?>
                <?php endif; ?>
            <?php echo JHtml::_('bootstrap.endTab'); ?>

            <?php if ($params->get('show_urls_images_frontend')) : ?>
            <?php echo JHtml::_('bootstrap.addTab', $this->tab_name, 'images', JText::_('COM_CONTENT_IMAGES_AND_URLS')); ?>
                <?php echo $this->form->renderField('image_intro', 'images'); ?>
                <?php echo $this->form->renderField('image_intro_alt', 'images'); ?>
                <?php echo $this->form->renderField('image_intro_caption', 'images'); ?>
                <?php echo $this->form->renderField('float_intro', 'images'); ?>
                <?php echo $this->form->renderField('image_fulltext', 'images'); ?>
                <?php echo $this->form->renderField('image_fulltext_alt', 'images'); ?>
                <?php echo $this->form->renderField('image_fulltext_caption', 'images'); ?>
                <?php echo $this->form->renderField('float_fulltext', 'images'); ?>
                <?php echo $this->form->renderField('urla', 'urls'); ?>
                <?php echo $this->form->renderField('urlatext', 'urls'); ?>
                <div class="control-group">
                    <div class="controls">
                        <?php echo $this->form->getInput('targeta', 'urls'); ?>
                    </div>
                </div>
                <?php echo $this->form->renderField('urlb', 'urls'); ?>
                <?php echo $this->form->renderField('urlbtext', 'urls'); ?>
                <div class="control-group">
                    <div class="controls">
                        <?php echo $this->form->getInput('targetb', 'urls'); ?>
                    </div>
                </div>
                <?php echo $this->form->renderField('urlc', 'urls'); ?>
                <?php echo $this->form->renderField('urlctext', 'urls'); ?>
                <div class="control-group">
                    <div class="controls">
                        <?php echo $this->form->getInput('targetc', 'urls'); ?>
                    </div>
                </div>
            <?php echo JHtml::_('bootstrap.endTab'); ?>
            <?php endif; ?>

            <?php echo JLayoutHelper::render('joomla.edit.params', $this); ?>

            <?php echo JHtml::_('bootstrap.addTab', $this->tab_name, 'publishing', JText::_('COM_CONTENT_PUBLISHING')); ?>
            <?php echo $this->form->renderField('catid'); ?>
            <?php echo $this->form->renderField('tags'); ?>
            <?php echo $this->form->renderField('note'); ?>
            <?php if ($params->get('save_history', 0)) : ?>
                <?php echo $this->form->renderField('version_note'); ?>
            <?php endif; ?>
            <span style="display: none;">
                <?php if ($params->get('show_publishing_options', 1) == 1) : ?>
                    <?php echo $this->form->renderField('created_by_alias'); ?>
                <?php endif; ?>
            </span>
            <?php if ($this->item->params->get('access-change')) : ?>
                <span style="display: none;">
                    <?php echo $this->form->renderField('featured'); ?>
                </span>

                <?php echo $this->form->renderField('state'); ?>

                    <?php echo $this->form->renderField('publish_up'); ?>
                    <?php echo $this->form->renderField('publish_down'); ?>

                <?php if ($params->get('show_publishing_options', 1) == 1) : ?>
                    <?php echo $this->form->renderField('publish_down'); ?>
                <?php endif; ?>
            <?php endif; ?>


            <?php // Custom added by Yolknet ?>

            <?php
            // Your date from database
            $date = JFactory::getDate($this->item->created);
            $formattedDate = $date->format('d-m-Y H:i');
            ?>

            <div class="control-group">
                <div class="control-label"><label id="jform_created-lbl" for="jform_created">Date event</label></div>
                <div class="controls">
                    <div class="input-append">
                        <?php echo JHTML::calendar($formattedDate, 'jform[created]', 'jform_created', "%Y-%m-%d %H:%M:%S", array('translateformat' => true, 'showTime' => 'showTime', 'class' => 'inputbox')); ?>
                    </div>
                </div>
            </div>

            <?php // End custom added by Yolknet ?>


                <span style="display: none;">
                    <?php echo $this->form->renderField('access'); ?>
                </span>
                <?php if (is_null($this->item->id)) : ?>
                    <div class="control-group">
                        <div class="control-label">
                        </div>
                        <div class="controls">
                            <?php echo JText::_('COM_CONTENT_ORDERING'); ?>
                        </div>
                    </div>
                <?php endif; ?>
            <?php echo JHtml::_('bootstrap.endTab'); ?>

            <?php echo JHtml::_('bootstrap.addTab', $this->tab_name, 'language', JText::_('JFIELD_LANGUAGE_LABEL')); ?>
                <?php echo $this->form->renderField('language'); ?>
            <?php echo JHtml::_('bootstrap.endTab'); ?>

            <?php if ($params->get('show_publishing_options', 1) == 1) : ?> 
                <?php echo JHtml::_('bootstrap.addTab', $this->tab_name, 'metadata', JText::_('COM_CONTENT_METADATA')); ?>
                    <?php echo $this->form->renderField('metadesc'); ?>
                    <?php echo $this->form->renderField('metakey'); ?>
                <?php echo JHtml::_('bootstrap.endTab'); ?>
            <?php endif; ?>

            <?php echo JHtml::_('bootstrap.endTabSet'); ?>

            <input type="hidden" name="task" value="" />
            <input type="hidden" name="return" value="<?php echo $this->return_page; ?>" />
            <?php echo JHtml::_('form.token'); ?>
        </fieldset>
    </form>
</div>

Thanks to the major help of @zollie the past weeks I've solved the probem. I disabled a 3rd party plugin and created an override. Now it's working correctly.

9
  • Thank you for your tips @mickmackusa. The file is an override in the frontend manegment of /com_content/form/edit.php The Joomla version is 3.9.4, Php 7.1. I tried %R, but when I do that the field display %R without converting. Also using strtotime doesn't help.
    – YolkNet
    Apr 4, 2019 at 14:38
  • I uploaded the override to 185.75.159.82/~stack/edit.txt If you rename .txt to .php you can test it.
    – YolkNet
    Apr 5, 2019 at 10:53
  • Thank you for testing @Zollie. I now have JHTML::calendar($formattedDate, 'jform[created]', 'jform_created', "%d-%m-%Y %H:%M:%S", array('filter' => 'user_utc', 'translateformat' => true, 'showTime' => 'showTime', 'class' => 'inputbox')) It displays the date and time when loading the page. And when you change it with the popup calendar the format is still correct (Dutch). But after saving the field is blanc. Maybe I'm missing another attribute in the array?
    – YolkNet
    Apr 6, 2019 at 9:55
  • @YolkNet I have done a substantial edit to your question to transfer all relevant details from your comments into the question body -- it is important that the "full story" is all in the question body. You may need to continue editing as Zollie continues to provide support. Now that my comments were answered, I have removed my comments. This also allows you to delete the comments which have been transferred to the question. Ultimately, fewer comments make a page more attractive for future researchers. Apr 6, 2019 at 14:21
  • As you make more attempts (and fail), please add the attempts and their outcomes to your question body for absolute clarity. At this point, I am unsure if the earliest point of failure is in the saving step, before the saving step, or after the saving step. Apr 6, 2019 at 14:21

1 Answer 1

1

The basic issue is that sql datetime field format is this: 'YYYY-MM-DD HH:MM:SS'. You can only save a date in this format when you save a date/time value (in MySQL at least). If you have a calendar html input field (a DatePicker) and because of a language (country) you have to change the format of the date (for example to this: 'DD-MM-YYYY HH:MM:SS'), then you will be unable to save it back to the database in this format and Joomla will just replace it with a default or null value in the database. You can of course change the date input value' format in your model before saving, however, in Joomla this problem is already solved if you create an html calendar field with using XML, as the basic way how it should be created in Joomla.

1. You have to create the Calendar form field in XML and since you make an override thus you will create this mycalendar.xml file in your template html folder for example at your_joomla_root/templates/yourtemplate/html/com_content/article/forms/ :

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fieldset name="mynewcalendar">
      <field  name="created"
              type="calendar"
              label="Date event"
              description="This field is for the events"                  
              translateformat="true"
              showtime="true"
              size="40"
              class="inputbox"
              default=""
              filter="user_utc"
      />
    </fieldset>
</form>

2. Then, you will load this form field into your layout override' Form using the already loaded form object:

<?php // Custom added by Yolknet

// Your date from database
$date = (string) JFactory::getDate($this->item->created);

// your xml calendar field file
$file = JPATH_THEMES . '/your_template/html/com_content/article/forms/mycalendar.xml';

$this->form->loadFile($file, $reset = true);

// setting default date value
$this->form->setFieldAttribute($name='created', $attribute='default', $value=$date);

echo $this->form->renderField('created');

// End custom added by Yolknet ?>

Or if you want to load the Calendar form field with a new Form object, you can also do that:

<? php

// on the top of your layout file you have the Form class:
use \Joomla\CMS\Form\Form;

// the code where you would like to load the input field    
$date = (string) JFactory::getDate($this->item->created); // any date from your table - you do not need to format that
$file = JPATH_THEMES . '/your_template/html/com_content/article/forms/mycalendar.xml';

// create a new form object
$mycalendar = new Form('MyNewForm');

$mycalendar->loadFile($file, $reset = true);

$mycalendar->setFieldAttribute($name='created', $attribute='default', $value=$date);

echo $mycalendar->renderField('created');

?>

You will get a fully functional calendar input field that automatically displays the datetime according to the user language setting and you can also save the picked date without any problem. (The above is tested and works). I hope it will now work for you too. Please give me a feedback on this.

Still, the basic problem of this question was about how to add translateformat="true" option value to the form field which makes it possible to display the datetime value according to any user language setting, at the same time keeping the date format at saving the date back. I just do not see the possibility of doing that with JHtml::calendar() method.

While we can create form input fields in many other ways of course, here is a very good explanation about why we should create form fields using XML in Joomla: https://magazine.joomla.org/issues/issue-jun-2017/item/3248-new-datepicker-for-joomla-3-7

UPDATE - On Article 'created' date field editing from front-end

The previous part of my answer works on any Form except in the front-end editing of an article's created date.

After I got the template file from @Yolknet (that he is working on) it became obvious what the real problem is when he tries to use the above instructions on creating and using Calendar form field at article editing in front-end.

Here the original question should be: how to edit created date of an article from the front-end of Joomla? So the question here is not how to change date format in JHtml::calendar(), since the problem here is that in Joomla core they restricted the editing of the created date of an article only to the administrator area of Joomla.

This problem cannot be solved by just creating a calendar form field in a layout override, since the date input is going to be filtered out by the core Form->validate() method in Joomla due to the fact that created date field's filter attribute is set to unset value, which means that the value after form field filtering will be a null value. So the original question was really misleading and the real problem was already shortly but well answered by @Sharky few moths ago here: How can I enable the created date for an article to be edited in the front end?

The solution

The only thing you have to add to the front-end content edit.php layout override is:

<?php // Custom added by Yolknet

$this->form->setFieldAttribute($name='created', $attribute='showtime', $value='true');
$this->form->setFieldAttribute($name='created', $attribute='label', $value='Created date');
$this->form->setFieldAttribute($name='created', $attribute='class', $value='inputbox');

echo $this->form->renderField('created');

// End custom added by Yolknet ?>

Now, this override will not solve the problem yet, it will just display the created datetime field nicely in the article editing layout in the front-end of Joomla but you will not be able to save the date yet.

In order to be able to save the input data into the content table, you have to create and use a plugin (that @Sharky very well has given in his answer already) or I just also created my own version on another plugin event (onContentNormaliseRequestData()), which is an event before a submitted form and data is going through filtering and validation in \Joomla\CMS\Form\Form class. The plugin should look like this:

<?php
/**
 * @package    [PACKAGE_NAME]
 *
 * @author     [AUTHOR] <[AUTHOR_EMAIL]>
 * @copyright  [COPYRIGHT]
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 * @link       [AUTHOR_URL]
 */
defined('_JEXEC') or die;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Factory;

/**
 * ContentArticleformfieldcreated plugin.
 *
 * @package  [TEMPLATE_NAME]
 * @since    1.0
 */
class PlgContentArticleformfieldcreated extends CMSPlugin
{
    /**
     * Application object
     *
     * @var    CMSApplication
     * @since  1.0
     */
    protected $app;
    /**
     * Database object
     *
     * @var    Factory::getDbo()
     * @since  1.0
     */
    protected $db;
    /**
     * Affects constructor behavior. If true, language files will be loaded automatically.
     *
     * @var    boolean
     * @since  1.0
     */
    protected $autoloadLanguage = true;

    /**
     * This is an event that is called in FormController.php in save() method
     * before the submitted Form $data is filtered and validated in the Form class
     * This plugin makes it possible to edit article created date from the front-end of Joomla.
     * Without this plugin the form field named 'created' is unset and the filter nulls it's value.
     *
     * @param string $context The context of the content passed to the plugin (added in 1.6).
     * @param object $article A JTableContent object.
     *
     * @return  void.
     *
     * @since   1.0
     */
    public function onContentNormaliseRequestData($context, $data, Form $form)
    {
        if ($this->app->isClient('site') && $context == 'com_content.article' && $form->getField('created') != false)
        {
            $form->setFieldAttribute('created', 'filter', 'user_utc');
            $form->setFieldAttribute('created', 'showtime', 'true');
        }
    }    
}

Using either of the plugins will make you able to modify and save the created date of an article in the front-end.

And just to finalize this question, I've made a short visual that shows the front-end editing and saving of article's created date (labelled here as Datum Evenement) and also shows that it works with Dutch date format too:

enter image description here

9
  • Thank you for your answer and the detailed information Zollie. I've tried both ways, but unfortunately without any luck. When I save the date with the first code of step 2 the date field is empty. The second code of step 2 return "30-11-2001 00:19:32" after saving the form. It's the right format, but the wrong date and time :-)
    – YolkNet
    Apr 8, 2019 at 11:48
  • In the meantime I checked the calendar field in Hungarian, Romanian, Slovak, Czech and works without a problem, in German 5-10 years added to or deducted from the displayed datetime when I am saving it to the db and i get it back to the calendar.
    – Zollie
    Apr 9, 2019 at 13:20
  • @YolkNet - after checking the field with German language, and I added the filter="user_utc" definition to the field, it handled the wrong datetime value saving and now it works perfectly in German too. I updated the xml field with that in my answer. Please check your calendar with that and let's see if it works for you too with Dutch language setting.
    – Zollie
    Apr 9, 2019 at 15:00
  • @YolkNet - I have now also installed the Dutch language pack, tested that with the field and it works well now. I hope you can confirm that too.
    – Zollie
    Apr 9, 2019 at 15:56
  • What am I doing wrong? I've followed every hint you gave me, but I don't get it working. Would you mind if I emailed you the template files? If your tests work then something is wrong with my browser or computer I guess. Or maybe it clearifies my question for you and why it wouldn't work.
    – YolkNet
    Apr 9, 2019 at 17:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.