开发者

How do I stop multiple posts in my script?

I've written a rudimentary text editor for my page. Any tag with the .edit class can be clicked by a logged in user and a form appears with the text in the textarea field to be edited in addition to unbinding the 'click'. Upon submit the function performs a post and updates the database via a ColdFusion component and reloads the page to reflect the changes made. Works great (thanks in no small part to the Stackoverflow community and Ray Camden).

I created a 'cancel' function that clears the form field (because it's reusable) and re-binds teh 'click'. The trouble is, I see in firebug that if I click some text, cancel, click some other text and then click submit my code performs two posts - one for the cancelled click and one for the real thing.

What do I need to do to kill that first aborted effort?

Here's the code:

    $(document).ready(function() {

$('#cancelEdit').click(rebinder);
$('.edit').click(texteditor);

function texteditor(){
    var theName = $(this).attr('name'); 
    var textToEdit = $(this).html();
    var theParentID = $(this).closest('div').attr('id');
    var theTag = this.tagName.toLowerCase();
    var theID = theName.split("-")[1];
    var gateway = ("<cfoutput>#URL.page#</cfoutput>");
    var fieldDims = [$(this).css('width'), $(this).css('height')];

    $('#theText').attr('value', textToEdit );
    $('#theText').css('height', fieldDims[1]);
    $('#theText').css('width', fieldDims[0]);
    $('.edit').unbind('click');


    $('#texteditform').submit(function(e){
    //stop the form submission
      e.preventDefault()
        var newText = $('#theText').val();
        //CFC
        $.post("cfc/engine.cfc?method=updateText&returnformat=json", 
            {text:newText, field:theID, gateway_id:gateway},
            function(res) {
                //Handle the result
                if(res.trim() == "true") {
                    $('#theText').attr('value', '');
                    location.reload();
                    //$('.edit').bind('click');
                } else {
                    alert("Didn't Work");
                }
            });
    });

    };

function rebinder(){
    alert('rebinder');
    $('.edit').click(texteditor);
    $('#theText').attr( 'value', '' );
    $('#theText').css('height', '');
    $('#theText').css('width', '');
};


// End of doc开发者_如何学Goument.ready function //                
});

I just looked at the console and not only does the post happen twice but it posts the text from the second attempt to both post efforts which, unfortunately updates both elements with the .edit class. That's bad...


You're binding the submit event on the form multiple times. Move the binding out of the texteditor function or unbind the event before binding again.


Instead of blindly rebinding the "click" handler for your ".edit" elements, make sure they're "clean" first:

function rebinder(){
    alert('rebinder');
    $('.edit').unbind('click').click(texteditor);
    // ...
}

Sometimes there are other handlers for "click" for different purposes. In that case, you would only want to unbind the handler for the "editor" function. To do that, jQuery lets you bind events with a contextual marker so that you can later unbind just the click handler you want. That would look like this:

    $('.edit').unbind('click.editor').bind('click.editor', texteditor);

In other words, instead of just "click", you add a suffix after a '.' and that suffix distinguishes that click handler for any others that might be bound. (In this case that may not be necessary of course.)


Ofeargall, the problem seems to be in how you are binding the submit event to your form. I've refactored your code below for fun and also took the bind to submit function out side of texteditor(). Let me know if it works out or if you are still having troubles. I'm hoping that you understand why you are having the problem, if you don't after this, please feel free to ask further questions.

$(function() {
    $('#cancel').click(rebinder);
    $('.edit').click(texteditor);

    $('#texteditform').live('submit', function(e) {
        // stop the form submission
        e.preventDefault();
        var $el = $(this /*, DOM_ELEMENT_PARENT */);
        var $theText = $('#theText', this); // change this?
        var newText = $theText.val(),
            // NOT USED: theParentID = $el.closest('div').attr('id'),
            theTag = this.tagName.toLowerCase(),
            theID = theName.split("-")[1],
            gateway = ("<cfoutput>#URL.page#</cfoutput>"),

        // CFC
        $.post("cfc/engine.cfc?method=updateText&returnformat=json", 
            {text:newText, field:theID, gateway_id:gateway},
            function(res) {
                // Handle the result
                if(res.trim() == "true") {
                    $theText.attr('value', '');
                    location.reload();
                    // $('.edit').bind('click');
                } else {
                    alert("Didn't Work");
                }
            }
        );
    });

    function texteditor() {
        var $el = $(/* DOM_ELEMENT_WITH_EDITABLE_TEXT, DOM_ELEMENT */);
        var theName = $el.attr('name'), 
            textToEdit = $el.html(),
            fieldDims = [$el.css('width'), $el.css('height')];

        $('#theText, #texteditform').attr('value', textToEdit )
                                   .css({
                                        'height' : fieldDims[1],
                                        'width' : fieldDims[0]
                                   });

        // you should make only current .edit unbound, and autocancel
        // when other .edit is clicked (and by cancel -- change to just
        // temporary disabling the form (hiding, etc.) such that the
        // text edits are saved if same .edit is clicked later
        $('.edit').unbind('click');
    }       

    function rebinder() {
        // alert('rebinder');
        $('.edit').click(texteditor);
        $('#theText, #texteditform').attr('value', '')
                     .css({
                        'height' : '',
                        'width' : ''
                     });
    }

}); /* END */

Please keep in mind there are most definitely problems with the code, it's not meant to just be copy pasted. You should look it over and make sure you understand why I changed certain things in my quick check of it. Please point out fixes. Good luck.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜