Drupal AJAX wird nur einmal ausgelöst


7

In Drupal 7 habe ich ein Formular, in dem ich Folgendes tun möchte:

  • Zeigen Sie eine Liste mit Optionen in einer einfachen zweispaltigen Tabelle an
  • Durch Auswahl einer Aktion aus einer Dropdown-Liste wird AJAX ausgelöst und die Optionen in der Tabelle ersetzt

Ich habe Code geschrieben und Drupal sendet nur Werte an die AJAX, wenn Sie zum ersten Mal eine Auswahl treffen. Funktioniert dies nicht bei Formularelementtypen? Beachten Sie, dass die Seite auch andere Formulare enthält, die Formular-IDs jedoch ebenso wie die Formularfelder eindeutig sind.

$form['new_date'] = array(
            '#type' => 'select',
            '#title' => 'Delivery Date',
            '#options' => $date,
            '#ajax' => array(
                'callback' => 'delivery_date_weekends',
                'wrapper' => 'dates-ajax',
                'method' => 'replace',
                'effect' => 'fade',
            ),
        );

$form['date_weekend'] = array(
                '#type' => 'item',
                '#prefix' => '<div id="dates-ajax">',
                '#suffix' => '</div>',
                '#markup' => '',
          );

Im AJAX-Rückruf werden dann Daten zurückgegeben, wobei #markup auf das Thema ('Tabelle') der Ergebnisse gesetzt ist. Es funktioniert nur beim ersten Mal, ich sehe die POST-Daten in der Firebug-Konsole. Wählen Sie eine andere Dropdown-Option, meine Tabelle wird nicht aktualisiert.

Habe ich hier etwas falsch gemacht?

Bearbeiten: Scheint, als würde der POST es schaffen, aber die Antwort ist leer, sollte es aber nicht sein.

Edit 2: Ajax Callback:

function delivery_date_weekends($form, $form_state) {

    $query = new EntityFieldQuery();
    $result = $query->entityCondition('entity_type', 'field_collection_item')
        ->propertyCondition('item_id', $form_state['values']['rates'])
        ->fieldCondition('field_delivery_basis', 'value', 'Weekly', '=');

    $startmonth = strtotime(date('m', $form_state['values']['new_date']).'/01/'.date('Y'));
    $endmonth = strtotime('+1 month', $startmonth);

    $query->fieldCondition('field_delivery_date_period', 'value', $startmonth, '>=')
                ->fieldCondition('field_delivery_date_period', 'value', $endmonth, '<=');

    $result = $query->execute();

    if ($result) {
        $headers = array(
            array('data' => 'Weekend', 'class' => 'tableHeader-processed'),
            array('data' => '', 'class' => 'tableHeader-processed'),
        );

        $rates = entity_load('field_collection_item', array_keys($result['field_collection_item']));

        foreach ($rates as $key => $rate) {
            if ($rate->field_delivery_available['und'][0]['value']) {
                $rows[] = array('data' => array(date('M j, Y', $rate->field_delivery_date_period['und'][0]['value']), array('data' => 'delivery link', 'class' => array('fee'))));
            } else {
                $rows[] = array('data' => array(date('M j, Y', $rate->field_delivery_date_period['und'][0]['value']), array('data' => 'Not Available!')));
            }
        }

        $form['booking_weekend']['#markup'] = theme('table', array('header' => $headers, 'rows' => $rows, 'sticky' => FALSE));
    } else {
        $form['booking_weekend']['#markup'] = 'No delivery weekends exist for this month. Please select another date.';
    }

    return $form['booking_weekend'];
}

Grundsätzlich frage ich bei der Auswahl eines Monats / Jahres nach Daten (innerhalb einer Feldsammlung).


Könnten Sie Ihre Frage auch mit dem Code für aktualisieren delivery_date_weekends()?
Clive

Rückruf hinzugefügt
Kevin

Antworten:


5

Es ist schwer zu sagen, ohne diese Abfragen tatsächlich auszuführen, aber ich denke, das Problem liegt nur an der Ungleichheit in den Namen Ihrer Formularelemente.

In Ihrem Formular ist das Element definiert als, $form['date_weekend']aber in Ihrem Rückruf setzen Sie ein Element namens $form['booking_weekend'].

Dies wäre wahrscheinlich in Ordnung, außer dass $form['booking_weekend']das nicht das hat #prefixund #suffixdas $form['date_weekend']tut. Drupal ersetzt das gesamte Wrapper-Element, wenn ein AJAX ersetzt wird. Wenn das neue Element keinen Wrapper mit derselben ID enthält, funktioniert der nächste AJAX-Aufruf nicht (da kein Element mit der richtigen ID vorhanden wäre).

Ich würde empfehlen, die Elementnamen so zu ändern, dass sie übereinstimmen, da dies das Problem lösen sollte. Wenn Sie jedoch wirklich ein anderes Element benötigen, fügen Sie einfach den Wrapper um das neue Element in Ihrem Rückruf hinzu:

// The rest of delivery_date_weekends() comes before this as normal...

  $form['booking_weekend']['#markup'] = theme('table', array('header' => $headers, 'rows' => $rows, 'sticky' => FALSE));
} else {
    $form['booking_weekend']['#markup'] = 'No delivery weekends exist for this month. Please select another date.';
}

$form['booking_weekend']['#prefix'] = '<div id="dates-ajax">';
$form['booking_weekend']['#suffix'] = '</div>';

return $form['booking_weekend'];

Okay, ich habe das alles behoben und sie sind konsistent. Es funktioniert immer noch nur beim ersten Mal, dann beim zweiten Mal, wenn das Feld überhaupt nicht aktualisiert wird und die Antwort keine Daten enthält (und es sollte vorhanden sein). Die Abfrage funktioniert einwandfrei. Auch wenn keine Ergebnisse erzielt werden, sollte das Markup "Keine Lieferwochenenden ..." zurückgegeben werden.
Kevin

Versucht es, es beim zweiten Mal zu ersetzen, dh führt es die Überblendungsanimation durch und ersetzt es einfach durch dieselbe Tabelle? Und wenn nicht, erhalten Sie js-Fehler in der Konsole?
Clive

Keine Fehler, kein Ersetzen, es scheint nicht einmal etwas zu passieren. Daten werden noch gebucht. Die Antwort ist völlig leer, fast so, als ob Drupal weiß, dass es etwas tun sollte, aber nicht was. Mit 'leer' meine ich, ich sehe nur die generischen Befehle, die zurückgegeben werden, aber alle Werte sind null und es gibt nur das Element 0 (normalerweise 3).
Kevin

Kevin, hast du das jemals zum Laufen gebracht? Ich habe das gleiche Problem, bei dem der Ajax-Aufruf nur einmal ausgelöst wird. Und nie wieder, bis die Seite neu geladen wird.
Brandon Bearden

Ja, habe ich. Stellen Sie sicher, dass Sie die richtigen Elemente im AJAX-Rückruf zurückgeben, damit es beim erneuten Rendern weiterhin an das Formularelement gebunden ist. Ich denke das war mein Problem.
Kevin

0

Ich hatte mit ähnlichen Problemen zu kämpfen und fand hier endlich eine Lösung:

Drupal ersetzt das gesamte Wrapper-Element, wenn ein AJAX ersetzt wird. Wenn das neue Element keinen Wrapper mit derselben ID enthält, funktioniert der nächste AJAX-Aufruf nicht (da kein Element mit der richtigen ID vorhanden wäre).

Sehr einfach, aber ich habe es vergessen. Nachdem das Div-ID-Problem behoben wurde, verschwand es :) Danke, Clive!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.