【问题标题】:Wordpress Ajax reload with updated query vars使用更新的查询变量重新加载 Wordpress Ajax
【发布时间】:2016-12-09 22:21:23
【问题描述】:

我创建了一个前端过滤器,它可以更改 url 中的查询变量。

http://example.com/events/?zone=strength&days=28th&locations=136

zone 和 days 是分类法,locations 是来自自定义字段的元查询。

我有 3 个选择输入,其中包含每个查询变量的列表,当您选择其中一个时,页面会使用 url 中的新查询重新加载,并且它按预期工作。

一切正常,但我认为让 ajax 重新加载循环而不是完整的页面加载会更好。

我的 jQuery(可能写得不好):

// function to split up URL queries
function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split('&');
  for (var i=0; i<vars.length; i++) {
    var pair = vars[i].split('=');
    if (pair[0] == variable) {
      return pair[1];
    }
  }

  return false;
}	

// on ready, set the select values to the url queries
var zone = getQueryVariable('zone');
var days = getQueryVariable('days');
var locations = getQueryVariable('locations');

if(zone) {
  $(".event-filter .zone").val(zone);	
}
if(days) {
  $(".event-filter .day").val(days);	
}
if(locations) {
  $(".event-filter .location").val(locations);
}

// on select change, detect what changed and update url
jQuery('.event-filter select').on('change', function() {

  var params = {};

  if($(".event-filter .zone option:selected").val() != 'zone'){
    var zone = $(".event-filter .zone option:selected").val();
    params['zone'] = zone;
  }
  if($(".event-filter .day option:selected").val() != 'day'){
    var days = $(".event-filter .day option:selected").val()	
    params['days'] = days;
  }
  if($(".event-filter .location option:selected").val() != 'location'){
    var locations = $(".event-filter .location option:selected").val()
    params['locations'] = locations;
  }
  // create new url
  var path = window.location.pathname;
  if ($.isEmptyObject(params)) {
    var new_url = path;	
  } else {
    var new_url = path + '?' + jQuery.param(params);					
  }

  // reload page
  window.location.href = new_url;						

});	

我想用 ajax 将 new_url 变量重新加载为 url,并使用新的查询变量使循环再次运行。

我的循环:

// Check if query vars are being used in the URL. 
$days = get_query_var('days',FALSE);
$zone = get_query_var('zone',FALSE);	

// Created tax_query array, supporting multiple arrays where all conditions must be met 
$tax_query = array('relation' => 'AND');

// Set days variable with terms from the query var in url
if( ($days) ) {
  $tax_query[] = array(
    'taxonomy'  => 'day',
    'field'     => 'slug',
    'terms'     => $days,
  );
}

// Set zone variable with terms from the query var in url
if( ($zone)) {
  $tax_query[] = array(
    taxonomy'  => 'zone',
    'field'     => 'slug',
    'terms'     => $zone,
  );
}

// Check if locations query var is used
if(isset($_GET['locations']) && !empty($_GET['locations'])){
  $locations[] = array(
    'key' => 'event_location',
    'value' => $_GET['locations'],
    'compare' => 'IN'
  );
}

// Load both taxonomy query and meta query arrays into their respective args!
$args = array( 
  'post_type' => 'event', 
  'posts_per_page' => -1,
  'tax_query' => $tax_query,
  'meta_query' => $locations
);

$events = new WP_Query( $args );?>

我的想法是,我应该使用上述循环创建一个函数,只要使用 jQuery/ajax 更改选择字段时调用该函数,而不是重新加载页面。这是正确的吗?

如何让它从更改后的 new_url jquery 变量中仅加载包含循环的部分,而不是整个页面?

【问题讨论】:

    标签: jquery ajax wordpress


    【解决方案1】:

    好的,您想调整您当前的方法,用 AJAX 解决方案替换重定向(重新加载)。

    如何让它从更改后的 new_url jquery 变量中仅加载包含循环的部分,而不是整个页面?

    让我们考虑一下处理:

    1. 您将像现在一样获取参数,但它们将成为通过$.post() 返回服务器的数据包的一部分。
    2. 您将删除将查询变量附加到 URL 并执行重新加载的代码。不再需要了。
    3. 然后使用$.post 将参数发送到服务器。然后服务器检查安全随机数。如果没问题,您可以运行 PHP 代码来获取查询并构建事件 HTML。
    4. 然后服务器回显新的 HTML 并执行 die()wp_die()
    5. 脚本$.post 接收响应,即新的HTML 字符串。然后,您将删除旧的 HTML 并用新的 HTML 替换它。

    还和我在一起吗?让我们逐步了解将代码转换为新方法所需的操作。我写了一个答案,向另一个 PO 解释了这一点,you can find it here

    为脚本设置 URL 目标

    AJAX 需要一个 URL 来与服务器对话。在 WordPress 中,我们使用 admin-ajax.php 文件。入队时,您需要本地化参数以将其从服务器传递到脚本。

    wp_enqueue_script( 'your-script-handle', 'path-to/filename.js', array('jquery'), $version );
    wp_localize_script( 'your-script-handle', 'eventParams', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
    ));
    

    请注意,localize 命令的目标是您在将脚本排入队列时为其提供的句柄。它的作用是:

    • 将数组传递给脚本
    • 它被存储为一个对象,然后在脚本中使用变量eventParams

    在脚本中,您会收到这样的管理 ajax URL:

    $.post( eventParams.ajaxurl, dataPacket, function(htmlResponse) {
    
    });
    

    安全

    接下来,您需要添加一个随机数以确保安全。我建议添加hidden input field

    构建数据包

    jQuery $.post() 构造将数据包传递给服务器。您可以在上面看到我将它设置为一个名为dataPacket 的变量。您需要在运行 $.post() 之前构建该对象。

    我已将您的代码改编为您的起点:

    (function($, window, document){
        "use strict";
    
        var init = function() {
            $('.event-filter select').on('change', eventSelectHandler);
        }
    
        var eventSelectHandler = function() {
    
            var dataPacket = {
                action: 'event_filter',
                security: getSecurity(),
                zone: getZone(),
                days: getDay(),
                locations: getLocation()
            };
    
            $.post( eventParams.ajaxurl, dataPacket, function(htmlResponse) {
                // add your processing code
            });
    
        }
    
        function getSecurity() {
            // you'll grab that from the nonce field and then
            // return it.
        }
    
        function getZone() {
            return getSelected( '.zone', 'zone' );
        }
    
        function getDay() {
            return getSelected( '.day', 'day' );
        }
    
        function getLocation() {
            return getSelected( '.location', 'location' );
        }
    
        function getSelected( classAttribute, compareValue ) {
            var $element = $( ".event-filter " + classAttribute + " option:selected");
            if ( $element.length < 1 ) {
                return '';
            }
    
            var optionSelected = $element.val();
    
            if ( optionSelected != compareValue ) {
                return optionSelected;
            }
    
            return '';
        }
    
        $(document).ready(function(){
            init();
        });
    
    }(jQuery, window, document));
    

    查看函数eventSelectHandler()。请注意,您首先要构建数据包。然后一旦你构建了它,它就会被传递到$.post

    PHP 端

    现在在 PHP 端,您需要为 WordPress AJAX 事件注册一个回调函数。这些由您在数据包中提供的操作名称确定。

    您将对登录用户使用wp_ajax_{your action name},对访客使用wp_ajax_nopriv_{your action name}

    看起来像这样:

    add_action( 'wp_ajax_event_filter', 'process_event_filter_ajax_request' );
    add_action( 'wp_ajax_nopriv_event_filter', 'process_event_filter_ajax_request' );
    function process_event_filter_ajax_request() {
        // Check the security nonce first
        // If it fails, it returns immediately.
    
        // The parameters are in $_POST['zone']
        $zone     = strip_tags( $_POST['zone'] );
        $days     = strip_tags( $_POST['days'] );
        $location = strip_tags( $_POST['location'] );
    
        // do your work here
    
        // build the HTML
    
        wp_die();
    }
    

    您的带有WP_Query 处理的代码将是上述AJAX 处理的一部分。您需要将您的代码调整为上述回调。

    这应该足以让您走上正轨。

    【讨论】:

    • 托尼亚,非常感谢你,这太棒了,肯定让我走上了正轨。精彩而详细的回复,不胜感激!
    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 2014-07-23
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多