9

In a custom plugin, I generate a demoConnectors shortcode and initialize its content. This one contains PHP variables in input of type select. The user must therefore select the parameters and the PHP variables are updated via ajax. Depending on the selected parameters, the content of the shortcode is modified.

The problem is that I don't know how to update the shortcode content after the Ajax is triggered.

Here is my PHP code:

<?php 
/**
 *   Plugin Name: demoConnecteurs
 *   Description: Plugin de démo des connecteurs Jenkins et Mantis
**/
require_once(file_with_external_fonctions.php);

$inst_demoConnecteurs = new demoConnecteurs();
if (isset($inst_demoConnecteurs)){
}

class demoConnecteurs{   
    private $projects;
    private $versions;

    private $project_id;
    private $project_name;
    private $version_id;


    function __construct(){
        $this->setProjects();

        $this->initAjaxActions();

        add_action('admin_enqueue_scripts', array($this,'demo_scripts'));
        add_action('wp_enqueue_scripts', array($this,'demo_scripts'));


        $this->init();
    }

    function initAjaxActions(){
        add_action('wp_ajax_setProjectChosen', array($this,'setProjectChosen'));
        add_action('wp_ajax_nopriv_setProjectChosen', array($this,'setProjectChosen'));
    }

    function demo_scripts(){
        wp_register_script( 'ajaxHandle', plugins_url() . '/DemoConnecteurs/buttons_ajax.js');
        wp_localize_script( 'ajaxHandle', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

        wp_enqueue_script( 'ajaxHandle');
    }

    function init(){
        add_shortcode( 'demoConnecteurs', array($this,'demoConnecteurs_shortcode') );
    }

    function demoConnecteurs_shortcode () {
        return $this->contentDemoConnecteurs();
    }

    public function setProjects(){
        $this->projects = getProjects();
    }

    public function setProjectChosen(){
        if (isset ($_POST['demo_projet_name']))$this->project_name = $_POST['demo_projet_name'];
        $this->project_id = getProjectIdFromName($this->mantisClient,  $_SESSION['username'], $_SESSION['password'], $this->project_name);

        $this->setVersions();
        echo $this->contentDemoConnecteurs();
        wp_die();
    }

    public function setVersions(){
        $this->versions = getVersionsOfProjectChosen($this->project_id);
    }

    function contentDemoConnecteurs(){
        $html = "";

        $html .= 'Choix du projet : ';        
        $html .= '<select id="projectChosen" name="project">';
        foreach($this->projects as $p) {
            $selected = ($p->id == $this->project_id) ? 'selected="selected"' : '';
            $html .= '<option value="' . $p->name .'" '. $selected . ' >' . $p->name . '</option>';
        }
        $html .= '</select><br>';

        $html .= 'Choix de la version : ';
        if (isset ($this->versions)){
            $html .= '<select id="versionChosen" name="version">';
            foreach($this->versions as $v) {
                $selected = ($v->id == $this->version_id) ? 'selected="selected"' : '';
                $html .= '<option value="' . $v->id .'" '. $selected . ' >' . $v->id . '</option>';
            }
            $html .= '</select>';
        }

        return $html;
    }
}

And here my jQuery code:

jQuery(document).ready(function($) {

    $('#projectChosen').on('change', function () {
        jQuery.ajax({
            type: "POST",
            url: ajax_object.ajaxurl,
            data: {
                'action': 'setProjectChosen',
                'demo_projet_name': $('#projectChosen option:selected').val()
            },
            success: function (output) {
                //how can I update the content of my shortcode with my variable output 
            },
            error: function(errorThrown){
                console.log(errorThrown);
            }
        });
    } );
} );

EDITS

I'm trying to use the filter do_shortcode_tag to update the content of the shortcode, I don't manage to make this work.. It just does not update the content

public function setProjectChosen(){
        if (isset ($_POST['demo_projet_name']))$this->project_name = $_POST['demo_projet_name'];
        $this->project_id = getProjectIdFromName($this->mantisClient,  $_SESSION['username'], $_SESSION['password'], $this->project_name);

        $this->setVersions();

        apply_filters( 'do_shortcode_tag', array($this, 'contentDemoConnecteurs'), 'demoConnecteurs',10,3 );

        wp_die();
    }

ninagath
  • 369
  • 2
  • 15
  • First of all this function `setProjectChosen` need to echo the new content of the shortcode, this will send it back to the ajax call, add another parameter there to handle success `success: function(response){ // handle response here }` and use the response object to display your new content – Ali_k Jun 14 '19 at 15:34
  • Thanks for your answer, I don't get how I should echo this new content: something like `echo $this->contentDemoConnecteurs();` ? does not seem to work – ninagath Jun 14 '19 at 15:40
  • Won't work on it's own, you need to handle it back in your jQuery ajax call as it's not complete. Check some of the answers here: https://stackoverflow.com/questions/5004233/jquery-ajax-post-example-with-php – Ali_k Jun 14 '19 at 15:44
  • ok thanks for your answers, gonna try out that – ninagath Jun 14 '19 at 15:45
  • try to right a functioning example and then edit your question – Ali_k Jun 14 '19 at 15:49
  • @Ali_k thanks to you, the `output` of my `success` Ajax returns the right content. My problem is that I don't know how to update the content of my WordPress shortcode with the `output` variable, would you have any idea? – ninagath Jun 17 '19 at 08:37
  • 2
    @ninagath try in the ajax url returning the full updated HTML and then simple replace the contents of the container. i.e. shortcode container is called `box` so you return the new html for `box` and with javascript replace the HTML completely. – Deckerz Jun 17 '19 at 10:33
  • @ninagath can you tell me how your shortcode value looks like (I do not need the real value, just to understand what kind of data it is) and the HTML where you need to put it? – Lajos Arpad Jun 17 '19 at 11:05
  • I use WordPress shortcode API, then, @LajosArpad the content of the shortcode is the content of the `contentDemoConnecteurs` function. @Deckerz I don't understand, there is no `box` container in my HTML shortcode.. – ninagath Jun 17 '19 at 11:54
  • I would like to clarify that if you describe 1. What is the generated shortcode of your HTML 2. What kind of value do you have for it on PHP 3. How should that value be converted into HTML, then I can give you a solution. – Lajos Arpad Jun 17 '19 at 12:25
  • What is the actual output of your `output` variable in your success function of the ajax call? Add it in your question please. – Refilon Jun 18 '19 at 14:50

2 Answers2

4

I would wirte a comment, but my current reputation only lets me to write an answer. Here id my solution to reprint the content of the AJAX output.

On PHP, add a container div with ID:

function contentDemoConnecteurs(){
    $html = '<div id="projectSelector">';

    $html .= 'Choix du projet : ';        
    $html .= '<select id="projectChosen" name="project">';
    foreach($this->projects as $p) {
        $selected = ($p->id == $this->project_id) ? 'selected="selected"' : '';
        $html .= '<option value="' . $p->name .'" '. $selected . ' >' . $p->name . '</option>';
    }
    $html .= '</select><br>';

    $html .= 'Choix de la version : ';
    if (isset ($this->versions)){
        $html .= '<select id="versionChosen" name="version">';
        foreach($this->versions as $v) {
            $selected = ($v->id == $this->version_id) ? 'selected="selected"' : '';
            $html .= '<option value="' . $v->id .'" '. $selected . ' >' . $v->id . '</option>';
        }
        $html .= '</select>';
    }
    $html .= '</div>';
    return $html;
}

On JQuery:

jQuery(document).ready(function($) {
    $('#projectChosen').on('change', function () {
        jQuery.ajax({
            type: "POST",
            url: ajax_object.ajaxurl,
            data: {
                'action': 'setProjectChosen',
                'demo_projet_name': $('#projectChosen option:selected').val()
            },
            success: function (output) {
                $( "div#projectSelector" ).replaceWith(output);
            },
            error: function(errorThrown){
                console.log(errorThrown);
            }
        });
    } );
} );

I hope that's what you need.

Adrian Cobo
  • 163
  • 1
  • 10
4

I finally made it, I got confused about what I wanted to do...

<?php 
/**
 *   Plugin Name: demoConnecteurs
 *   Description: Plugin de démo des connecteurs Jenkins et Mantis
**/
require_once(file_with_external_fonctions.php);

$inst_demoConnecteurs = new demoConnecteurs();
if (isset($inst_demoConnecteurs)){
}

class demoConnecteurs{   
    private $projects;
    private $versions;

    private $project_id;
    private $project_name;
    private $version_id;


    function __construct(){
        $this->setProjects();

        $this->initAjaxActions();

        add_action('admin_enqueue_scripts', array($this,'demo_scripts'));
        add_action('wp_enqueue_scripts', array($this,'demo_scripts'));


        $this->init();
    }

    function initAjaxActions(){
        add_action('wp_ajax_setProjectChosen', array($this,'setProjectChosen'));
        add_action('wp_ajax_nopriv_setProjectChosen', array($this,'setProjectChosen'));
    }

    function demo_scripts(){
        wp_register_script( 'ajaxHandle', plugins_url() . '/DemoConnecteurs/buttons_ajax.js');
        wp_localize_script( 'ajaxHandle', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

        wp_enqueue_script( 'ajaxHandle');
    }

    function init(){
        add_shortcode( 'demoConnecteurs', array($this,'demoConnecteurs_shortcode') );
    }

    function demoConnecteurs_shortcode () {
        return $this->contentDemoConnecteurs();
    }

    public function setProjects(){
        $this->projects = getProjects();
    }

    public function setProjectChosen(){
        if (isset ($_POST['demo_projet_name']))$this->project_name = $_POST['demo_projet_name'];
        $this->project_id = getProjectIdFromName($this->mantisClient,  $_SESSION['username'], $_SESSION['password'], $this->project_name);

        $this->setVersions();
        echo $this->contentDemoConnecteurs();
        wp_die();
    }

    public function setVersions(){
        $this->versions = getVersionsOfProjectChosen($this->project_id);
    }

    function contentDemoConnecteurs(){
        $html = '<div id="contentDemoConnecteurs">';

        $html .= 'Choix du projet : ';        
        $html .= '<select id="projectChosen" name="project">';
        foreach($this->projects as $p) {
            $selected = ($p->id == $this->project_id) ? 'selected="selected"' : '';
            $html .= '<option value="' . $p->name .'" '. $selected . ' >' . $p->name . '</option>';
        }
        $html .= '</select><br>';

        $html .= 'Choix de la version : ';
        if (isset ($this->versions)){
            $html .= '<select id="versionChosen" name="version">';
            foreach($this->versions as $v) {
                $selected = ($v->id == $this->version_id) ? 'selected="selected"' : '';
                $html .= '<option value="' . $v->id .'" '. $selected . ' >' . $v->id . '</option>';
            }
            $html .= '</select>';
        }
        $html .= '</div>';
        return $html;
    }
}
jQuery(document).ready(function($) {

    $('#projectChosen').on('change', function () {
        jQuery.ajax({
            type: "POST",
            url: ajax_object.ajaxurl,
            data: {
                'action': 'setProjectChosen',
                'demo_projet_name': $('#projectChosen option:selected').val()
            },
            success: function (output) {
                $('#contentDemoConnecteurs').replaceWith(output);
            },
            error: function(errorThrown){
                console.log(errorThrown);
            }
        });
    } );
} );
Adrian Cobo
  • 163
  • 1
  • 10
ninagath
  • 369
  • 2
  • 15