Защо този файл, качен чрез ajax, извежда грешка в Drupal 7?

Имам webform и mymodule, който го променя. Уеб формулярът има поле stelle, което се попълва въз основа на url заявката. Например, ако ?stelle=10 полето се попълва от заглавието на възел с nid 10. Ако заявката ?stelle не съществува или е последвана от nid, който не съществува (не е от определен тип съдържание) или не съдържа определен низ, формулярът ще пренасочва към mynode?stelle=initiativ. Формата има 2 полета за качване на файлове чрез ajax, работи добре досега. Ето моят код:

<?php

/**
 * Altering the form! this will add class to the file upload/ remove buttons
 */
function mymodule_form_alter(&$form, &$form_state, $form_id) {
    $conf = mymodule_defaults();

    if ($form_id == 'webform_client_form_' . $conf['nid']) {
        if (isset($form['submitted']['field1'])) {
            $form['submitted']['field1']['#process'] = array('mymodule_my_file_element_process');
        }

        if (isset($form['submitted']['field2'])) {
            $form['submitted']['field2']['#process'] = array('mymodule_my_file_element_process');
        }

        $nid = $form['#node']->nid;
        $form['actions']['submit']['#ajax'] = array(
            'callback' => 'mymodule_webform_js_submit',
            'wrapper' => 'webform-client-form-' . $nid,
            'method' => 'replace',
            'effect' => 'fade',
        );

        $redirect_form = false;
        $maintenance = false;

        if (isset($form['submitted']['stelle']['#default_value']) && $form['submitted']['stelle']['#default_value'] !== '') {
            $hide_components = array(
                'einleitung_standard',
                'einleitung_initiativ',
            );
            $unhide_components = array();

            if ($form['submitted']['stelle']['#default_value'] == '') {
                $redirect_form = true;
            }
            elseif (is_numeric($form['submitted']['stelle']['#default_value'])) {
                $nid = $form['submitted']['stelle']['#default_value'];
                $node = node_load($nid);

                if ($node === false || (isset($node->type) && $node->type !== 'job')) {
                    $redirect_form = true;
                }
                else {
                    $type = $node->type;
                    if ($type == 'job') {
                        $form['submitted']['stelle']['#default_value'] = $node->title;
                        $form['submitted']['stelle']['#attributes']['disabled'] = 'disabled';
                        $form['submitted']['related']['#value'] = $nid;

                        $unhide_components = array(
                            'einleitung_standard'
                        );
                    }
                }
            }
            elseif ($form['submitted']['stelle']['#default_value'] == 'initiativ') {
                // unset($form['submitted']['stelle']);
                $form['submitted']['related']['#value'] = 'initiativ';
                $unhide_components = array(
                    'einleitung_initiativ'
                );
            }
        }
        else {
            // $redirect_form = true;
            // this causes an error

        }

Това е странната част:

        $redirect_form = false;
        $maintenance = false;

        if (isset($form['submitted']['stelle']['#default_value']) && $form['submitted']['stelle']['#default_value'] !== '') {
        ...
        else {
            // $redirect_form = true;
            // this causes an error

        }

Когато активирам реда за пренасочване на формуляра, когато условието if е невярно, бутонът за качване на файл чрез ajax извежда предупреждение за грешка при щракване (вижте отдолу за грешка). За мен това изглежда така, сякаш куката за промяна на формуляра се извиква отново, когато се щракне върху бутона за качване на файл без моето поле stelle да е налично - така ли е? Как да поправя това?

И сега останалата част от модула, основно само промени:

        else {
            // $redirect_form = true;
            // this causes an error

        }

        foreach ($unhide_components as $key => $component) {
            if (is_array($component)) {
                foreach ($component as $_key => $_component) {
                    $index = array_search($_component, $hide_components[$key]);
                    if ($index !== false) {
                        unset($hide_components[$key][$index]);
                    }
                }
            }
            else {
                $index = array_search($component, $hide_components);
                if ($index !== false) {
                    unset($hide_components[$index]);
                }   
            }
        }

        // hide
        foreach ($hide_components as $k=>$hc1){
            if (is_array($hc1)) {
                foreach ($hc1 as $hc2) unset($form['submitted'][$k][$hc2]);
            } else {
                unset($form['submitted'][$hc1]);
            }
        }


        if ($redirect_form) drupal_goto('node/'.$conf['nid'], array('query'=>array('stelle'=>'initiativ')), 301);
    }
}

function mymodule_my_file_element_process($element, &$form_state, $form) {
    $element = file_managed_file_process($element, $form_state, $form);
    $element['upload_button']['#attributes'] = array('class' => array('button'));
    $prefix = '<label class="browse-slave">';
    $prefix .= '<span class="button">' . t('Choose a file') . '</span>';
    $element['upload']['#prefix'] = $prefix;
    $element['upload_button']['#prefix'] = '</label>';


    $element['remove_button']['#attributes'] = array('class' => array('button'));
    $element['remove_button']['#prefix'] = '</label>';

    return $element;
}

function mymodule_webform_js_submit($form, $form_state) {
  // define the $sid variable (submission id from webform)
  $sid = $form_state['values']['details']['sid'];
  // if we have a sid then we know the form was properly submitted, otherwise, we'll just return the existing $form array
  if ($sid) {
    // first we have to load up the webform node object
    $node = node_load($form_state['values']['details']['nid']);
    // create an array up with the confirmation message, retreived from the webform node
    $confirmation = array(
      '#type' => 'markup',
      '#markup' => check_markup($node->webform['confirmation'], $node->webform['confirmation_format'], '', TRUE),
    );
    // return the confirmation message
    return $confirmation;
  }
  else {
    // return the form
    return $form;
  }
}

Грешката в AJAX е нещо като описаното тук. Промяната на настройките на сървъра/php не помогна.

Благодаря!


person Alex    schedule 03.12.2013    source източник


Отговори (2)


Конструкторът на формуляри (и всички промени на куките) ще бъдат стартирани, когато даден формуляр бъде валидиран, което се случва при #ajax действия.

Харесва ми да хвърлям статични персонализирани данни в $form['#someProperty'], така че да са налични във функциите за изграждане, валидиране и изпращане. Нещо подобно трябва да ви помогне:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  // ...
  if (isset($_GET['stelle'])) {
    $form['#stelle'] = $_GET['stelle']; // This will always be there.
  } 
  // ...
}

Друг вариант би бил да хвърлите $node, който зареждате във формуляра, като $form['#stelle_node'] = node_load(...) и очевидно само да правите това, когато nid действително е достъпен за вас, така че да не го презаписвате с празни данни, когато конструкторът на формуляри се изпълнява отново в бъдеще.

person Charlie Schliesser    schedule 12.12.2013
comment
ще го пробвам. премахнах всяко пренасочване и сега работи, но все пак се чудя как да поправя това - person Alex; 12.12.2013

Когато работех с ajax в drupal 6, хеш символът в url или заявка предизвикваше грешка всеки път..... така че замених url с това

         data.url.replace(/%2523/, '%23');        
person Sachin9    schedule 12.12.2013