Question

I'm a beginner with Ajax requests.

I've an Ajax request using Prototype and other using Jquery. The two are working, but only if I call them separately. I need a help getting a solution for this conflict.

In the code that I show bellow, only the Ajax request on "$.fn.bindPostCommentHandler = function()" will work. The Ajax request on "new VoteHijacker("link");" is not working.

How can I make this two Ajax requests work together?

Here is the code on my webpage.

<html lang="en">
<head>
    <link rel="stylesheet" href="/media/css/base.css" type="text/css" />
    <script src="/media/js/prototype.js"></script>
    <script src="/media/js/getcookie.js"></script>
    <script src="/media/js/prototype.extend.js"></script>
    <script src="/media/js/votehijaker.js"></script>

    <script src="/media/js/jquery-1.8.3.js"></script>
    <script type="text/javascript" charset="utf-8">
        (function( $ ){
        $.fn.bindPostCommentHandler = function() {
            // We get passed a list of forms; iterate and get a unique id for each
            // attach a submit trigger to handle saving and returning
            this.each(function() {
            //$(this).find('input.submit-preview').remove();
            $(this).submit(function() {
                commentform = this;
                commentwrap = $(this).parent();
                $.ajax({
                    type: "POST",
                    data: $(commentform).serialize(),
                    url: "/comments/post/",
                    cache: false,
                    dataType: "html",
                    success: function(html, textStatus) {   
                        // Extract the form from the returned html
                        postedcomment = $(html).find('#newly_posted_comment');
                        //alert(html);
                        $(commentform).replaceWith(postedcomment.html());
                        $(commentwrap).hide();
                        $(commentwrap).slideDown(600);
                        $(commentwrap).find('.comment-form form').bindPostCommentHandler();
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        $(commentform).replaceWith('Your comment was unable to be posted at this time.  We apologise for the inconvenience.');
                    }
                });
                return false;
            });
            }); //each
        };  
        })( jQuery );

        $(function() {
            $('.comment-form form').bindPostCommentHandler();
        });
    </script>


</head>
<body>
    ...
    ...
    <script type="text/javascript">
    Event.observe(window, "load", function()
    {
        new VoteHijacker("link");
    });
    </script>
    ...
    ...

The code on "VoteHijaker()", votehijaker.js is the following:

var VoteHijacker = Class.create();
VoteHijacker.prototype =
{
    initialize: function(prefix)
    {
    this.prefix = prefix || "";
    this.registerEventHandlers();
    },

    registerEventHandlers: function()
    {
    $$("form." + this.prefix + "vote").each(function(form)
    {
        Event.observe(form, "submit", this.doVote.bindAsEventListener(this), false);
    }.bind(this));
    },

    doVote: function(e)
    {
    Event.stop(e);
    var form = Event.element(e);
    var id = /(\d+)$/.exec(form.id)[1];
    var action = /(up|down|clear)vote/.exec(form.action)[1];
    new Ajax.Request(form.action, {
        onComplete: VoteHijacker.processVoteResponse(this.prefix, id, action)
    });
    }
};

VoteHijacker.processVoteResponse = function(prefix, id, action)
{
    return function(transport)
    {
    var response = transport.responseText.evalJSON();
    if (response.success === true)
    {
        var upArrowType = "grey";
        var upFormAction = "up";
        var downArrowType = "grey";
        var downFormAction = "down";

        if (action == "up")
        {
            var upArrowType = "mod";
            var upFormAction = "clear";
        }
        else if (action == "down")
        {
            var downArrowType = "mod";
            var downFormAction = "clear";
        }

        VoteHijacker.updateArrow("up", prefix, id, upArrowType);
        VoteHijacker.updateArrow("down", prefix, id, downArrowType);
        VoteHijacker.updateFormAction("up", prefix, id, upFormAction);
        VoteHijacker.updateFormAction("down", prefix, id, downFormAction);
        VoteHijacker.updateScore(prefix, id, response.score);
    }
    else
    {
        alert("Erro a votar: " + response.error_message);
    }
    };
};

VoteHijacker.updateArrow = function(arrowType, prefix, id, state)
{
    var img = $(prefix + arrowType + "arrow" + id);
    var re = new RegExp("a" + arrowType + "(?:mod|grey)\\.png");
    img.src = img.src.replace(re, "a" + arrowType + state + ".png");
};

VoteHijacker.updateFormAction = function(formType, prefix, id, action)
{
    var form = $(prefix + formType + id);
    form.action = form.action.replace(/(?:up|down|clear)vote/, action + "vote");
};

VoteHijacker.updateScore = function(prefix, id, score)
{
    var scoreElement = $(prefix + "score" + id);
    scoreElement.innerHTML = score.score + " point" + VoteHijacker.pluralize(score.score);
    scoreElement.title = "after " + score.num_votes + " vote" + VoteHijacker.pluralize(score.num_votes);
};

VoteHijacker.pluralize = function(value)
{
    if (value != 1)
    {
    return "s";
    }
    return "";
};

And the code on "prototype.extend.js":

// This is an extend solution to inject in the HEADERS the csrftoken
Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
        function (callOriginal, options) {
        var headers = options.requestHeaders || {};
        headers["X-CSRFToken"] = getCookie("csrftoken");
        options.requestHeaders = headers;
        return callOriginal(options);
        }
    );

Any clues on how to make this two Ajax requests work together?

Best Regards,

Was it helpful?

Solution

The problem is both libraries want to own the $ short-cut. There is a setting in jQuery to use "no-conflict mode", but doing so requires that you replace all $ shortcuts in your jQuery code with something else, such as j$.

See: http://docs.jquery.com/Using_jQuery_with_Other_Libraries

Using JQuery and Prototype in the same page

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top