XenForo AJAX Tutorial

OK, here's a question... if I wanted to modify the contents of a <div> based on what is selected in a form, could I modify the original code to work for what I want? Because I am building the next version of BB Code Manager that'll support an arbitrary number of required options (gotta figure out help display for that...), and replaces it... However, the description setups that I'd want to set for the replacement fields, would be different.
It sounds like you just want to change some text based on the value of a form element (like a radio button)? If so, you should be able to bind a click event to input:radio[name=xxx], and inside the callback look at the checked value and update accordingly. Also see: http://api.jquery.com/val/
 
Aah yes, will do, sorry :)
Any update on this?
Adapted the javascript to an addon I'm working on as best I can using the non-HD video, but jQuery keeps spitting out errors. Would appreciate being able to look at the original for reference.
 
When i try to use ajax for a comment system (copied as it is from the user profile commenting system), when i click on "comment" i get back an "Unknow Error". The comment is inserted in the database (not in the user comment table, on a custom one) correctly, and the json reply for the request is ok but i get that error.
Any way i can debug it to find it out what it is?

Thank you.
 
The 'unknown error' thing seems to be new with beta 3 - we are still trying to track it down.

I'll post the source code tonight for anyone interested.
 
Just use a javascript debugger, for example firebug^^
I've yet to lear how to firebug to debug javascript... will try however ;)

The 'unknown error' thing seems to be new with beta 3 - we are still trying to track it down.

I'll post the source code tonight for anyone interested.
I'm actually using beta2, however i was wrong: it's not Unknow error, but Unspecified Error ;)
Thank you!
 
Kier... this guide was awesome... my question now is how to get this working with input forms...

I got basic AJAX page loading and replacement working here:
http://xen1.8wayrun.com/media/nicovideo-test-video.6/

Using the page navigation tabs, you will see that the comments change on each click. However, if someone posts a comment, it still refreshes the page. How would I go about processing the AJAX for the submit form? I basically just want it to post the comment, and then refresh the CommentList. With the pagenav, I am refreshing the comment list as follows:

Code:
/** @param {jQuery} $ jQuery Object */
!function($, window, document, _undefined)
{
	XenForo.CommentFeedLoader = function($link)
	{
		$link.click(function(e)
		{
			e.preventDefault();
			var oriurl = $link.attr('href').split('?');
			var newurl = oriurl[0] + "comments/?" + oriurl[1];

			XenForo.ajax(
				newurl,
				{},
				function(ajaxData, textStatus)
				{
					if (ajaxData.templateHtml)
					{
						new XenForo.ExtLoader(ajaxData, function()
						{
							$(ajaxData.templateHtml).xfInsert('replaceAll', '#mediaComments', 'xfShow');
						});
					}
				}
			);
		});
	}

	// *********************************************************************

	XenForo.register('#CommentFeed div.PageNav a[href]', 'XenForo.CommentFeedLoader');
}
(jQuery, this, document);

As you can see, the most important part of the function is the way it generates "newurl". It takes the link url, splits it before the question mark, and adds "comments/" before it.
 
Thanks Kier... these guides are great... I managed to get the form validator working... I just have a few followup questions... First of all, how does the system handle multiple submissions? For instance, with the way I have it now, if I rapid click the submit button, there will be several submissions, instead of just one. Secondly, how would I empty the contents of the message textarea; the code I have below isn't working.

Code:
    XenForo.CommentPoster = function($form)
    {
        $form.bind('AutoValidationComplete', function(e)
        {
            $form.find('input:submit').blur();
            $form.find('textarea[name="message"]').val('').blur();

            if (e.ajaxData.status)
            {
                $('#CommentStatus').text(e.ajaxData.status);
            }

            XenForo.ajax(
                e.ajaxData.newurl,
                {},
                function(ajaxData, textStatus)
                {
                    if (ajaxData.templateHtml)
                    {
                        new XenForo.ExtLoader(ajaxData, function()
                        {
                            $(ajaxData.templateHtml).xfInsert('replaceAll', '#mediaComments', 'xfShow');
                        });
                    }
                }
            );
        });
    }
 
Jason, I think your stuff is being executed too late to have the effect you want with regard to the submit button.

If you search xenforo.js for "$.Event(" you will find all the instances where we fire custom events. For the AutoValidator system, which handles AJAX form submission and validation, you have the following events:
  1. AutoValidationBeforeSubmit
    Fires immediately before the form data is submitted, after the submit button is clicked or 'enter' is hit.
  2. AutoValidationDataReceived
    Fires after the AJAX data response is received, but before validation is checked.
  3. AutoValidationComplete
    Fires after the returned AJAX data is checked for validity.
  4. AutoValidationRedirect
    Fires immediately before the page is redirected following a successful AJAX response (if a redirect has been requested).
Of these, I think your submit button blur needs to be bound to AutoValidationBeforeSubmit. Your textarea clearing code is fine with AutoValidationComplete. Have you checked that it's finding the correct element? Try adding something obvious like $form.find('textarea[name="message"]').css('backgroundColor', 'hotpink'); to ensure that you have correctly grabbed it. Other than that, I can't see why the clearing code would not be working.

Can you also explain what your XenForo.ajax() call is supposed to be doing there? I have a suspicion that I know what you're trying to do, and I think I can show you a better way, but I need to know your intentions there first.
 
I have a suspicion that I know what you're trying to do, and I think I can show you a better way, but I need to know your intentions there first.
I have a comment form here: http://xen1.8wayrun.com/media/nicovideo-test-video.6/
(you need to be logged in to comment)

When someone submits a comment, it sends the comment, and then updates the comment list... the XenForo.ajax() call is working perfectly fine in refreshing the comment list. I have it so when someone posts a new comment, it refreshes the comment list, rather than simply prepend it to the comment list... but if there is a better way, I'm all for it.

The only question I've been unable to figure out is... how do I prevent multiple submits...

Code:
XenForo.CommentPoster = function($form)
{
    $form.bind('AutoValidationComplete', function(e)
    {
        if (e.ajaxData.status)
        {
            $('#CommentStatus').text(e.ajaxData.status);
        }

        var StatusEditor,
            $textarea = $form.find('textarea[name="message"]')
            .val('')
            .blur();

        if (StatusEditor = $textarea.data('XenForo.StatusEditor'))
        {
            StatusEditor.update();
        }

        XenForo.ajax(
            e.ajaxData.newurl,
            {},
            function(ajaxData, textStatus)
            {
                if (ajaxData.templateHtml)
                {
                    new XenForo.ExtLoader(ajaxData, function()
                    {
                        $(ajaxData.templateHtml).xfInsert('replaceAll', '#mediaComments', 'xfShow');
                    });
                }
            }
        );
    });
}
 
I figured it out... here is the contents of my current JS file... I commented some of the stuff in the CommentPoster so that others could look at it and see exactly what I did...

PHP:
/** @param {jQuery} $ jQuery Object */
!function($, window, document, _undefined)
{
    XenForo.CommentFeedLoader = function($link)
    {
        $link.click(function(e)
        {
            e.preventDefault();
            var oriurl = $link.attr('href').split('?');
            var newurl = oriurl[0] + "comments/?" + oriurl[1];

            XenForo.ajax(
                newurl,
                {},
                function(ajaxData, textStatus)
                {
                    if (ajaxData.templateHtml)
                    {
                        new XenForo.ExtLoader(ajaxData, function()
                        {
                            $(ajaxData.templateHtml).xfInsert('replaceAll', '#mediaComments', 'xfShow');
                        });
                    }
                }
            );
        });
    }

    // *********************************************************************

    XenForo.CommentPoster = function($form)
    {
        // disables submit form to prevent multiple submissions
        $form.bind('AutoValidationBeforeSubmit', function(e)
        {
            XenForo.MultiSubmitFix($form);
        });

        // updates comment list after validation
        $form.bind('AutoValidationComplete', function(e)
        {
            // blurs focus away from submit button, dont see purpose of this line
            $form.find('input:submit').blur();

            // sets contents of a "status" DIV in template, removes status notice after 4 seconds
            if (e.ajaxData.status)
            {
                $('#CommentStatus').text(e.ajaxData.status);
                setTimeout(function() { $('#CommentStatus').text(''); }, 4000);
            }

            // gets information about the contents of text area
            var StatusEditor,
                $textarea = $form.find('textarea[name="message"]')
                .val('')
                .blur();

            // clears contents of text area
            if (StatusEditor = $textarea.data('XenForo.StatusEditor'))
            {
                StatusEditor.update();
            }

            // runs ajax refresher to update the list of comments and return to comment page 1
            XenForo.ajax(
                e.ajaxData.newurl,
                {},
                function(ajaxData, textStatus)
                {
                    if (ajaxData.templateHtml)
                    {
                        new XenForo.ExtLoader(ajaxData, function()
                        {
                            $(ajaxData.templateHtml).xfInsert('replaceAll', '#mediaComments', 'xfShow');
                        });
                    }
                }
            );
        });
    }

    // *********************************************************************

    XenForo.register('#CommentFeed div.PageNav a[href]', 'XenForo.CommentFeedLoader');
    XenForo.register('#CommentPoster', 'XenForo.CommentPoster');
}
(jQuery, this, document);[/[SIZE=18px]PHP[/SIZE]]
 
Okay, that's what I thought you were doing. How about not doing that separate AJAX call at all, and having the necessary templates etc. to refresh your comment list (or just the latest comments) be returned from the same request that submits the form data? Having that extra XenForo.ajax() call is rather wasteful of resources. I've got to take the kids to nursery now, but I'll embellish some details when I return unless you've already worked it out. :)
 
Back
Top Bottom