it-swarm.com.de

Fügen Sie in Joomla 3.9 ein Kalenderfeld hinzu, ohne das Formular xml zu verwenden

Ich versuche, in meiner benutzerdefinierten Komponente ein Kalenderfeld in Joomla 3.9 zu erstellen. Da ich dies in ein AJAX - Skript einrahme, kann ich das XML-Formular nicht verwenden.

Unten ist der Code, den ich benutze. Das Feld wird angezeigt, aber wenn ich auf klicke, wird das Popup nicht angezeigt. In der Konsole wurde kein Fehler erfasst.

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

Es folgen die Einfügungen, die bereits fertig sind:

<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-Inhalt wie folgt gerendert:

<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>

Beim tiefen Tauchen des HTML-Codes fand ich den Block, der im gerenderten HTML fehlt.

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

Irgendeine Idee, warum dieser Codeblock fehlt und warum das Popup nicht kommt?


Der vollständige Codefluss ist wie folgt

Ansichten

Ich habe die Ladevorlage zum Laden von profile_fields

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

AJAX

Methode beim Laden der Seite aufgerufen

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){
        }
    });
}

Regler

Das ruft das Modell auf, um den HTML-Inhalt zu laden

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

Modell zum Einrahmen des Kalenders

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;
}
2
Malaiselvan

Nachdem Sie dieses Problem einige Male getestet haben, können Sie feststellen, dass über den Ajax-Aufruf die HTML-Felder des Kalenders erstellt werden, die JoomlaCalendar-Javascript-Methoden jedoch nicht ausgelöst werden, die zum Erstellen dieses Felds mit voller Funktion erforderlich sind.

So hat es also funktioniert für mich durch Erstellen eines neuen JoomlaCalendar-Objekts aus den geladenen HTML-Feldern:

  1. sie müssen ein einfaches, leeres HTML div in Ihrem HTML-Formular erstellen und wir sollten das Kalenderfeld in diesem div hinzufügen:

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

(Sie können dieses <div> Auch mit jQuery erstellen, wenn Sie möchten, oder Sie können die HTML-Kalenderfelder in ein <div> In Ihrem Modell einbinden, wie Sie es bereits tun, aber es funktioniert auf jeden Fall, wenn Das Div ist vor dem Ajax-Aufruf im DOM vorhanden.

  1. Sie müssen Ihr Ajax-Aufrufskript mit wenigen Zeilen erweitern:

    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){
        }
        });
    }
    

Sie sehen, dass ich habe gerade 3 Zeilen hinzugefügt zu Ihrem jQuery/Ajax-Aufrufskript. Und ein paar Anmerkungen dazu:

1. Ich glaube nicht, dass der Anforderungstyp POST sein muss, da dort keine wichtigen Daten veröffentlicht werden müssen, sodass der Anforderungstyp GET sein könnte. Möglicherweise müssen wir keine #profile-form - Daten senden, um das Kalenderfeld von Ihrem Modell zu erhalten (ich sehe Ihre vollständigen Anforderungen dazu nicht, daher ist dies nur ein Vorschlag).

2. In der ersten Zeile der Erfolgsfunktion fügen wir die von Ajax zurückgegebenen HTML-Daten aus unserem Modell zu unserem zuvor erstellten <div> Hinzu, sodass unser HTML-Kalenderfeld erstellt wird. (Und der Grund dafür, dass es nicht funktioniert, ist, dass es zu diesem Zeitpunkt kein Javascript mehr auslöst, das erforderlich war, um ein voll funktionsfähiges Kalenderfeld zu erhalten.).

. In den nächsten beiden Zeilen der Erfolgsfunktion definieren wir ein neues Javascript-Objekt mit der Auswahl unseres erstellten (Wrappers) <div>, Der nun ein gültiges Element sein kann zum Erstellen eines neuen JoomlaCalendar -Objekts damit (es funktioniert, wenn die erforderlichen Joomla-Kalender-Javaskripte geladen sind, da Sie sie bereits auf Ihrer Seite geladen haben).

Und Sie sollten ein voll funktionsfähiges JoomlaCalendar-Feld haben. (es ist getestet).

EDIT

Nur um sicherzustellen, dass das oben Genannte nicht missverstanden wird. Die Hauptfrage lautet: wie erstelle ich ein Joomla-Kalenderformularfeld, das über einen Ajax-Aufruf geladen wird? Ich möchte hier eine einfache, klare Version von Codes platzieren, die auf der Frage basiert, um das Ganze zu testen.

Die Funktion in der Steuerung (Profil) der Ansicht (Profil) :

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

die vom Controller aufgerufene Funktion im Modell (Profil) :

public function getFields() {
        $newDate = date("Y-m-d H:i:s");
        $myDateField = JHtml::calendar($newDate, "field-calendar-150", "jform-field-150", '%Y-%m-%d');
        return $myDateField;
    }

Skript mit dem Ajax-Aufruf im Layout :

<script>

function getFields(){
    jQuery('#ajax_loader_image_2').show();    

    return jQuery.ajax({
        type: 'GET',
        url: '/index.php?option=com_mycomponent&view=default_page_html&task=profile.getFields',
        success: function(data){
           jQuery('#datefield1').html(data);
           let myDateField1 = document.getElementById('datefield1');
           let newElement = myDateField1.firstChild;
           new JoomlaCalendar(element = newElement);
        },
        error: function(result){
        }
    });
}

</script>

Ich habe der Erfolgsfunktion des Ajax-Aufrufs eine zusätzliche Zeile hinzugefügt, um sicherzustellen, dass das Kalenderfeld ohne undefinierten JavaScript-Fehler parentNode beim Unschärfeereignis funktioniert. Das Obige ist also das einfache Grundgerüst zum Erstellen eines voll funktionsfähigen Joomla-Kalenderfelds mithilfe von Ajax.

UPDATE

In Ihrem speziellen Fall in Ihrer Testkomponente in script_fields.php Sollte Ihr Skript folgendermaßen aussehen:

<script type="text/javascript">

jQuery(document).ready(function(){
    jQuery('#task').val('profile.getFields');

    return jQuery.ajax({
        type: 'GET',
        url: 'index.php?option=com_ajaxdate&task=profile.getFields',

        success: function(result) {
            jQuery('#fields_container').html(result);
            if (jQuery("[class*='field-calendar']")) {
                let newElement = jQuery("[class*='field-calendar']");
                jQuery.each(newElement, function(index, value) {
                    if (! value.querySelector('.js-calendar')) {
                        try {
                            new JoomlaCalendar(element = value);
                        } catch {
                            console.log("JoomlaCalendar instance is already exists for this element");
                        }
                    }
                });
            }
        },
        error: function(result){
            jQuery('#fields_container').html("no custom fields found");
        }
    });

});

</script>

Im obigen Skript :

  1. Wir wählen alle DOM-Elemente aus, die den Klassennamen 'field-calendar' Haben. Dies sind offensichtlich die Kalenderfelder in Ihrem Formular.
  2. Dann prüfen wir, ob auf das Element bereits JoomlaCalendar object instance Angewendet wurde oder nicht, indem wir prüfen, ob es bereits ein .js-calendar Div-Kind hat oder nicht.
  3. Wenn nicht, erstellen wir ein new JoomlaCalendar Objekt auf diesem Div.
1
Zollie