0

What I'm trying to do:
Make an ajax-powered search button that gets the text from an input and give a list of post id's that match that search.

Note: I must probably sound very stupid to 90% of you, but I'm rather new to ajax and wordpress, so if I'm doing it all wrong, it would be great if someone could point me out what I'm doing wrong or if he knows a better guide than the ones I used. (The problems I think I'm having with the script are written all the way down below.)

To start I thought of just making a button that uses ajax to get the title of a post-id.
I read these pages:

I've tried out all this code on both these pages, however, I'm always stuck because I need to create a plugin. I'm not trying to create a plugin so I was wondering if I could just write all the code on my search page.

I'm sad however that it doesn't work, and I cannot find out why... (i get redirected to the homepage)

I'm just curious if I have to research how to create plugins etc. or is there a much simpler way that just allows me to get e.g. the post title of a certain ID through an AJAX call without using a plugin?

This is the code I tried:

The Ajax call:

<script>    
jQuery(document).ready(function($) {           //wrapper
    $("body").on("click",".ajax",function() {             //event
        var s_str = this.value;
        console.log(s_str);
        console.log(admin_ajax_url.ajax_url);
        var this2 = this;                      //use in callback
        $.post(admin_ajax_url.ajaxurl, {         //POST request
           _ajax_nonce: get_title_nonce.nonce,     //nonce
            action: "get_title",            //action
            id: s_str,                  //data
            success: function(response) {
                if(response.type == "success") {
                    alert("success")
                }
                else {
                    alert("failed")
                }
            }
        }, function(data) {                    //callback
            $("#tt").html(data);              //insert server response
        });
    });
});
</script>

The search form:

$the_title = '';
 $s_str = 18694;
 $nonce = wp_create_nonce("get_title_nonce");
  $link = admin_url('http://jtc.ae/pre/wp/wp-admin/admin-ajax.php?action=get_title&post_id='.$s_str.'&nonce='.$nonce);
        echo '<a class="ajax" data-nonce="' . $nonce . '" data-post_id="' . $s_str . '" href="' . $link . '">'.$s_str.'</a> Title: <span id="tt">'.$the_title."</span>";

The rest of the code I added as written in the guides:

<?php

add_action( 'init', 'my_script_enqueuer' );
function my_script_enqueuer() {
    wp_register_script('ajax_search',TEMPLATEPATH.'/new/js/ajax_search.js', array('jquery'));
    wp_localize_script('ajax_search', 'admin_ajax_url', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));

   wp_enqueue_script( 'jquery' );
   wp_enqueue_script( 'ajax_search' );
}



add_action("wp_ajax_get_title", "get_title");
add_action("wp_ajax_nopriv_get_title", "get_title_must_login");

function get_title() {
   if ( !wp_verify_nonce( $_REQUEST['nonce'], "get_title")) {
      exit("No naughty business please");
   }   
   $the_title = get_the_title($_REQUEST["post_id"]);

   if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
      $result = json_encode($result);
      echo $result;
   }
   else {
      header("Location: ".$_SERVER["HTTP_REFERER"]);
   }

   die();
}
function get_title_must_login() {
   echo "You must log in to get title";
   die();
}
?>

Probably the problems lie here:
I'm not sure about these add_action parts... I don't think I need it if I add the link to admin-ajax.php directly like I did just here above: http://jtc.ae/pre/wp/wp-admin/admin-ajax.php? So could I just scrap this first add_action?

Also I think that the bottom add_actions are probably not properly excecuted on my search_page.php. But this is just the thing: I'm not planning on creating any plugins, so I don't know where to put them...

3 Answers 3

0

Plugin code is just... code, it can go in a themes functions.php, or a plugin file, there's no magical or special difference other than the order they're loaded in, and the API calls are identical, work the same way etc because they're the same. It's just how the code is packaged

For example, if you ever want to do something without using a plugin, take a plugin, remove the comment at the top of the main file, and hey presto you've got your answer.

The problem you're facing is that you've tried to put your logic inside the search page. But that's not how the AJAX API works. When the browser makes a request to the AJAX endpoint, no templates are loaded, so your search template is never loaded, and your code to handle the request is never loaded.

Instead, the code needs to be in functions.php which is always loaded.

You can see this here:

add_action( 'init', 'my_script_enqueuer' );

Here, you're saying "When the init event happens, run this function", but if you're in the search page template, then that event has already happened. Remember, templates are loaded after everything else, not before

5
  • Do i need to put the whole bottom part in functions.php?
    – mesqueeb
    Commented Mar 14, 2016 at 15:10
  • The hooks go in functions.php, although there really is no reason not to put it in a plugin
    – Tom J Nowell
    Commented Mar 14, 2016 at 17:49
  • I saw the wordpress manual on making plugins, and it's really long. I'm just too time constraint now to go through that. So we decided not to make plugins but do everything through functions.php.
    – mesqueeb
    Commented Mar 14, 2016 at 23:49
  • Take whats in your functions.php and copy paste it into a new file in the plugins folder. Copy paste the comment at the top from another plugin and change the plugin name. That's literally all you need to do. A plugin is just a PHP file with a comment at the top that's written a certain way. But if you're time constrained, then you really do need to learn what hooks are, and some basics, otherwise you'll be wasting a lot of time over things that are super simple and take 10-20 words to explain
    – Tom J Nowell
    Commented Mar 15, 2016 at 12:41
  • Thanks Tom! I'm really learning a lot. Do you have any wordpress guide recommendations?
    – mesqueeb
    Commented Mar 15, 2016 at 14:19
0

After a lot of tinkering I finally got the answer:

First of all you don't need this: Delete it

add_action( 'init', 'my_script_enqueuer' );
function my_script_enqueuer() {
    wp_register_script('ajax_search',TEMPLATEPATH.'/new/js/ajax_search.js', array('jquery'));
    wp_localize_script('ajax_search', 'admin_ajax_url', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));

   wp_enqueue_script( 'jquery' );
   wp_enqueue_script( 'ajax_search' );
}

Second, I was messing up GET and POST data. Use this to create an ajax search form:

<form method="post" id="searchbox">
    <input value="18694" name="post_id" class="ajax">
    <input type="button" class="ajaxgo" value="Submmmittt" name="submit">
</form>
Title: <span id="tt"></span> //to test the output

And make the ajax call with a script below this like this:

<script>
jQuery(document).ready(function($) {
    $("body").on("click",".ajaxgo",function(){
        console.log("fire");
        var s_str = $(".ajax").val();
        var ajax_url = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
        var get_title_nonce = "<? echo $get_title_nonce; ?>";
        var data = {
            nonce: get_title_nonce,
            action: "get_title",
            post_id: s_str, 
        };
        $.post(
            ajax_url,
            data,
            function(data) {                    //callback
                $("#tt").html(data);              //insert server response
            }
        );
    });
});
</script>

Finally use this code in your template's functions.php file:

function get_title() {

   if ( !wp_verify_nonce( $_POST['nonce'], "get_title_nonce")) {
      exit("No naughty business please");
   }   
   $result = get_the_title($_POST["post_id"]);

   if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
      //$result = json_encode($result);
      echo $result;
   } else {
      header("Location: ".$_SERVER["HTTP_REFERER"]);
   }

   die();
}
function get_title_must_login() {
   echo "You must log in to get title";
   die();
}
3
  • Where are you hooking up the 2 functions though? They're very generic and similar to an existing API, you should prefix them or namespace them. Also you should use wp_localize_script to pass in the AJAX endpoint URL and the nonce rather than outputting it inline via PHP
    – Tom J Nowell
    Commented Mar 15, 2016 at 17:25
  • Thanks Tom! I'll rename the hook. About the wp_localize_script I'm not sure what you mean... Maybe it has something to do with doing something with the data returned from AJAX? Maybe this is the same problem I'm having here: stackoverflow.com/questions/36006058/… I cannot access the data to use in a table... If you have some time it would be great if you could have take a look.
    – mesqueeb
    Commented Mar 15, 2016 at 23:48
  • Look into wp_localize_script, it's how you're meant to pass data from PHP to javascript. You're meant to use it instead of echo'ing it out. Consider asking a new question about what it does and why you would use it for a more indepth answer
    – Tom J Nowell
    Commented Mar 20, 2016 at 3:42
0

You may not want to post the ID via ajax for security reasons becuase your users can manipulate the ajax request. Here is a server side way to get the post id:

<script>
jQuery(document).ready(function($) {
    $("body").on("click",".ajaxgo",function(){
        console.log("fire");
        var s_str = $(".ajax").val();
        var ajax_url = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
        var get_title_nonce = "<? echo $get_title_nonce; ?>";
        var data = {
            nonce: get_title_nonce,
            action: "get_title",
        };
        $.post(
            ajax_url,
            data,
            function(data) {                    //callback
                $("#tt").html(data);              //insert server response
            }
        );
    });
});
</script>

And

function get_title() {

  if ( !wp_verify_nonce( $_POST['nonce'], "get_title_nonce" ) ) {
    exit( "No naughty business please" );
  }

  $url      = wp_get_referer();
  $post_id  = url_to_postid( $url )
  $result   = get_the_title( $post_id );

  if ( !empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' ) {
    //$result = json_encode( $result );
    echo $result;
  } else {
    header( "Location: ".$_SERVER["HTTP_REFERER"] );
  }

  die();
}

function get_title_must_login() {
  echo "You must log in to get title";
  die();
}
1
  • You mean with these two lines? $url = wp_get_referer(); $post_id = url_to_postid( $url )
    – mesqueeb
    Commented Mar 22, 2016 at 5:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.