• I have written a WordPress plugin which places several buttons inside a metabox on the post-edit page. To see the page where this is done, I’d go to example.com/wp-admin/post.php?post=number1&action=edit When one of the buttons is clicked, I want to use php code to send data to a remote server that requires a password; however, I understand PHP cannot listen for click events. How might I go about doing this? I will be making an Ajax request and sending data thru a proxy.

    My code for the form with the data I want to send is two custom HTML elements’ entered data. They are:

        class MyFormData extends HTMLElement{
            
            constructor() {
              super();      
            }
        
            connectedCallback(){
              const li = document.createElement('li');
        
              const newDat = document.createElement('input');
              newDat.setAttribute('type','text');
              newDat.setAttribute('name',<code>title box</code>);
              newDat.setAttribute('placeholder',<code>Test Data</code>);
        
              const deleteButton = document.createElement('button');
              deleteButton.setAttribute('type','button');
              deleteButton.innerHTML = "-";
              deleteButton.addEventListener("click",function(){
                li.parentNode.remove();
              });
        
              li.appendChild(newDat);
              li.appendChild(deleteButton);
        
              this.appendChild(li);
            }
          }
        customElements.define('form-data',MyFormData);
    
    and 
    
        class DurationMenu extends HTMLElement{
        	
        	constructor(){
        		super();
        	}
        
        	connectedCallback(){
        		const amount = document.createElement('input');
        		amount.setAttribute('id','selectedTime');
        		amount.setAttribute('type','number');
        		amount.setAttribute('step',5)
        		amount.setAttribute('name','duration');
        		amount.setAttribute('min',5);
        		amount.setAttribute('max',60);
        		amount.setAttribute('value',15);
        		this.appendChild(amount)
        	}
        
        
        }
        customElements.define('duration-choice', DurationMenu);
    
    Both of these custom elements show up in the metabox. I have a custom element for the submit button:
    
        import ModelObject from './model/modelobject.js'
        
        var theJson;
        var data;
        
        import {CO} from './Controller/controllerobject.js';
        
        export var c = new ModelObject();
        import {grabDataForSending} from './Controller/wordpressrelay.js';
        
        export class SubmitAndCreate extends HTMLElement{
        	
        	constructor(){
        		super();			
        	}
        
        	connectedCallback(){
        		var data;
        		const submitbutton = document.createElement('button');
        		submitbutton.setAttribute('type','submit');
        		submitbutton.setAttribute('id','submitButton');
        		submitbutton.innerHTML = "Begin ";
        
        		submitbutton.addEventListener('click',this.myFunc.bind(this));
        
        		submitbutton.addEventListener('click',()=>{
        			document.getElementById('selectedTime').value = 15;
        			var dataset = document.getElementById("dataset").children;
        			for(var i = 0; i < dataset.length; i++){
        				document.getElementById("dataset").children[i].children[0].childNodes[0].value = '';	
        			}
        
        		});
        		submitbutton.addEventListener('click',(event)=>{
        			CO.updateModelData();
        			event.preventDefault();
        		})
        
        		submitbutton.addEventListener('click',(event)=>{
        			grabExperimentForSending();
        		})
        
        
        		this.appendChild(submitbutton);
        	}
        
        	gatherData(){
        		
        		//var enteredURL = document.getElementsByName('URL box')[0].value;
        		var dataAmount = document.getElementById('dataset').children.length;
        		var experTime = document.getElementById('selectedTime').value;
        
        		var dataObject = {
        			experimentDuration : experTime,
        			myData: {}
        		}
        
        		var individualDatum = [];
        
        		for (var i = 0; i < dataAmount; i++){
        			individualDatum[i] = {
        				dataset: document.getElementById("dataset").children[i].children[0].childNodes[0].value
        			}
        		}
        
        		dataObject.myData = individualDatum;
        		var dataObjectJSON = JSON.stringify(dataObject,null,2);
        		theJson = dataObjectJSON;
        
        		
        
        		return theJson;
        	}
        
        }
        export {theJson, CO};
        customElements.define('submit-button', SubmitAndCreate)
    
    I want to grab the data one enters in both, and submit it to an external site that normally requires a password and username to login to from outside WordPress. I want to submit it as JSon. How can I do this with Ajax and php?
    
    My php so far is:
    
        add_action( 'admin_footer', 'my_action_javascript' ); 
    	<script type="text/javascript" >
    	jQuery(document).ready(function($) {
    
    		var data = {
    			'action': 'MytestAjax',
    		};
    
    		jQuery.post(ajaxurl, data, function(response) {
    			alert('Got this from the server: ' + response);
    		});
    	});
    	</script> <?php
    }
    
        add_action( 'wp_ajax_my_action', 'MytestAjax' );
        
        function MytestAjax() {
    	header('Content-type: application/json');
    	$url = 'https://subdomain.example.com:port/api/v1/whereIWantItToGo';
    
    	//I'm not sure how to authenticate into the above site from here
    	if (isset($_POST['username']) && $_POST['username'] && isset($_POST['password']) && $_POST['password']) {
    	    echo json_encode(array('success' => 1));
    	} else {
    	    echo json_encode(array('success' => 0));
    	}
    	$handle = fopen($url, "r");
    	if ($handle) {
    	    while (!feof($handle)) {
    	        $buffer = fgets($handle, 4096);
    	        echo $buffer;
    	    }
    	    fclose($handle); 
    
    	wp_die();
    	}
    
    }

    Once a person hits the submit button, then I need it to go to do ajax and php.

Viewing 7 replies - 16 through 22 (of 22 total)
  • Moderator bcworkz

    (@bcworkz)

    Which error log? You should see something in your browser’s JS console, not the server’s error log. If there’s nothing, there’s an error elsewhere.

    Did you get a value assigned to ajaxurl through wp_localize_script()? It goes after a call to wp_enqueue_script(). But if you’re not enqueuing, that method will not work. If you’re directly outputting your jQuery code, you could just hardcode the value as part of your <script> block, for example:
    var ajaxurl = 'https://your-domaion-here.com/wp-admin/admin-ajax.php';

    Thread Starter bullshark

    (@bullshark)

    Hi @bcworkz, I see nothing in my error log. Are you saying it should go in the callback function given as an argument to add_action(‘admin_enqueue_scripts’,function(){})?

    However, I did not enqueue the script in which the intial JS ajax call lives, namely: import {grabDataForSending} from ‘./Controller/wordpressrelay.js’;

    That file is ./Controller/wordpressrelay.js

    import {c} from ‘../submitandcreate.js’;

    function grabDataForSending(){

    $.ajax({
    url: “post.php”,
    type: “POST”,
    data: c ,
    success: function (response, statusCode) {
    console.log(c.exps[0]);
    //console.log(response is ${response});
    console.log(statusCode is ${statusCode});
    console.log(data is ${data});
    },
    error: function(jqXHR, textStatus, errorThrown) {
    console.log(jqXHR is ${jqXHR}, textStatus is ${textStatus}, errorThrown is ${errorThrown});
    }
    });
    }

    export {grabDataForSending};

    Do I need to enqueue this? The reason I didn’t is bc the logs in there DO show up on the browser console.

    Moderator bcworkz

    (@bcworkz)

    You don’t have to enqueue, but it’s ” The WordPress Way? ” of doing things. Something on the page needs to be enqueued in order to use wp_localize_script(). You need a “handle” argument from enqueuing something for the function to work. What it actually does is output something similar to
    var ajaxurl = 'https://your-domain-here.com/wp-admin/admin-ajax.php';
    in a <script> block. You could output it yourself when you output your other code. The downside of doing it yourself is such code is not portable to any other WP site unless someone manually modifies the code.

    To be truly portable the correct path needs to come from PHP. This does not have to be done through wp_localize_script(). You can have custom PHP somewhere output the correct path taken from admin_url( 'admin-ajax.php' )

    Thread Starter bullshark

    (@bullshark)

    alright, so now my code gives me a 400 error when I try to submit the data to the server, and a response of 0. I’ve reognized my code. My non HTML-element code is:

    My php so far is:

    //for admin-ajax
    add_action( ‘admin_enqueue_scripts’, ‘my_enqueue’ );
    function my_enqueue($hook) {
    if( ‘index.php’ != $hook ) {
    return;
    }

    wp_enqueue_script( ‘ajax-script’, plugins_url( ‘/wp-content/plugins/my-plugin/js/Controller/ajaxdata.js’, __FILE__ ), array(‘jquery’) );
    wp_localize_script( ‘ajax-script’, ‘ajax_object’,
    array( ‘ajax_url’ => admin_url( ‘admin-ajax.php’ ), ‘c’ => c ) ); //c has the data that I need to send to the remote site’s server
    }

    //relevant to admin-ajax
    add_action( ‘wp_ajax_CBAjax’, ‘CBAjax’ );

    //relevant to admin-ajax
    function CBAjax() {

    error_log(print_r($_REQUEST));

    if ( isset($_REQUEST) ) {

    $exper = $_REQUEST[‘experdata’];

    error_log(print_r($exper,true));

    echo “The exper is ” . $exper;

    }

    $body = array(
    ‘dur’ => $exper[‘experimentDuration’],
    ‘buckets’=> $experdata[‘myData’]
    );

    $response = wp_remote_post( $url = “https://subdomain.example.com:8080/api/v1/data&#8221;, array(
    ‘body’ => $body,
    ‘headers’ => array(
    ‘Authorization’ => ‘Basic ‘ . base64_encode( “[email protected]” . ‘:’ . “password!” ),
    ),
    ) );
    // I need to send my data here: “https://subdomain.example.com:8080/api/v1/data&#8221;!!!
    if($response){
    error_log(print_r($response,true));
    error_log(“PING”);

    }

    $respcode = wp_remote_retrieve_response_code($response);
    error_log(print_r($respcode,true));
    $ajax[‘remote_code’] = $response[‘response’][‘code’];
    echo json_encode( $ajax );
    error_log(print_r($ajax,true));

    wp_die();

    }

    in the creation of the metabox, I have:

    add_action( ‘admin_enqueue_scripts’, ‘my_enqueue’ );
    add_action( ‘wp_ajax_CBAjax’, ‘CBAjax’ );

    This is how I proxy the data from the button to the admin-ajax.php page:

    import {c} from ‘../submitbutton.js’;

    function grabExperimentForSending(){

    $.ajax({
    url: “admin-ajax.php”,
    type: “POST”,
    data: c ,
    success: function (response, statusCode) {
    console.log(c.exps[0]);
    console.log(statusCode is ${statusCode});
    console.log(data is ${data});
    },
    error: function(jqXHR, textStatus, errorThrown) {
    console.log(jqXHR is ${jqXHR}, textStatus is ${textStatus}, errorThrown is ${errorThrown});
    console.log(c.exps[0]);
    }
    });
    }

    and from there, it goes to ajaxdata.js

    import {c} from ‘./wordpressrelay.js’;

    function my_action_javascript(){

    $(‘#submitButton’).click( function(){
    var data = { //model
    ‘action’: ‘CBAjax’,

    ‘experdata’: ajax_object.c
    }

    jQuery.post(ajax_object.ajax_url, data, function(response) {
    console.log(‘Got this from the server: ‘ + response);
    console.log(data.experdata);
    console.log(data[experdata] is ${data['experdata']});
    });
    });

    }

    export {my_action_javascript,c};

    export {grabExperimentForSending,c};

    • This reply was modified 4 years, 8 months ago by t-p.
    • This reply was modified 4 years, 8 months ago by t-p.
    • This reply was modified 4 years, 8 months ago by t-p.
    Moderator bcworkz

    (@bcworkz)

    Some of your print_r() calls within error_log() are missing the second true argument required for it to return a string to error_log().

    Comment out the bulk of code within CBAjax(). Make it so the remaining functional code is something like:

    function CBAjax() {
      error_log('CBAjax() was called');
      echo 'Hello world!';
      exit;
    }

    See if that works with your jQuery or not. Once it works correctly, add back more of your code, bits at a time. Test after every addition and correct as needed. Eventually you’ll build out your code to what you need. PHP Ajax callbacks are difficult to debug. By building up your code incrementally you’ll know where the problem lies when anything goes wrong. As it is now, we’ve no idea where the problem is.

    Thread Starter bullshark

    (@bullshark)

    @bcworkz I still got nothing.

    Moderator bcworkz

    (@bcworkz)

    Which jQuery are you testing? .ajax() or .post()? Your .ajax() has issues, there’s no “action” value and data passed needs to be serialized (use .param()). Your .post() looks more like it should work. .post() serializes provided data for you and you’ve passed an “action” value.

Viewing 7 replies - 16 through 22 (of 22 total)
  • The topic ‘How can I write hook that receives AJAX call from button click?’ is closed to new replies.