• Resolved davidsimon14

    (@davidsimon14)


    Hey guys,

    I want to include a custom code into a page with dynamic selects. I am using code snippets plugin to write PHP. But I am stuck right now with a 400 ajax error when I try to select a value.

    Here’s my php code:

    add_shortcode('choix_produits', 'wpcode_elementor_shortcode');
    
    function wpcode_elementor_shortcode($atts) {
    	global $wpdb;
    	$admin_url = admin_url( 'admin-ajax.php' );
    	echo '<form 
            action="$admin_url" 
            method="post" 
            class=""
        >';
    	
    	echo '<select name="marques" id="marques">';
    
        $results = $wpdb->get_results("SELECT distinct(marque) FROM wpfir_module_bougies;");
    
        if ($results) {
            foreach ($results as $row) {
                echo '<option value="' . esc_attr($row->marque) . '">' . esc_html($row->marque) . '</option>';
            }
        } else {
            echo '<option value="">Aucune donnée trouvée</option>';
        }
        
    	echo '</select>';
    		
    	echo '<select name="modeles" id="modeles"><option value="">Sélectionnez un modèle</option></select>';
    	
    	echo '</form>'; 
    	
    	add_action('wp_ajax_get_modeles', 'get_modeles_callback');
    	add_action('wp_ajax_nopriv_get_modeles', 'get_modeles_callback');
    
    	// Ajout du script
        wp_register_script('script_bougies', content_url() . '/plugins/bougies/script_bougies.js', array('jquery'), '1.0', true);
    	wp_localize_script('script_bougies', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
        wp_enqueue_script('script_bougies');
       
    
    
    	function get_modeles_callback() {
    		$marque_selected = $_POST['marque'];
    		error_log("marque : ".print_r( $marque_selected, true ) );
    		$modeles = $wpdb->get_results("SELECT distinct(modele) FROM wpfir_module_bougies where marque=$marque_selected;");
    
    		/*if ($results) {
    			foreach ($results as $row) {
    				echo '<option value="' . esc_attr($row->modele) . '">' . esc_html($row->modele) . '</option>';
    			}
    		} else {
    			echo '<option value="">Aucune donnée trouvée</option>';
    		}*/
    
    		if ($modeles) {
    			$options_html = '';
    			foreach ($modeles as $modele) {
    				$options_html .= '<option value="' . $modele . '">' . $modele . '</option>';
    			}
    		}else {
    			echo '<option value="">Aucune donnée trouvée</option>';
    		}
    
    		echo $options_html;
    		wp_die();
    	}
    	
    
    }

    At first, I placed my jquery inside the elementor page where I imported my short_code, but reading a lot of stuff here and there, I placed it inside the plugin directory:

    jQuery(document).ready(function ($) { 
        $('#marques').on('change', function() {
            var marqueSelected = $(this).val();
    
            $.ajax({
                url: ajax_object.ajax_url,
                type: 'POST',
                data: {
                    action: 'get_modeles', 
                    marque: marqueSelected
                },
                success: function(response) {
                    $('#modeles').html(response);
                },
                error: function(xhr, status, error) {
                    console.error(status + ': ' + error);
                }
            });
        });
    });

    Can someone tell me what I am doing wrong? Would be great to get some pointers, developing alone is lonely sometimes ??

    Thanks!

    The page I need help with: [log in to see the link]

Viewing 6 replies - 1 through 6 (of 6 total)
  • It looks like you’re on the right track with your code, but encountering a 400 AJAX error can be frustrating. Let’s go through some potential issues and solutions:

    1. AJAX URL in Form Action: In your PHP code, you’re echoing the $admin_url inside a single-quoted string, which means it won’t parse the variable. Change the single quotes to double quotes around the action attribute in your form tag.php

    echo "<form action=\"$admin_url\" method=\"post\" class=\"\">";

    AJAX Data Type: Ensure that your AJAX request in jQuery is sending data in the correct format. It’s good practice to specify the dataType in the AJAX call. Since you’re expecting HTML in response, you could add dataType: 'html'.

    $.ajax({ url: ajax_object.ajax_url, type: 'POST', dataType: 'html', data: { action: 'get_modeles', marque: marqueSelected }, ... });

    Escaping and SQL Injection: In your get_modeles_callback function, you are directly using the POST variable in your SQL query. This is vulnerable to SQL injection. You should escape and sanitize the input. Also, make sure you are using prepared statements.

    $marque_selected = esc_sql($_POST['marque']);

    $modeles = $wpdb->get_results($wpdb->prepare("SELECT distinct(modele) FROM wpfir_module_bougies where marque = %s", $marque_selected));

    Error in Callback Function: In your callback function, the foreach loop is iterating over $modeles but you are using $modele instead of $modele->modele. Update the loop accordingly.

    foreach ($modeles as $modele) {
        $options_html .= '<option value="' . esc_attr($modele->modele) . '">' . esc_html($modele->modele) . '</option>';
    }
    Thread Starter davidsimon14

    (@davidsimon14)

    Hey @wpprovider

    Thanks a lot for taking the time to detect and fix all these issues!

    Unfortunately, after fixing everything, the 400 error is still there :'(

    Cheers,

    Moderator bcworkz

    (@bcworkz)

    I don’t think PHP can properly read the default or HTML data types being sent. Try using dataType : 'json',. This is to format the data sent as JSON, it does not impact the returned response data type, that’s up to your PHP code.

    Thread Starter davidsimon14

    (@davidsimon14)

    Hey guys,

    I changed my code with all your answers, but the error persists. I also added a nonce… Here is what I have now:

    add_shortcode('choix_produits', 'wpcode_elementor_shortcode');
    
    function wpcode_elementor_shortcode($atts) {
    	global $wpdb;
    	$admin_url = admin_url( 'admin-ajax.php' );
    	echo "<form action=\"$admin_url\" method=\"post\" class=\"\">";
    	
    	echo '<select name="marques" id="marques">';
    
        $results = $wpdb->get_results("SELECT distinct(marque) FROM wpfir_module_bougies;");
    
        if ($results) {
            foreach ($results as $row) {
                echo '<option value="' . esc_attr($row->marque) . '">' . esc_html($row->marque) . '</option>';
            }
        } else {
            echo '<option value="">Aucune donnée trouvée</option>';
        }
        
    	echo '</select>';
    		
    	echo '<select name="modeles" id="modeles"><option value="">Sélectionnez un modèle</option></select>';
    	
    	echo '</form>'; 
    	
    	$nonce = wp_create_nonce('my_nonce_action');
    
    	// Ajout du script
        wp_register_script('script_bougies', content_url() . '/plugins/bougies/script_bougies.js', array('jquery'), '1.0', true);
    	wp_localize_script('script_bougies', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php'),'nonce' => $nonce));
        wp_enqueue_script('script_bougies');
    
    
    	function get_modeles_callback() {
    		$marque_selected = esc_sql($_POST['marque']);
    		//error_log("marque : ".print_r( $marque_selected, true ) );
    		$modeles = $wpdb->get_results($wpdb->prepare("SELECT distinct(modele) FROM wpfir_module_bougies where marque = %s", $marque_selected));
    
    		if ($modeles) {
    			$options_html = '';
    			foreach ($modeles as $modele) {
       				$options_html .= '<option value="' . esc_attr($modele->modele) . '">' . esc_html($modele->modele) . '</option>';
    			}
    		} else {
    			echo "<option value=''>Aucune donnée trouvée</option>";
    		}
    		
    		
    
    		echo $options_html;
    		wp_die();
    	}
    		
    	add_action('wp_ajax_get_modeles', 'get_modeles_callback');
    	add_action('wp_ajax_nopriv_get_modeles', 'get_modeles_callback');
    
    }
    jQuery(document).ready(function ($) { 
        $('#marques').on('change', function() {
            var marqueSelected = $(this).val();
    
            $.ajax({
                url: ajax_object.ajax_url,
                type: 'POST',
    			dataType: 'json', 
                data: {
                    action: 'get_modeles', 
                    marque: marqueSelected,
    				nonce: ajax_object.nonce
                },
                success: function(response) {
                    $('#modeles').html(response);
                },
                error: function(xhr, status, error) {
                    console.error(status + ': ' + error);
                }
            });
        });
    });

    Any way I can debug it step by step?

    It’s great to see that you’ve made several improvements to your code, but it’s indeed frustrating when the issue persists. Debugging step by step is a good approach here. Let’s consider some steps and additional aspects to focus on:

    1. Check Console for Detailed Error Information: The browser’s developer console can provide more specific details about the 400 error. This can sometimes indicate what exactly is causing the problem, such as a missing parameter or a formatting issue.
    2. Verify AJAX Request and Response: Ensure that your AJAX request is correctly formatted and that the server is receiving it as expected. You might want to log the entire request on the server side to see if everything is being passed correctly.
    3. Nonce Verification: Since you’ve added a nonce, make sure it’s being verified in your get_modeles_callback function. Lack of or incorrect nonce verification can lead to a 400 error. Add this to the start of your callback function:

    if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'my_nonce_action') ) { wp_die('Nonce verification failed!'); }

    Check Response Format: You’ve changed dataType to ‘json’, but your PHP callback seems to be returning HTML. Ensure that the response from the server matches the expected dataType. If you’re returning HTML, use ‘html’ as the dataType; for JSON, the server response should be a JSON object.

    Inspect Network Requests: Use the Network tab in your browser’s developer tools to inspect the AJAX request. This can show you the exact data being sent to the server and the server’s response. Check if the request headers, parameters, and body are as expected.

    Error Logging: Utilize error_log() in your PHP code to log various steps in your callback function. This can help pinpoint where the process is failing.

    AJAX URL and Path: Double-check the AJAX URL and make sure it’s correctly pointing to admin-ajax.php. Sometimes path issues can cause unexpected errors.

    Test with Simplified Code: Temporarily simplify your AJAX handler to return a static response. This can help determine if the issue lies in the AJAX setup or the specific PHP code handling the request.

    WordPress Environment Check: Ensure that there are no conflicts with other plugins or themes that might be affecting AJAX functionality.

    Enable WP_DEBUG: If not already done, enable WP_DEBUG in your WordPress configuration to see if there are any relevant error messages.

    if you follow these approach we can narrow the source of the 400 error

    Thread Starter davidsimon14

    (@davidsimon14)

    I managed to fix it.

    The problem was that I was declaring my scripts and ajax handlers inside my short code. I needed to declare them either inside the plugin or functions.php.

    Thanks all!

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Custom code: admin-ajax.php 400 (Bad Request)’ is closed to new replies.