Загрузить страницу с Drupal AJAX из JavaScript

Я работаю над модулем Drupal, который предоставляет тип узла jvectormap. Все отлично работает кроме друпала .load(), я использую

jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code +'?ajax=1');

Происходит следующее, я щелкаю страну на карте, и это вызывает / контент / институты /BE

/content/institutes is an views page with a contextual filter witch grabs the last part of the url and displays some data.

Узел jvectormap включен на этой же странице через мини-панель и блоки (представление находится в div #content, а jvectormap - в блоке мини-панели)

До этого момента все в порядке. Теперь, когда я нажимаю второй регион, URL-адрес внезапно переключается на /content/undefined,

Позвольте мне уточнить на примере: я нажимаю на Бельгию, URL-адрес изменяется на /content/institutes/BE, и представление выбирает это, затем я нажимаю на Францию, и URL-адрес изменяется на /content/undefined, но представление все еще корректно реагирует и показывает Информация о Франции. Теперь я нажимаю F5, чтобы обновить браузер, и drupal говорит, что /content/undefined не существует. Если я нажму F5 после первого клика (Бельгия), он перезагрузит страницу правильно. Кажется, проблема возникает с последовательными запросами AJAX. Я могу исправить это с помощью псевдонима URL, чтобы он обрабатывал край обновления F5, видя, что все остальное работает правильно, но если кому-то еще нужно более одного узла, у них есть (маленькая) проблема.

Я подозреваю .load это причина, почему это происходит.

Любая помощь приветствуется, спасибо.

jvectormapnode.js

(function ($) 
{
  Drupal.behaviors.jvectormapnode = 
  {
    attach: function (context, settings) 
    {
    $('#jvectormapnode').once('jvectormapnode', function() {  //fix duplicating behavior when using ajax

        highlighted=JSON.parse(Drupal.settings.jvectormapnode.coloredregions);
        //console.log(Drupal.settings.jvectormapnode.coloredregions);
        //console.log(highlighted);

            //change color of clicked region ==> todo
            /*
            currentSelected = '';
            defaultColor = '#00FF00';
            selectedColor = '#FF00FF'; 
            maphandle = $('#map-teste'); 

            maphandle.vectorMap({
                map: 'br_en',
                onRegionClick: function(event, code){
                    if(currentSelected !== code) {
                        if(currentSelected !== ''){
                            // Deselect, then select new choice
                            maphandle.vectorMap('set', 'colors', currentSelected, defaultColor);
                            maphandle.vectorMap('set', 'colors', code, selectedColor);
                            currentSelected = code;
                        } else {
                            // Nothing currently selected, go ahead and select
                            maphandle.vectorMap('set', 'colors', code, selectedColor);
                            currentSelected = code;
                        }
                    } else {
                        // Deselect
                        maphandle.vectorMap('set', 'colors', code, defaultColor);
                        currentSelected = '';
                    }
                    alert(code); // return the state
                }
            });*/

          $('#jvectormapnode').vectorMap({
                                        map: 'world_mill_en',
                                        focusOn: {
                                          x: Drupal.settings.jvectormapnode.x,
                                          y: Drupal.settings.jvectormapnode.y,
                                          scale: Drupal.settings.jvectormapnode.scale
                                        },
                                        color: '#aaaaaa',
                                        hoverColor: false,
                                        hoverOpacity: 0.5,
                                        backgroundColor: 'false',
                                        onRegionClick: function (event, code)   {

                                                                                //if(typeof(afunctiontodo!='undefined') afunctiontodo();
                                                                                //else
                                                                                //{
                                                                                    //window.location = Drupal.settings.jvectormapnode.url+'/'+ code;
                                                                                    jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code +'?ajax=1');
                                                                                    //$('#jvectormapnode').vectorMap('set', 'focus', code);
                                                                                    //showSelectedCountry;
                                                                                //}
                                                                                },  
                                        series: {
                                        regions: [{
                                            values: highlighted ,
                                            attribute: 'fill'
                                        }]
                                    }

                                    });
        });
    }
  };
}(jQuery));

jvectormapnode.module

<?php
/**
 * @file 
 */

/**
 * @defgroup jvectormapnode : Node
 * @ingroup jvectormapnode
 * @{
 * 20130812 pieterm
 * Integrates jvectormapnode into Drupal through the node type system
 */


 /**
 * Implements hook_libraries_info().
 */
function jvectormapnode_libraries_info() {
  $libraries['jvectormap'] = array(
    'name' => 'jVectorMap',
    'vendor url' => 'http://jvectormap.com/',
    'download url' => 'http://jvectormap.com/download/',
    'version arguments' => array(
      'file' => 'jquery.jvectormap.min.js',
      'pattern' => '@jVectorMap version ([0-9\.]+)@',
      'lines' => 2,
      'cols' => 30,
    ),
    'versions' => array(
      '1.2.2' => array(
        'files' => array(
          'js' => array('jquery.jvectormap.min.js'),
          'css' => array('jquery.jvectormap.css'),
        ),
      ),
    ),
  );

  return $libraries;
}

/**
 * Implements hook_view().
 */
function jvectormapnode_view($node, $view_mode) {
      $node->content['jvectormapnodebody'] = array(
    '#markup' => _jvectormapnode_page($node),
    '#weight' => 1,
  );
    return $node;
}


/**
 * Implements hook_theme().
 * Overriding the default node template for jvectormapnode pages
 */
function jvectormapnode_theme($existing, $type, $theme, $path) {
    $items = array(
        'node__jvectormapnode' => array(
            // Don't specify the path in the template name.
            // Unless you have your template inside a directory within this module.
            'template' =>  'templates/node--jvectormapnode',
            'variables' => array('node' => (object)array()),
            // If you want to put the tpl in another location, you can use this key.
            //'theme path' => drupal_get_path('module', 'another_module'),
        ),
    );
    return $items;
}

/**
 * Implements hook_node_info().
 *
 * We use hook_node_info() to define our node content type.
 */
function jvectormapnode_node_info() {
  // We define the node type as an associative array.
  return array(
    'jvectormapnode' => array(
      'name' => t('jvectormapnode'),
      'base' => 'jvectormapnode', //function prefix hooks
      'description' => t('This is the jvectormapnode node type. It can display interactive maps.'),
      'title_label' => t('jvectormapnode page title'),
      'locked' => FALSE, //TODO SET TRUE
    ),
  );
}

/**
 * Implements hook_node_type_insert().
 * lets us know that a new content type has been inserted.
 * this gives us a chance to add the fields we want. (called for all node isnert!==>check type)
 */
function jvectormapnode_node_type_insert($content_type) {
  if ($content_type->type == 'jvectormapnode') {
    // Add default body field
    $body_instance = node_add_body_field($content_type, t('Information you want to show on each page before the content of the jvectormapnode module'));
    $body_instance['display']['example_node_list'] = array(
      'label' => 'hidden',
      'type' => 'text_summary_or_trimmed',
    );
    // Save our changes to the body field instance.
    field_update_instance($body_instance);

    // Create all the fields we are adding to our content type.
    foreach (_jvectormapnode_installed_fields() as $field) {
      field_create_field($field);
    }

    // Create all the instances for our fields.
    foreach (_jvectormapnode_installed_instances() as $instance) {
      $instance['entity_type'] = 'node';
      $instance['bundle'] = 'jvectormapnode';
      field_create_instance($instance);
    }
  }
}

/**
 * Define the fields for our content type.
 *
 * This big array is factored into this function for readability.
 *
 * @return
 *  An associative array specifying the fields we wish to add to our
 *  new node type.
 */
function _jvectormapnode_installed_fields() {
  return array(
      'jvectormapnode_field_color' => array(
      'field_name'  => 'jvectormapnode_field_color',
      'cardinality' => 1,
      'type'        => 'text',
    ),
      'jvectormapnode_field_url' => array(
      'field_name'  => 'jvectormapnode_field_url',
      'cardinality' => 1,
      'type'        => 'text',
    ),
      'jvectormapnode_field_width' => array(
      'field_name'  => 'jvectormapnode_field_width',
      'cardinality' => 1,
      'type'        => 'text',
    ),
      'jvectormapnode_field_height' => array(
      'field_name'  => 'jvectormapnode_field_height',
      'cardinality' => 1,
      'type'        => 'text',
    ),  
      'jvectormapnode_field_regions' => array(
      'field_name'  => 'jvectormapnode_field_regions',
      'cardinality' => 1,
      'type'        => 'text',
    ),  
          'jvectormapnode_field_scale' => array(
      'field_name'  => 'jvectormapnode_field_scale',
      'cardinality' => 1,
      'type'        => 'text',
    ),
          'jvectormapnode_field_x' => array(
      'field_name'  => 'jvectormapnode_field_x',
      'cardinality' => 1,
      'type'        => 'text',
    ),
          'jvectormapnode_field_y' => array(
      'field_name'  => 'jvectormapnode_field_y',
      'cardinality' => 1,
      'type'        => 'text',
    ),
  );
}

/**
 * Define the field instances for our content type.
 *
 * The instance lets Drupal know which widget to use to allow the user to enter
 * data and how to react in different view modes. 
 *
 * This big array is factored into this function for readability.
 *
 * @return
 *  An associative array specifying the instances we wish to add to our new
 *  node type.
 */
function _jvectormapnode_installed_instances() {
  return array(

    'jvectormapnode_field_url' => array(
      'field_name' => 'jvectormapnode_field_url',
      'label'       => t('URL, format http://www.vliz.be/en/...'),
      'widget'      => array(
        'type'    => 'text_textfield',
      ),
      ),
     'jvectormapnode_field_width' => array(
     'field_name' => 'jvectormapnode_field_width',
     'label'       => t('Map width, format px or %'),
     'widget'      => array(
     'type'    => 'text_textfield',
      ),
      ),
        'jvectormapnode_field_height' => array(
     'field_name' => 'jvectormapnode_field_height',
     'label'       => t('Map height, format px or %'),
     'widget'      => array(
     'type'    => 'text_textfield',
      ),
    ),
         'jvectormapnode_field_regions' => array(
     'field_name' => 'jvectormapnode_field_regions',
     'label'       => t('Regions to be highlighted'),
     'widget'      => array(
     'type'    => 'text_textfield',
      ),
      ),

          'jvectormapnode_field_color' => array(
      'field_name' => 'jvectormapnode_field_color',
      'label'       => t('Highlight color, HEX format #ffffff.'),
      'widget'      => array(
        'type'    => 'text_textfield',
      ),
    ),
              'jvectormapnode_field_scale' => array(
      'field_name' => 'jvectormapnode_field_scale',
      'label'       => t('Initial zoom, nummeric format.'),
      'widget'      => array(
        'type'    => 'text_textfield',
      ),
    ),
              'jvectormapnode_field_x' => array(
      'field_name' => 'jvectormapnode_field_x',
      'label'       => t('Initial x-axis focus, nummeric format.'),
      'widget'      => array(
        'type'    => 'text_textfield',
      ),
    ),
              'jvectormapnode_field_y' => array(
      'field_name' => 'jvectormapnode_field_y',
      'label'       => t('Initial y-axis focus, nummeric format.'),
      'widget'      => array(
        'type'    => 'text_textfield',
      ),
    ),
  );
}

/**
 * Implements hook_entity_info_alter().
 *
 * We need to modify the default node entity info by adding a new view mode to
 * be used in functions like node_view() or node_build_content().
 */
function jvectormapnode_entity_info_alter(&$entity_info) {
  // Add our new view mode to the list of view modes...
  $entity_info['node']['view modes']['example_node_list'] = array(
    'label' => t('Example Node List'),
    'custom settings' => TRUE,
  );
}

/**
 * Implement hook_form().
 *
 * Drupal needs for us to provide a form that lets the user
 * add content. This is the form that the user will see if
 * they go to node/add/node-example.
 */
function jvectormapnode_form($node, $form_state) {
  return node_content_form($node, $form_state);
}

/**
 * Implements hook_field_formatter_info().
 */
function jvectormapnode_field_formatter_info() {
  return array(
    'jvectormapnode_field_color' => array(
      'label' => t('jvectormapnode color Handle'),
      'field types' => array('text'),
    ),
    'jvectormapnode_field_url' => array(
      'label' => t('jvectormapnode url Handle'),
      'field types' => array('text'),
    ),
        'jvectormapnode_field_width' => array(
      'label' => t('jvectormapnode width Handle'),
      'field types' => array('text'),
    ),
        'jvectormapnode_field_height' => array(
      'label' => t('jvectormapnode height Handle'),
      'field types' => array('text'),
    ),
        'jvectormapnode_field_regions' => array(
      'label' => t('jvectormapnode regions Handle'),
      'field types' => array('text'),
    ),  
            'jvectormapnode_field_scale' => array(
      'label' => t('jvectormapnode scale Handle'),
      'field types' => array('text'),
    ),          
    'jvectormapnode_field_x' => array(
      'label' => t('jvectormapnode x Handle'),
      'field types' => array('text'),
    ),
        'jvectormapnode_field_y' => array(
      'label' => t('jvectormapnode y Handle'),
      'field types' => array('text'),
    ),      
  );
}

/**
 * Implements hook_help().
 */
function jvectormapnode_help($path, $arg) {
  switch ($path) {
    case 'examples/jvectormapnode':
      return "<p>" . t("The Node Example module provides a custom node type.
        You can create new Example Node nodes using the <a href='!nodeadd'>node add form</a>.",
        array('!nodeadd' => url('node/add/node-example'))) . "</p>";
  }
}

/**
 * Page callback to show jvectormapnode
 */
function _jvectormapnode_page($n) {
    //get params from drupal entity created by user in add content
    $dcolor= field_get_items('node', $n, 'jvectormapnode_field_color');
    $dcolor=render(field_view_value('node', $n, 'jvectormapnode_field_color',$dcolor[0]));

    $durl= field_get_items('node', $n, 'jvectormapnode_field_url');
    $durl=render(field_view_value('node', $n, 'jvectormapnode_field_url',$durl[0]));

    $dwidth= field_get_items('node', $n, 'jvectormapnode_field_width');
    $dwidth=render(field_view_value('node', $n, 'jvectormapnode_field_width',$dwidth[0]));

    $dheight= field_get_items('node', $n, 'jvectormapnode_field_height');
    $dheight=render(field_view_value('node', $n, 'jvectormapnode_field_height',$dheight[0]));   

    $dregions= field_get_items('node', $n, 'jvectormapnode_field_regions');
    $dregions=render(field_view_value('node', $n, 'jvectormapnode_field_regions',$dregions[0]));    

    $dscale= field_get_items('node', $n, 'jvectormapnode_field_scale');
    $dscale=render(field_view_value('node', $n, 'jvectormapnode_field_scale',$dscale[0]));  

        $dx= field_get_items('node', $n, 'jvectormapnode_field_x');
    $dx=render(field_view_value('node', $n, 'jvectormapnode_field_x',$dx[0]));  

        $dy= field_get_items('node', $n, 'jvectormapnode_field_y');
    $dy=render(field_view_value('node', $n, 'jvectormapnode_field_y',$dy[0]));  

    //$coloredregions=array();

    $exploderegions = explode(",", $dregions);

    $coloredregions=array();
    foreach ($exploderegions as $region) 
        {
        $coloredregions[$region] = $dcolor ;
        }

    $coloredregions_object = json_encode($coloredregions);

    $jvectormapnodebody.= '<div style="width: '.$dwidth.'; height: '.$dheight.'" id="jvectormapnode"></div>';


    libraries_load('jvectormap');

    drupal_add_js('/sites/all/modules/vliz/jvectormapnode/js/maps/jquery-jvectormap-world-mill-en.js');

    drupal_add_js(array('jvectormapnode' => array('url' => $durl,'coloredregions'=> $coloredregions_object,'scale' => $dscale,'x' => $dx,'y' => $dy)), 'setting');

    drupal_add_js('/sites/all/modules/vliz/jvectormapnode/js/jvectormapnode.js');

    return $jvectormapnodebody;
}



/**
 * @} End of "defgroup jvectormapnode".
 */

2 ответа

Я узнал, что стало причиной неопределенности, вот код, который работает

jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code ,'ajax=1' ,
function() {Drupal.attachBehaviors('#content');});

надеюсь, это поможет кому-то еще

Кажется, что code аргумент передан в рамках onRegionClick обратный вызов не определен.

Вы можете сделать console.log() этого аргумента, чтобы узнать точное значение? Обычно это должен быть код региона в виде строки. (то есть: "BE", "NL", ...)

onRegionClick: function (event, code) {
     console.log(code);
}
Другие вопросы по тегам