This is a common question. It plagued me when I first started because it doesn’t make any sense and it is hard to search for until you know. The problem is that WordPress bundles a version of jQuery that is set to noConflict mode. Therefore, to run scripts you must use noConflict wrappers
jQuery(document).ready(function($) {
// Inside of this function, $() will work as an alias for jQuery()
// and other libraries also using $ will not be accessible under this shortcut
});
Update
-
There’s no need to load a different version of jQuery. It just complicates things. Let, WordPress load it’s own version. Delete your
jquery_enqueue()
method. -
Next adjust your
create_admin_page()
to not print the script directly. What I think is happening is thatadd_menu_page()
runs beforewp_enqueue_scripts
and so jQuery isn’t available yet. Hence, error. Instead of printing the scripts, you can print them in the footer by adding a new function to theadmin_print_footer_scripts
hook.
So modified, your create_admin_page()
would now look like this:
public function create_admin_page()
{
// Set class property
$this->options = get_option( 'my_option_name' );
add_action( 'admin_print_footer_scripts', array( $this, 'footer_scripts' ) );
?>
<div class="wrap">
<h2>Test</h2>
<form method="post" action="options.php">
<?php
// This prints out all hidden setting fields
settings_fields( '...' );
do_settings_sections( '...' );
?>
</form>
<textarea></textarea>
</div>
<?php
}
With your new function being:
public function footer_scripts()
{ ?>
<script>
jQuery( document ).ready(function($) {
$( "#my_option_name" ).change(function() {
$.post(
'classes/dummy.class.php'
).success(function(x){
json = $.parseJSON(x);
$('textarea').text(json);
});
});
});
</script>