How to post a form using AJAX?

I need to submit the registration form using AJAX and retrieve the response using AJAX. I am looking through documentation and through comments in discussion and still can't understand. It seems that everybody somehow know how to do it and they only have minor questions. I looked for plugins that do similar things but the only one that I found is about elgg 1.7

Is there any tutorial or code example how to create forms views to be retrieved with AJAX, post them with AJAX and return a json response instead of forward(REFERER);

  • Using ajax in elgg is almost same as that with regular webpages. You can take a look at following plugins to learn about it

    1. Core messageboard plugin - https://github.com/Elgg/Elgg/blob/1.x/mod/messageboard/views/default/messageboard/js.php
    2. Ajax comments - https://community.elgg.org/plugins/881922/1.2/ajax-comments
  • Thank you. I saw the Ajax comments plugin. I understand how to make the ajax request with javascript and how to expect it and what to do with it afterwards. My main confusion is on the server. I have no idea how to handle the request in the server. 

    My problem at hand right now is the registration form. I need to load it in a <div> in the page and when the form is submitted I don't want the whole page to be reloaded. Just the contents of that <div>.

    So far I have registered my own page handler for that form and loaded the form in that div. Now I need to submit the form somewhere using ajax.

    The default in elgg is 'action/register'. Without ajax i just handles the registration, get's interrupted by event's and hooks and completes the registration. Do action handlers have to do something special to handle ajax calls? Do I have to override the default or it should just work?

    Also I see that on success it calls forward() and in the end it calls forward(REFERER). I am not sure what this function does and I couldn't understand from it's description (total noob here :D). I guess it is the function responsible for browser redirect after the form submission. Instead of this I need a json response to notify the browser that registration is ok. No redirection. Javascript will handle the UI. Again, do I have to override that action and remove the calls to redirect and maybe replace them with a function to display the registered error messages as json and send them back?

    Finally how do I send an AJAX response from the server? 

    Thank you for your help.

     

     

  • Thanks for doing all the research beforehand.

    You do not need to replace the register action. There is a hook handler registered for 'forward','all' that checks if the action was requested via AJAX (elgg_is_xhr()) and instead of issuing a redirect, server a JSON response with what's in the output buffer (including status and system messages).

    There are two ways to submit your form via ajax, I am assuming you are using 1.8.

    Option 1. Submit with jquery form plugin

    In your php, elgg_load_js('jquery.form');

    In your js,

    $('.elgg-form-register').ajaxForm({

      success: function(response) {

        if (response.status >= 0) {  // -1 is error status ode

         // registration succeeded

         // do stuff here 

       }

      }

    });

     

    Option 2. Using elgg.action

    $('.elgg-form-register').live('submit', function(e) {

       e.preventDefault();

       var $form = $(this);

       elgg.action($form.attr('action'), {

         data: $form.serialize(),

        success: function(data) {

          // check the status and do stuff

        }

       });

       return false; // prevent the form from submitting

    });

  • Thanks. It works. I am using dojo for javascript and it works great. But still I don't understand how server side works. I try to study the profile fields plugin but I can't even find where it does it's magic.

    Let's say that I want to validate live if the username is available. So I register a page handler for something like

    elgg_register_page_handler('actions/check_user', 'verify_uname_page_handler');

    And in that page handler there is a check if the username exists and if it exists then it returns a json response. What  are the proper steps for this?

    Also can you please point me in the code where that hook handler is registered and where the output management is done?

    Please don't think I am lazy for asking this, I don't know where to look first.

  • You want to register the action (in this case you've named the action 'check_user')

    elgg_register_action('check_user', __DIR__ . '/actions/check_user.php', 'public');

    the parameters are the name of the action, the path to the action file (where your logic is), and a permissions flag (which defaults to logged in users, but in this case you would want it public).

    In your action file you can get your username with something like

    $username = get_input('username');

    // some checking

    echo 'some output, will be available in the returned json';

  • Thank you Matt. I reread what I wrote and the meaning is totally different from what I intended to write.  Ismayil Kharedinov wrote that  there is a hook handler registered for 'forward','all' that checks if the action was requested via AJAX (elgg_is_xhr()) and instead of issuing a redirect, server a JSON response with what's in the output buffer (including status and system messages).

    My question was where in the code is this hook handler registered and where in the code is made the decision if the return is going to be a json or something else. Do I have to also register for that hook in my plugin or it is taken care automatically? I was hopping that if I read that code maybe I can understand how it works and how to construct my own custom json responses.

    Update: It seems I have confused things a little bit. From what I begin to understand, to get a custom json I need to use elgg_register_ajax_view($view) which is irrelevant with posting forms and actions, thus irrelevant with this topic. 

  • The hook handler in question is registered automatically in core: https://github.com/Elgg/Elgg/blob/1.8/engine/lib/actions.php#L546

    Could you perhaps spell out a step-by-step of what you are trying to do?

  • Thanks for your answer. What I am trying to do is in my form to have the username field to be checked for availability and validated against a list of disallowed usernames. Then the browser would get a json response like {isValid:true}. Then that form will be submitted with AJAX to proceed with registration. 

    My main problem was: how to return a json with the response?.

    I did some more digging through various plugins and I think I am beginning to understand how it works. With POST I just have to make a request and elgg magically decides to return a json.  If that action uses register_error() then the action has failed and the response has status -1. The errors array that is returned to the browser, can be as complex as we want using arrays. On success it returns 0. I still don't know how to return a custom json but at this point I don't need it.

    But I have one more question. In the object that is returned to the browser the system_messages->error[] array is populated with register_error(). What is the equivalent for success?

  • You can echo your custom json in your action:

    if (elgg_is_xhr()) {
    echo json_encode($my_array);
    }
    forward();

  • In php:
    system_message('Your action was successful');
    register_error('Your action failed');

Beginning Developers

Beginning Developers

This space is for newcomers, who wish to build a new plugin or to customize an existing one to their liking