2

I am trying to create a Calendar field in Joomla 3.9 inside my custom component. Since I am framing this inside an AJAX script, I can't use the XML form.

Below is the code I am using. The field gets displayed, but when I click, the popup is not coming. There is no error captured in the console.

$html .= "<div class='controls'>";
$html .= JHtml::_('calendar', '', "jform_field_4", "jform_field_4", '%Y-%m-%d', '');
$html .= "</div>";

Following are the inserts which are already done:

<link href="/jschool/media/system/css/fields/calendar.css" rel="stylesheet">
<script src="/jschool/media/system/js/fields/calendar-locales/en.js"></script>
<script src="/jschool/media/system/js/fields/calendar-locales/date/gregorian/date-helper.min.js"></script>
<script src="/jschool/media/system/js/fields/calendar.min.js"></script>

HTML content rendered as below:

<div class="field-calendar">
    <div class="input-append">
        <input type="text" id="jform_field_4" name="jform_field_4" value="" data-alt-value="" autocomplete="off">
        <button type="button" class="btn btn-secondary" id="jform_field_4_btn" data-inputfield="jform_field_4" data-dayformat="%Y-%m-%d" data-button="jform_field_4_btn" data-firstday="0" data-weekend="0,6" data-today-btn="1" data-week-numbers="1" data-show-time="0" data-show-others="1" data-time-24="24" data-only-months-nav="0" title="Open the calendar">
        <span class="icon-calendar" aria-hidden="true"></span>
        </button>
    </div>
</div>

On deep diving the HTML code, I found the block missing in the rendered HTML.

<div class="js-calendar" style="direction: ltr; position:.....
.....
.....
</div>

Any idea why this block of code is missing and why the popup is not coming?


Full Flow of the code is as below

Views

I got the load template to load profile_fields

echo $this->loadTemplate('profile_fields');

AJAX

Method called at page load

function getFields(){
    jQuery('#ajax_loader_image_2').show();
    jQuery('#task').val('profile.getFields');
    var dataString = jQuery("#profile-form").serialize();

    return jQuery.ajax({
        type: 'POST',
        url: 'index.php',
        data: dataString,
        success: function(result){
        },
        error: function(result){
        }
    });
}

Controller

That calls the model to load the HTML content

public function getFields(){
    JFactory::getDocument()->setMimeEncoding( 'application/json' );
    $model = $this->getModel();
    $response = $model->getFields();
    echo $response ;
    JFactory::getApplication()->close();
}

Model to frame the Calendar

public function getFields() {

    $field <-- this is an object contains an uniqe id, type etc...
    $html_content = $this->convertFieldHtml ( $field );
    return $html_content;
}


private function convertFieldHtml($field) {
    $field_type = $field->fldtype_html_field;
    $html = '';

    $properties = $this->getFieldProperties ( $field );

    switch ($field_type) {
        case 'date' :
            $html = $this->loadDateField ($properties, $field );
            break;
    }
    return $html;
}

private function loadDateField($properties, $field) {

    $html = '';
    $html .= "<div class='control-group'>";

    // Set the control
    $html .= "<div class='controls'>";

    $attribs = array();
    $attribs['size']=18;
    $attribs['maxlength']=20;

    $html .= JHtml::calendar('', "jform_field_".$field->field_id, "jform_field_".$field->field_id, '%Y-%m-%d',$attribs);
    //$html .= JHtml::_('calendar','', "jform_field_".$field->field_id, "jform_field_".$field->field_id, '%Y-%m-%d',$attribs);

    if ($field->field_tooltip) {
        $html .= "<div>" . $field->field_tooltip . "</div>";
    }
    $html .= "</div>";

    $html .= "</div>";

    return $html;
}
  • On your rendered page use your browsers development tool and change the type="text" to type="date" and see if your calendar pops up. Last week I was trying to remove the pop up calendar and it came down to the field type and how each browser handles it slightly different. – Irata Dec 1 at 11:38
  • Could you please try to add the calendar field in the standard way and see it that way: JHtml::calendar($value, $name, $id, $format= '%Y-%m-%d', $attribs = array()); – Zollie Dec 1 at 12:18
  • @Zollie tried both the ways and behavior is same. No javascript error in the console and no popup comes. – Malaiselvan Dec 1 at 13:49
  • @Irata tried changing the type to date and that doesnt make any difference. – Malaiselvan Dec 1 at 13:50
  • How do you frame this inside an ajax script? It has something to do with that probably, since your code looks OK. – Zollie Dec 1 at 19:01
0

After testing this issue few times, you can realize that via the ajax call the Calendar HTML fields are created but it will not trigger the JoomlaCalendar javascript methods which are needed to create this field fully functional.

So this is how it worked for me by creating a new JoomlaCalendar object from the loaded HTML fields:

  1. you need to create a simple, empty HTML div within your html form and we should add the calendar field inside this div:

    <div class="datefield1" id="datefield1"> </div>

(You can create this <div> with jQuery too if you would like to or you can wrap the html calendar fields in a <div> in your model as you do it already, but for sure it works if the div is there before the ajax call in the DOM).

  1. You have to extend you ajax call script with few lines:

    function getFields(){
        jQuery('#ajax_loader_image_2').show();
        jQuery('#task').val('profile.getFields');
        var dataString = jQuery("#profile-form").serialize();
    
    return jQuery.ajax({
        type: 'POST',
        url: 'index.php',
        data: dataString,
        success: function(data){
           jQuery('#datefield1').html(data);
           let myDateField1 = document.getElementById('datefield1');
           new JoomlaCalendar(element = myDateField1);
        },
        error: function(result){
        }
        });
    }
    

You see that I just added 3 lines to your jQuery/ajax call script. And few notes about that:

1. I do not think that the request type has to be POST since there is no important data there to be posted, so the request type could be GET. We maybe do not need to send #profile-form data to get the calendar field from you model (I do not see your full requirements regarding this, so this is just a suggestion).

2. In the first line of the success function we add the ajax returned html data from our model to our previously created <div> thus our html calendar field is built. (And the reason that it is not functional is because it is not triggering any more javascript at this point which were needed to get a fully functional calendar field).

3. In the next two lines of success function We define a new javascript object with selecting our created (wrapper) <div> which can now be a valid element for creating a new JoomlaCalendar object with that (it works if the required joomla calendar javascripts are loaded as you already have them loaded on your page).

And you should have a fully functional JoomlaCalendar field. (it’s tested).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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