AdamMasters
AdamMasters

Reputation: 385

Dirty Forms giving error when I try to set form to clean

I have a form that I am trying to monitor to see when it becomes "Dirty" (changed), so that I can then enable a Save Changes button. It's fairly simple. In the $(document).ready() section, I enable dirtyForms on my form.

$(".dirtyForm").dirtyForms();

Then, I load the form from an ajax call, and inside that same function, I set it to clean and then start calling a function to check when it's dirty.

$(".dirtyForm").dirtyForms("setClean");
constant = setInterval(function(){checkDirty()}, 500);

Here is my function to check for when this becomes Dirty. Btw, if anyone knows of a better way to do this part, please let me know.

function checkDirty(){
    if ($.DirtyForms.isDirty()){
        $(".saveDirtyForm").removeAttr("disabled");
            $(".resetDirtyForm").removeAttr("disabled");
            console.log("Dirty...");
            clearTimeout(constant);
    }
}

You will notice that in the checkDirty function, it has clearTimeout(constant) to stop the function from continually repeating after the form becomes dirty. This all up to this point works fine. The buttons stay disabled until I change something and then almost immediately become enabled. The problem comes when I recall the ajax function to load the form with more info. When it resets the form, it gives an error when it's set to clean. It says,

Uncaught TypeError: Object function ( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context, rootjQuery );
} has no method 'facebox'

This error is in the jquery.dirtyForms.js file. It doesn't set the form to clean and start the monitoring function again. Does anyone have an idea what I'm doing wrong?

Here is the function that zeroflagL was asking about.

        function getOrderDets(id){
        $.ajax({
            url: DONEP+"blueBlob/donors/"+donorID+"/orders/"+id,
            type: "GET",
            dataType: "json",
            success: function(data){
                console.log(data);
                dataSec = data.main.aResultData[0];
                //Clear Fields
                $("#orderIdTag").text('');
                $("#orderNum").val('');
                $("#doPlaced").val('');
                $("#doShip").val('');
                $("#dTrack").val('');
                $("#doNote").val('');
                //Set Main fields
                $("#orderIdTag").text(dataSec.OrderID);
                $("#orderNum").val(dataSec.OrderNumber);
                $("#doPlaced").val(dataSec.OrderDate);
                $("#doShip").val(dataSec.ShipDate);
                $("#dTrack").val(dataSec.TrackingNumber);
                $("#doNote").val(dataSec.OrderNote);
                //Clean Dirty Form
                $(".dirtyForm").dirtyForms("setClean");
                constant = setInterval(function(){checkDirty()}, 500);
                //Set Table
                $(".orderDetTable").dataTable({
                    aaData: data.array,
                    "bAutoWidth": false,
                    "bDestroy": true,
                    "aoColumnDefs" : [
                        {"sWidth" : "13%", "sTitle" : "Quantity", "mData" : "Quantity", aTargets : [0]},
                        {"sTitle" : "Code", "mData" : "Code", aTargets : [1]},
                        {"sTitle" : "Amount", "mData" : "Amount", aTargets : [2]},
                        {"sWidth" : "6%", "sTitle" : "", "mData" : "OrderDetailsID", aTargets : [3], "mRender" : function(data, type, full){
                            return "<a href='#'><i class='glyphicon glyphicon-pencil orderDetEdit' id='"+data+"'></i></a>";
                        }}
                    ]
                });
            }
        });
    }

Here is the stack trace for the facebox call.

$.facebox@http://dev.mysite.info/details.php?id=63#:540
.DirtyForms.dialog.fire@http://dev.mysite.info/assets/js/jquery.dirtyforms.js:25
bindFn@http://dev.mysite.info/assets/js/jquery.dirtyforms.js:421
aBindFn@http://dev.mysite.info/assets/js/jquery.dirtyforms.js:311
jQuery.event.dispatch@http://dev.mysite.info/assets/js/jquery.js:5095
jQuery.event.add/elemData.handle@http://dev.mysite.info/assets/js/jquery.js:4766

Upvotes: 2

Views: 3357

Answers (2)

NightOwl888
NightOwl888

Reputation: 56909

The correct way to enable/disable the buttons when the form is dirty/clean is now posted in the official documentation. Do note that this only works with Dirty Forms 2.x.

// Enable/disable the reset and submit buttons when the state transitions
// between dirty and clean. You will need to first set the initial button
// state to disabled (either in JavaScript or by setting the attributes in HTML).
$('form').find('[type="reset"],[type="submit"]').attr('disabled', 'disabled');
$('form').on('dirty.dirtyforms clean.dirtyforms', function (ev) {
    var $form = $(ev.target);
    var $submitResetButtons = $form.find('[type="reset"],[type="submit"]');
    if (ev.type === 'dirty') {
        $submitResetButtons.removeAttr('disabled');
    } else {
        $submitResetButtons.attr('disabled', 'disabled');
    }
});

Also, it is pretty clear from your error message that you are using the default Dirty Forms 1.x behavior, which uses FaceBox as the dialog, but you don't have a reference in your page to FaceBox. You could fix that by adding the reference:

<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.facebox/1.4.1/jquery.facebox.min.js"></script>

Alternatively, you can use any dialog you want by setting the $.DirtyForms.dialog property, or you can set it to false to use the browser's default dialog.

$.DirtyForms.dialog = false;

In Dirty Forms 2.x, false is now the default setting, so there is no need to add a reference to FaceBox.

Upvotes: 0

redolent
redolent

Reputation: 4269

The first step is to call setClean after changing anything in the form including data tables.


If it's just the error, then here's a hack. This will get you by if you're under a deadline, and will also help you debug:

if ( typeof $.facebox !== 'function' )
{
    $.facebox = function(){
        var console = window['console'];
        if ( console && console.error ){
            console.error( 'Warning: $.facebox() was called', arguments );
        }
        return $();
    }
}

Another tip: If you include the same jQuery library more than once, your plugins may not work.

To solve that, do a search for all instances of jquery in your codebase using this magic:

grep -o 'jquery:[^"]*"1\....' -R *

This searches for the jQuery.fn.version string.


You also need to check that the plugin is working. Try checking the following:


EDIT: To get a stacktrace to see what's calling the facebox function:

$.facebox = function(){
    alert( new Error().stack );
};

Upvotes: 2

Related Questions