WordPress.org

Ready to get started?Download WordPress

Forums

TinyMCE + AJAX (11 posts)

  1. nusi
    Member
    Posted 1 year ago #

    Hello,

    I've written a custom TinyMCE plugin that gives me one more button which, when clicked, opens a modal window, allowing me to select images from my uploads, that can then be added as custom gallery in my post. I.e. by clicking the submit button a shortcode containing the ids of the selected images gets entered into the text of my post. So far, so good. That works as desired.
    Now I'm trying not only enter the shortcode but also add a meta-value when clicking 'submit'. Basically submitting my selection is done by the usual JavaScript-mechanism (no update to the database - just a string get added to the text). As there's no php-action involved I thought I could do this with AJAX. The function looks like this:

    function ajaxSubmit(id, argstring) {
    	jQuery.post("../../add_post_meta.php", {
    		post_id: id,
    		key: 'bildstrecke',
    		val: 'true',
    		unique: 'true',
    		security: '<?php echo $ajax_nonce ?>'
    	}).success(function() {
    		window.tinyMCE.execInstanceCommand('content', 'mceInsertContent', false, "[bildstrecke imgs=\""+argstring+"\"]");
    		tinyMCEPopup.editor.execCommand('mceRepaint');
    		tinyMCEPopup.close();
    	}).error(function(e, x) {
    		console.log([e, x])
    	});
    	return false;
    }

    'add_post_meta.php' containes some php-code that adds the meta-value to the database. However, executing the above function results in an unspecified error resp. the call to 'add_post_meta.php' doesn't get executed properly (in the console I see the call to the script but don't get the right response - I see the script being called but only a forever rotating process-wheel appears).

    Is there anything obvious that I'm doing wrong?

    Thanks for any hint,

    Stefan

  2. bcworkz
    Member
    Posted 1 year ago #

    WP ajax requests should be routed through wp-admin/admin-ajax.php. The .post() data array must then contain an {action: "tag_name"} element which in part defines an action to hook to handle the php side of the ajax request. See AJAX in Plugins for specific details

  3. nusi
    Member
    Posted 1 year ago #

    Thanks for the reply. At first sight AJAX in Plugins seemed to be the missing reference that I was looking for but after playing around with what's described on the page I'm still stuck.
    Just to make it clear once again - I'm not writing a wordpress plugin. I've written a TinyMCE plugin, following this tutorial. That means my jQuery/AJAX functionality exists within a custom HTML-page. Obviously that page doesn't know anything about a global 'ajaxurl' variable. Nevertheless it's no problem to reference wp-admin/admin-ajax.php directly (hardcoded).
    But how can I get wp-admin/admin-ajax.php to execute my desired action (add a meta-value to the database)? Hooking up an action with add_action (from within the same page) doesn't seem to have any effect. I'm obviously missing something that isn't mentioned on AJAX in Plugins. Though the 'ajaxurl' variable doesn't exist on my (custom) page I can see usual wp functionality is working (e.g. I can create a 'nonce' value with wp_create_nonce("nonce")). (Again, I don't want to write a wordpress-plugin - I'm just extending the functionality of my theme).

    Any clues?

  4. bcworkz
    Member
    Posted 1 year ago #

    The AJAX in Plugins reference leaves a lot to be desired, it's not too surprising you've hit a snag. I think your only issue is the add_action() hook may not be executed in time for your page to use it, though if called in the right place, it should be possible. To ensure it is in place when your page needs it, you could add it to your theme's functions.php file. But if you are using a packaged theme, you should create a child theme to protect your modification from theme upgrades.

    You could also create a very simple WordPress plugin which would contain the code. It's really just a matter of putting a properly formatted comment at the top of your code page and adding the page to a folder you create in the plugins folder. It's a good place to keep various custom code you may end up creating here and there.

    If you still are having trouble, post what code you have here or on pastebin.com if it's long. Perhaps someone here will see the glitch and set you straight.

  5. nusi
    Member
    Posted 1 year ago #

    Thanks for the reply! If I understand correctly what I did wasn't that wrong. First I tried to execute the 'add-action' part from within my custom page (the one within my modal window). However I only did that for the function that was supposed to be executed within wp-admin/admin-ajax.php. The other action, containing the jQuery-JavaScript part (jQuery.post(...)) was just written into the header of my page (I can see on the console that it's being executed. I didn't bother much for the 'ajaxurl' not being recognized. I just used hardcoded the path to wp-admin/admin-ajax.php).

    Also I tried to put the 'add_action' call into functions.php within my theme (it's a thematic-childtheme). However that didn't have the desired effect either. As a consequence I digged a bit deeper into the docs in order to get a better understanding on how 'add_action' basically works. I finally found this page which documents the existing action-hooks. Interesting

  6. nusi
    Member
    Posted 1 year ago #

    (Sorry, the previous post accidentally got posted before it was finished...)

    Interestingly I found 'admin_print_scripts' but not 'wp_ajax_my_action', so I did a quick grep through the sources which revealed that the hook indeed isn't defined anywhere (maybe it is in 3.5.x but I'm hesitant to upgrade from 3.4.2 due to a plugin that hasn't been updated to 3.5.x yet).

    Is it possible (or even necessary in this case) to define a custom action-hook ahead from using it in an 'add_action' call?

    Last but not least here's my code:

    window.php (the page within my modal window. Irrelevant parts stripped off): http://pastebin.com/TUxPegB0

    Thanks again for your support!

    P.s.: If it all doesn't work out it's not a big drama as my AJAX-functionality only adds a meta-value that can also be created manually. However, it's essential that the user creates the meta-value as it determines whether a not so small chunk of JavaScript shall be loaded with the page (e.g. the jQuery library) and also that JS has some unwanted sideeffects on regular pages.

  7. nusi
    Member
    Posted 1 year ago #

    p.p.s.: I know know why I didn't find 'wp_ajax_my_action' documented: https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)

    ... but maybe there's something else I'm doing wrong

  8. nusi
    Member
    Posted 1 year ago #

    ... and sorry once again for posting my last reply twice - I got a 'bad gateway' error but obviously posting worked...

  9. bcworkz
    Member
    Posted 1 year ago #

    I think your only real problem is understanding how the custom action gets named. You want your jQuery action value to only be "my_action". Based on that, WP appends it to the prefix "wp_ajax_", thus you add the action "wp_ajax_my_action". The variable portion is why you couldn't grep it. But if there is no logged in user, note that WP prefixes "wp_ajax_nopriv_" instead. So if the ajax call should work for both logged in and not logged in, you need to add both actions to the same handler function.

    A couple other things I noticed. You should require_once wp-load.php instead of require wp-config.php to files that are directly linked. If this were part of a plugin or theme, you don't need this at all.

    You should use wp_enqueue_scripts() to reference javascripts. It ensures dependencies are handled properly and avoids conflicts. Then you can use wp_localize_script() to easily pass values from php to your enqueued scripts. For one thing, you won't have to hard code the ajax url, you can use admin_url() or whatever in php, then pass it to the jquery function in a variable.

  10. nusi
    Member
    Posted 1 year ago #

    Well, as I wrote earlier I already found out why I didn't find 'wp_ajax_my_action' by grepping through the sources. However, I followed your advice and also tried 'wp_ajax_nopriv_(my_action)' which didn't change anything. Basically I believe 'wp_ajax_' is the right hook as the user has to be logged in when opening the page (there's a check for that at the beginning of my code).

    Out of curiosity I added the 'add_action' call in both, my custom page and functions.php within my theme. That resulted in an error 'Cannot redeclare add_post_meta_bs() (previously declared in ... /window.php' which leads me to the assumption that the call basically works ok (of course I can't redeclare it - it's php...).

    Regarding wp_enqueue_scripts(): If I understand the documentation correctly that's supposed to be used only for frontend pages. In the backend resp. admin-area one should use admin_enqueue_scripts(). However, I don't really think that causes a problem here - all of my JavaSripts are basically working as they should besides that AJAX thing (there's quite a lot of JS functionality on that page which I simply stripped out for the sake of conciseness). Also, I am already on the page into which I'm embedding those JavaScripts - how should wp_enqueue_scripts() or admin_enqueue_scripts() be used here? (once again, it's a custom page that's quite a bit different from other admin pages like post.php, edit.php or whatever).

    So, I'm still at the point of not getting a response after wp-admin/admin-ajax.php got called. I can see in the console what got sent and jQuery.post().success().error() gives me
    Object { readyState=0, status=0, statusText="error"}
    but no response like I get e.g. from the autosave-process which also calls wp-admin/admin-ajax.php.

    I think I'll give up if some lucky coincidence doesn't reveal the real source of my problem. Very possible that I should have done it all differently, rather following the standard wordpress-way of building admin-pages. But I simply don't have the time for that and my client won't pay the extra effort. It's not a big drama.

    Thanks again for your patience and attention to my little problem. Maybe I'll find a solution one day and I'll be able to help others when going through the same.

    Stefan

  11. bcworkz
    Member
    Posted 1 year ago #

    Basically I believe 'wp_ajax_' is the right hook as the user has to be logged in when opening the page

    Just to make sure we're communicating, the correct call remains
    add_action('wp_ajax_my_action', 'add_post_meta_bs');
    The correct .post data is:

    { action: 'my_action', /*<<<<< This is what's important */
                    post_id: id,
                    key: 'bildstrecke',
                    val: 'true',
                    unique: 'true',
                    security: '<?php echo $ajax_nonce ?>'
    }

    It's not clear you actually tried that combination.

    Yes, the nopriv variant is useless if your page only runs for logged in users. Did you try commenting out you page's call to add_action() when you put it in functions.php? (Probably doesn't matter anyway) And you're right about admin enqueue, my head was in the wrong context, apologies. The enqueue functions are not essential to the proper functioning anyway, just a preferred practice. All they do is echo out the link tags similar to what you have already, so they can be used in any <head> section. The reason for preferring their use is some dependencies are resolved which helps prevent conflicts. Also, a different avenue is available to pass PHP values to javascript. No big deal.

    Which could be extended to doing anything the "WordPress Way". No reason one can't use a different approach, but WP does things a certain way for a reason, but it's not a big deal.

Topic Closed

This topic has been closed to new replies.

About this Topic