3

I want to directly pass POST data to my .php file which is located in my module folder. I know this is security risk, but I'll try to fix that later.

I'm doing research on this subject - how to do it with out using any components, so please don't suggest me com_ajax.

default.php

//defined('_JEXEC') or die; 
<form method="post" name="form1">
            <input type="checkbox" name="checkboxList[]" value="1">value1</input>
            <input type="checkbox" name="checkboxList[]" value="2">value2</input>
            <input type="checkbox" name="checkboxList[]" value="3">value3</input>
</form>

<script>
 jQuery(document).ready(function(jQuery){

   jQuery("input[type='checkbox']").on("change",function(){
    if(jQuery(this).is(":checked"))
    {
         var checkboxdata=[];

         jQuery("input[type='checkbox']").each(function(){

                  if(jQuery(this).is(":checked"))
                            {
                            checkboxdata.push(jQuery(this).val());
                            }

                  })

         var data = checkboxdata;
         jQuery.ajax({
             url: '/modules/mod_test/respond.php',
             type: 'POST',
             async: true,
             cache: false,
             data: data,
             success:function(r){
                    alert(data); 
             }
         })
    }
})

});

</script

On every tick in checkbox - I get alerted by data (so far all good!).

respond.php (custom php file I want to have direct access - send POST data with ajax)

<?php
print_r($_POST);
?>

UPDATE: [jamesgarrett]

default.php

<form method="post" action="" name="form1" id="mycustomform">
<input type="checkbox" name="checkboxList[]" onclick="function1();" value="1"> Apple</input><br>
<input type="checkbox" name="checkboxList[]" onclick="function1();" value="2"> Pineapple</input><br>
<input type="checkbox" name="checkboxList[]" onclick="function1();" value="3"> Pen</input>
</form>
<div id="response"></div>

<script>
function function1() {
var data = jQuery("#mycustomform").serialize() + '&thisisajax=1';
jQuery.ajax({
    url: "<?php echo JUri::current(); ?>", 
    type: "POST",
    data: data, 
    success: function(response){ 
        response = jQuery.parseJSON(response);
        if(response.success === true){
           jQuery('#response').html(response.data);
        } else {
            alert('error');
        }
    }
});
}
</script>

helper.php

<?php

$jinput = JFactory::getApplication()->input;
$data = $jinput->post->get('checkboxList', [], 'array');
$ajax_test = $jinput->post->get('thisisajax', 0, 'int');

if($ajax_test){
$some_text = ['','Apple','Pineapple','Pen'];
$response = "";
foreach($data as $d){
    $response .= $some_text[$d] . " ";
}
echo new JResponseJson($response);
jexit();
}


class ModHelloWorldHelper
{
public static function getHello()
{

}
}

2 Answers 2

2

Here's a complete example for a module in 1 file, not bypassing Joomla, not using a component, running php function on async posted data, & running some js on the returned data (why not).

Use the testing only section to get your query working before dealing with your ajax request.

<?php 
defined('_JEXEC') or die;

// toggle this variable in order to show the results of the db query for testing purposes
$production = 0;

$jinput = JFactory::getApplication()->input;
$data = $jinput->post->get('checkboxList', [], 'array');
$ajax_test = $jinput->post->get('thisisajax', 0, 'int');

// = TESING ONLY ===================================================

if(!production){
    $data = [1,2,3];
    $ajax_test = 1;
}

// = END TESTING ONLY ===============================================

if($ajax_test){
    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query->select($db->quoteName('*'));
    $query->from($db->quoteName('#__custom_table'));
    $query->where($db->quoteName('custom_id') . ' IN (' . implode(",",$data) .')');
    $db->setQuery($query);
    $results = $db->loadObjectList();

    if(!production){
        echo "<pre>" . print_r($results,1) . "</pre>";
        die();
    }

    // PROCESS RESULTS HERE

    $response = 'xxx?';

    echo new JResponseJson($response);
    jexit();
}
?>
<form method="post" action="" name="form1" id="mycustomform">
    <input type="checkbox" name="checkboxList[]" onclick="function1();" value="1"> Apple</input><br>
    <input type="checkbox" name="checkboxList[]" onclick="function1();" value="2"> Pineapple</input><br>
    <input type="checkbox" name="checkboxList[]" onclick="function1();" value="3"> Pen</input>
</form>
<div id="response"></div>

<script>
function function1() {
    var data = jQuery("#mycustomform").serialize() + '&thisisajax=1';
    jQuery.ajax({
        url: "<?php echo JUri::current(); ?>", 
        type: "POST",
        data: data, 
        success: function(response){ 
            response = jQuery.parseJSON(response);
            if(response.success === true){
               jQuery('#response').html(response.data);
            } else {
                alert('error');
            }
        }
    });
}
</script>
7
  • Thank you. This is very useful! Is there some equivalent way to send ticked checkbox values to helper file (not by passing Joomla / hacking Joomla [ as long as it works ])? I want to put these values in special function and then fetch data based on checked values (if there are some) Apr 17, 2017 at 6:07
  • You can move the php from the top of the code provided into a helper file if you already have your module set up that way. Any part of your module that runs as part of the joomla request-response can take the ajaxed values from the jinput object, echo a suitable response and then exit before proceeding to the html output. The helper file is no different in this regard. Apr 17, 2017 at 6:42
  • 1. my recommendation is that you delete your helper.php file and your default.php file and keep the whole module in 1 file. If your module is called mod_test then just have 1 php file called mod_test.php. This will make things much easier for everyone trying to help. 2. I have edited the answer to show where I would put a call to the database. Apr 17, 2017 at 9:39
  • Well, I'll take under consideration your suggestions. Also, I do not see edited post version of yours. :/ Apr 17, 2017 at 9:44
  • Sorry. I was editing obviously while you were reading it. Apr 17, 2017 at 9:47
1

Tested your code and it works for me.

The things I changed were as follows, in case these are the issue:

  • Changed all references from $ to jQuery so that I don't have to worry about defining the jQuery object or any conflicts.
  • Added <script> tags around your javascript (though I assume you have just removed these for the sake of simplifying your question's code)
  • My test site was in a subfolder, so I had to update the AJAX call appropriately, so that it would load from the root.

If you go directly to the response.php URL in a browser, it should display "Array()". Is this the case?

As far as not suggesting com_ajax - that is going to be the right place to at least study to see how Joomla have built an ajax component. Once you break out of the framework, you aren't really building a Joomla site.

Update:

Array(
   [3] => 
)

Means that you have run print_r() on a string and not an array, and so that alert is exactly how it should be.

var data = jQuery(this).val();

is only sending the value of the box you have just checked - not the form data, not the name/value pair of the checkbox, just the value - the this at this point refers to the element you have just clicked on (ie the specific checkbox) and not the data of the whole form.

For the sake of a quick, hacky example (this is not a gread approach), replace var data = jQuery(this).val(); with the following, which will send an array of checkbox data.

  var checkboxdata=[];


  jQuery("input[type='checkbox']").each(function(){

          if(jQuery(this).is(":checked"))
                    {
                    checkboxdata.push(jQuery(this).val());
                    }

          })

   var data=  checkboxdata; 

Update 2

You need to read up on how AJAX works.

Each time you call a page via AJAX, it basically acts the same as if you submitted a form whose action points to that page (or loaded a page passing parameters in the URL). The only real difference is that the output is sent to your javascript function rather than printed on screen to the user.

Each time you call a page via AJAX, it is like re-submitting a form, or re-loading a page. As with re-submitting a form, it is not going to remember what has happened to it before unless you specifically code it to do so.

9
  • I updated my code in original post (added $ to jQuery). Seems like script works the same, but array is still null, when I print it out. 1) What did you mean by "update the AJAX call appropriately, so that it would load from the root". How is this done? You can see my path also in edit. 2) If I go joomla.dev/modules/mod_test/respond.php I get Array ( ); Same thing - array is empty. I really want to make sure that I fill up the array using ajax. Apr 16, 2017 at 10:39
  • The array path issue doesn't look relevent to you, as your site isn't in a sub-folder. I just meant that for me, I had to load from '/subfolder/modules/mod_test/respond.php'.
    – RichardB
    Apr 16, 2017 at 10:42
  • Are you testing the array response with alert(r); instead of alert(data)?
    – RichardB
    Apr 16, 2017 at 10:50
  • Going directly to the URL should return an empty one, as it hasn't been posted any data and there is no code to remember previous requests of the page. Have you tried building this outside of Joomla to make sure it isn't just some misunderstanding of how AJAX works? I can't actually see it being a Joomla issue.
    – RichardB
    Apr 16, 2017 at 10:55
  • 1
    Updated, but I suggest you go back to basics and learn first how forms work and then how AJAX works. The correct way in Joomla is ultimately com_ajax, but I suggest you take your script completely out of Joomla until you understand the theory in a simpler example.
    – RichardB
    Apr 16, 2017 at 13:24

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.