PHP called from javascript only half-working
I've written a little module to do a real-time check of whether an email address entered during checkout is subscribed to the site's newsletter (using simplenews, at least to maintain the list) in order to get a discount.
So far I have gotten the AJAX to work, it sends and receives OK.
The PHP all works, too. I have tested all the functions from other modules and the email address search works.
The trouble is that the email search will not run when I run it from javascript. I don't know if Drupal won't allow certain functions or ...?
I've spent over 8 hours trying to figure out what is going on here but still don't understand. The function that seems to be hanging the JS is simplenews_subscription_list_form().
What could be the trouble?
Javascript:
$(document).ready(function() {
$('.peaks-member').hide();
$('.non-peaks-member').hide();
// Drupal.attachBehaviors(check_user);
$('#edit-panes-email-address-primary-email').blur(function() {
$.ajax({
type: 'POST',
url: Drupal.settings.basePath + "?q=peaksclub/check",
dataType: 'json',
data: {
email: $('#edit-panes-email-address-primary-email').val()
},
success: function(data) {
if (data.member === true) {
$('.non-peaks-member').hide();
$('.peaks-member').show();
}
if (data.member === false) {
$('.peaks-member').hide();
$('.non-peaks-member').show();
}
}
});
return false;
});
});PHP:
/**
* Implementation of hook_menu().
*/
function simplenews_modifications_menu() {
$items = array();
$items['peaksclub/check'] = array(
'page callback' => 'simplenews_modifications_member_check',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function simplenews_modifications_member_check() {
$email = $_POST['email'];
$results = array();
$results = simplenews_modifications_list_search($email);
if ($results) {
$return['member'] = true;
}
else {
$return['member'] = false;
}
print drupal_to_js((array)$return);
}
/*
* Actually searches the newsletter subscriber list pull from simplenews
*/
function simplenews_modifications_list_search($email) {
$list = simplenews_subscription_list_form();
foreach ($list['mail'] as $address) {
if (in_array($email, $address)) {
$results['member'] = true;
return $results;
}
}
}
For the most part, everything
For the most part, everything looks ok. But I'm thinking the problem may be here:
url: Drupal.settings.basePath + "?q=peaksclub/check",You can do this a different way. Rather than declaring the URL in the javascript, you pass it as a setting from your php. You didn't show us the function/page that you are using to create your form using the form API, but wherever it is, you are attaching the javascript file that you showed us above. Add this to that file:
<?php$simplenews_modifications_js_settings = array
(
'callbackURL' => url('peaksclub/check', array('absolute' => TRUE)),
);
drupal_add_js(array('simplenewsModifications' => $simplenews_modifications_js_settings), "setting");
?>
This will pass the absolute URL for the callback function to your javascript file. You can then change this:
url: Drupal.settings.basePath + "?q=peaksclub/check",to this:
url: Drupal.settings.simplenewsModficiations.callbackURL,Since the URL is generated serverside each time as an absolute URL based on the site root, paying attention to whether you have clean urls enabled or not, and then is passed to the javascript file as a setting, you will definitely have the correct URL.
One other thing may be this:
$(document).ready(function() {
$('.peaks-member').hide();
$('.non-peaks-member').hide();
// Drupal.attachBehaviors(check_user);
$('#edit-panes-email-address-primary-email').blur(function() {
$.ajax({
type: 'POST',
url: Drupal.settings.basePath + "?q=peaksclub/check",
dataType: 'json',
data: {
email: $('#edit-panes-email-address-primary-email').val()
},
In Drupal 6 you don't use $(document).ready(function() as you normally do with jquery, rather you attach it as a drupal behavior. So change this:
$(document).ready(function() {to this:
Drupal.behaviors.simplenewsModifications = function()This adds your ready function to the Drupal object (actually, the Drupal.behaviors object), and it gets called automatically with all the other ready functions in its own ready statement. As long as you add it to your own namespace (simplnewsModifications) it will prevent any conflicts.
You can read more about the javascript API here.
Also, if you find it is still not working, install the firebug plugin for firefox, run your script using firefox with that plugin enabled, and check to see if you have any javascript errors.
Ok, I spent some time
Ok, I spent some time implementing those changes and the problem persisted. I could get to PHP but this one function would not run.
In the past when javascript would have an error there would be a big red error message in the lower right of my browser. Since there was no red dot, I figured everything was failing silently.
I noodled around and found that console window, and lo and behold, there is my script, and the error that it threw was that there was a call to an undefined function, the very function that was mucking things up.
I thought it was odd because it's always been the case that all module functions are available to all other module functions.
I put in a require_once() above the line that called the function in another module and fired the whole thing up.
It worked!
Thanks for helping out. Those 2 suggestions are a pretty neat way to shift data back and forth between drupal and js, but it was the offhand firebug remark that actually got me to thinking there may be more down there.
Goodbye 12 hours of my day and hello working stuff!
I'm glad it got solved, even
I'm glad it got solved, even though it wasn't my code suggestions that did it! But either way, those code practices are the standard way of working with the Drupal 6 API, so hopefully they can help you out in the future!