Coder Social home page Coder Social logo

jquery.dirty's Introduction

jquery.dirty's People

Contributors

challet avatar davvolun avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar mkllnk avatar renovate-bot avatar renovate[bot] avatar simon-reynolds avatar wrburgess avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

jquery.dirty's Issues

fails positiv with django-tagulous fields

I used some https://github.com/radiac/django-tagulous fields in my https://github.com/jedie/PyInventory project and whant to use https://github.com/simon-reynolds/jquery.dirty to warn user about unchanged forms.

Sadly jquery.dirty doesn't handle django-tagulous fields correctly. It raised the unchaned warning for new, but not filled forms and raise no warning on changes :(

tagulous used https://github.com/select2/ and the code looks like this:
grafik

Any idea how to fix this?

(Crosspost: radiac/django-tagulous#156 )

Question how to handle Chained dropdown Ajax ?

Hi,
I'm using select2.js and Ajax for chained drop down
Country, State, City

If the field are empty on page load then if I select items, then clear all 3 fields I'm getting the form dirty...
This seems related to when the code call .empty();

I saw that you have a refreshEvents is this something that could use for this problem?

Thanks

Error installing 0.8.0

Using npm i jquery.dirty brings up an error:

> [email protected] preinstall [snip]\node_modules\jquery.dirty
> npx npm-force-resolutions

npx: installed 5 in 1.727s
ENOENT: no such file or directory, open './package-lock.json'

It seems to be caused by b54f03b adding

"preinstall": "npx npm-force-resolutions",

Installing 0.7.2 works fine.

References:
oktadev/schematics#192 (comment)

How to add detection to a tab?

I'm having 2 differents forms on tabs (bootstrap tabs)
tab1 = form1
tab2 = form2

Let say a user made a change on tab1 form and click on a tab2, I want to detect this even as a quit before saving.

What will be the best way to do it?

Cando grid issue

/*

(function ($) {

//Save dirty instances
var singleDs = [];
var dirty = "dirty";
var clean = "clean";
var dataInitialValue = "dirtyInitialValue";
var dataIsDirty = "isDirty";
var formIsDirty = false;
var $el;
var thisIsDirty;
var result;
var $this;
var $e;
var initialValue;
var currentValue;


var getSingleton = function (id) {
    singleDs.forEach(function (e) {
        if (e.id === id) {
            result = e;
        }
    });
    return result;
};

var setSubmitEvents = function (d) {
    d.form.on("submit", function () {
        d.submitting = true;
    });

    if (d.options.preventLeaving) {
        $(window).on("beforeunload", function (event) {
            if (d.isDirty && !d.submitting) {
                event.preventDefault();
                return d.options.leavingMessage;
            }
        });
    }
};

var setNamespacedEvents = function (d) {

    d.form.find("input, select, textarea").on("change.dirty click.dirty keyup.dirty keydown.dirty blur.dirty", function (e) {
        d.checkValues(e);
    });

    d.form.on("dirty", function () {
        d.options.onDirty();
    });

    d.form.on("clean", function () {
        d.options.onClean();
    });
};

var clearNamespacedEvents = function (d) {
    d.form.find("input, select, textarea").off("change.dirty click.dirty keyup.dirty keydown.dirty blur.dirty");

    d.form.off("dirty");

    d.form.off("clean");
};

var Dirty = function (form, options) {
    this.form = form;
    this.isDirty = false;
    this.options = options;
    this.history = [clean, clean]; //Keep track of last statuses
    this.id = $(form).attr("id");
    singleDs.push(this);
};

Dirty.prototype = {
    init: function () {
        this.saveInitialValues();
        this.setEvents();
    },

    isRadioOrCheckbox: function (el) {
        return $(el).is(":radio, :checkbox");
    },

    isFileInput: function (el) {
        return $(el).is(":file")
    },

    saveInitialValues: function () {
        $this = this;
        this.form.find("input, select, textarea").each(function (_, e) {
            if ($this.isRadioOrCheckbox(e)) {
                $(e).data(dataInitialValue, ($(e).is(":checked") ? "checked" : "unchecked"));
            } else if ($this.isFileInput(e)) {
                $(e).data(dataInitialValue, JSON.stringify(e.files))
            } else {
                $(e).data(dataInitialValue, $(e).val() || '');
            }
        });
    },

    refreshEvents: function () {
        clearNamespacedEvents(this);
        setNamespacedEvents(this);
    },

    showDirtyFields: function () {
        return this.form.find("input, select, textarea").filter(function (_, e) {
            return $(e).data("isDirty");
        });
    },

    setEvents: function () {
        setSubmitEvents(this);
        setNamespacedEvents(this);
    },

    isFieldDirty: function ($field) {
        initialValue = $field.data(dataInitialValue);
        // Explicitly check for null/undefined here as value may be `false`, so ($field.data(dataInitialValue) || '') would not work
        if (initialValue == null) { initialValue = ''; }
        currentValue = $field.val();
        if (currentValue == null) { currentValue = ''; }

        // Boolean values can be encoded as "true/false" or "True/False" depending on underlying frameworks so we need a case insensitive comparison
        if ((/^(true|false)$/i).test(initialValue) && (/^(true|false)$/i).test(currentValue)) {
            return !(new RegExp("^" + initialValue + "$", "i")).test(currentValue);
        }

        return currentValue !== initialValue;
    },

    isFileInputDirty: function ($field) {
        return JSON.stringify(($field[0]).files) !== $field.data(dataInitialValue);
    },

    isCheckboxDirty: function ($field) {
        return $field.data(dataInitialValue) !== $field.is(":checked") ? "checked" : "unchecked";
    },

    checkValues: function (e) {
        $this = this;
        formIsDirty = false;            

        this.form.find("input, select, textarea").each(function (_, el) {
            $el = $(el);
            
            if ($this.isRadioOrCheckbox(el)) {
                thisIsDirty = $this.isCheckboxDirty($el);
            } else if ($this.isFileInput(el)) {
                thisIsDirty = $this.isFileInputDirty($el);
            } else {
                thisIsDirty = $this.isFieldDirty($el);
            }

            $el.data(dataIsDirty, thisIsDirty);

            formIsDirty |= thisIsDirty;
        });

        if (formIsDirty) {
            $this.setDirty();
        } else {
            $this.setClean();
        }
    },

    setDirty: function () {
        this.isDirty = true;
        this.history[0] = this.history[1];
        this.history[1] = dirty;

        if (this.options.fireEventsOnEachChange || this.wasJustClean()) {
            this.form.trigger("dirty");
        }
    },

    setClean: function () {
        this.isDirty = false;
        this.history[0] = this.history[1];
        this.history[1] = clean;

        if (this.options.fireEventsOnEachChange || this.wasJustDirty()) {
            this.form.trigger("clean");
        }
    },

    //Lets me know if the previous status of the form was dirty
    wasJustDirty: function () {
        return (this.history[0] === dirty);
    },

    //Lets me know if the previous status of the form was clean
    wasJustClean: function () {
        return (this.history[0] === clean);
    },

    setAsClean: function () {
        this.saveInitialValues();
        this.setClean();
    },

    setAsDirty: function () {
        this.saveInitialValues();
        this.setDirty();
    },

    resetForm: function () {
        $this = this;
        this.form.find("input, select, textarea").each(function (_, e) {
            $e = $(e);
            if ($this.isRadioOrCheckbox(e)) {
                $e.prop("checked", ($e.data(dataInitialValue) === "checked"));
            } if ($this.isFileInput(e)) {
                e.value = "";
                $(e).data(dataInitialValue, JSON.stringify(e.files))

            } else {
                $e.val($e.data(dataInitialValue));
            }
        });

        this.checkValues();
    }
};

$.fn.dirty = function (options) {

    if (typeof options === "string" && /^(isDirty|isClean|refreshEvents|resetForm|setAsClean|setAsDirty|showDirtyFields)$/i.test(options)) {
        //Check if we have an instance of dirty for this form
        // TODO: check if this is DOM or jQuery object
        $this = getSingleton($(this).attr("id"));

        if (!$this) {
            $this = new Dirty($(this), options);
            $this.init();
        }

        switch (options.toLowerCase()) {
            case "isclean":
                return !$this.isDirty;
            case "isdirty":
                return $this.isDirty;
            case "refreshevents":
                $this.refreshEvents();
            case "resetform":
                $this.resetForm();
            case "setasclean":
                return $this.setAsClean();
            case "setasdirty":
                return $this.setAsDirty();
            case "showdirtyfields":
                return $this.showDirtyFields();
        }

    } else if (typeof options === "object" || !options) {

        return this.each(function (_, e) {
            options = $.extend({}, $.fn.dirty.defaults, options);
            (new Dirty($(e), options)).init();
        });

    }
};

$.fn.dirty.defaults = {
    preventLeaving: false,
    leavingMessage: "There are unsaved changes on this page which will be discarded if you continue.",
    onDirty: $.noop, //This function is fired when the form gets dirty
    onClean: $.noop, //This funciton is fired when the form gets clean again
    fireEventsOnEachChange: false, // Fire onDirty/onClean on each modification of the form
};

})(jQuery);

setAsClean does not trigger onClean

I was wondering why setAsClean isn't triggering the onClean callback, if there is no reason, I'd like to create a PR and add it, just wanted to know before working on it.

*Same thing for resetForm

Not working with rich text editor fields

Hi, first of all, thank you very much for the handy plugin. It is really useful and I found it from a stack overflow answer.

My form has a rich text editor fields (CK Editors). Your plugin can detect the dirtiness of all other fields but those rich text editors. Is there any attributes to be set to make it work with rich text editors or it just isn't implemented? If it an unimplemented feature, is there a work around?

Thanks!

Datepicker

Hi,

I'm using an hybrid version a mix of yours and the original dirrty script.

I'm using this datepicker https://github.com/uxsolutions/bootstrap-datepicker
If I enable the datepicker clear button clearBtn: true,
this is not triggering a change when I clear the value and not enabling the save button

Any clue how I could handle this case?

It doesn't work on iOS Safari

Hello,
is jquery.dirty supposed to work on iOS Safari? In my tests, it doesn't work (the warning never appears).
The beforeunload event should work on iOS, though.

Thanks

E.

Multiple forms on same page submit will be considered as beforeunload

Let say I have two forms on the same page with different ids for the form and the submit
I edited both forms so they have both dirtty fields
If I click one of the submit button I will get beforeunload notification.

Any way to fix that?

Note:
I have redo my page and now it's working fine I'll close this for now as I don't know how to reproduce.

'leavingMessage' is ignored

This works properly, but the leavingMessage is ignored.
On Firefox it shows the default, on Chrome "Leave Site? The changes you made may not be saved"

Ignore save button

Do you have an example of how to stop the message appearing when you click a save/submit button?

Possible problem with setAsDirty

Hi,

I'm setting the form as dirty on page load $("#add").dirty("setAsDirty");
and if I quit the page it's not alerting and the button stay disable

How should I use it?

resetForm does not work for forms with no ID

If called via:

$('form').dirty();

For forms with no ID set, then a lot of features do not work. Can the array of forms not be identified using something other than ID?

For example:

dirty("resetForm")

No longer works

False positive on click / focus

Hello,
I have noticed that the form gets "dirty" even if I just click into a textbox without changing anything.
Is this the intended behaviour? Is it possible to change the status to "dirty" only if the form has actually been changed?

Thanks.

Best,

resetForm overwriting checkbox values, resetForm called erroneously from refreshEvents

I was experiencing strange behavior with resetForm being called unexpectedly and realized the switch statement doesn't break or return here:

        case "refreshevents":
            d.refreshEvents();
        case "resetform":
            d.resetForm();

So when you call refreshEvents it will also call resetForm.

Additionally there is a similar issue in resetForm, which was causing my checkbox values to be set to value="unchecked" and value="checked":

            if (isRadioOrCheckbox) {
                var initialCheckedState = $e.data(dataInitialValue);
                var isChecked = initialCheckedState === "checked";

                $e.prop("checked", isChecked);
            } if(isFile) {
                e.value = "";
                $(e).data(dataInitialValue, JSON.stringify(e.files))

            } else {
                var value = $e.data(dataInitialValue);
                $e.val(value);
            }

The second if should be an else if, which explains why my checkbox values were being changed.

I am putting together a pull request with these changes.

Demo example

Hi,
If you find the time, could you set up a demo page, with some basic instructions.
Thanks

Is there any setAsDirty

Hi,

I have a case that a form is pre-filled with some data, so I need to set the form to dirty on page load.

Do I need to create a setAsDirty or is there a way to call an existing function to do it setDirty?

Any help or guidance is welcome
Thanks

StopImmediatePropagation conflicts with other behaviors

Hello,

I have an issue caused by the stopImmediatePropagation at the end of checkValues.

This prevent other subscribers to react to key press on form. In my example, jquery validation do not validate input field after key has been pressed.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/codeql-analysis.yml
  • actions/checkout v3
  • github/codeql-action v2
  • github/codeql-action v2
  • github/codeql-action v2
.github/workflows/npm-publish.yml
  • actions/checkout v3
  • actions/setup-node v3
  • actions/checkout v3
  • actions/setup-node v3
  • actions/checkout v3
  • actions/setup-node v3
npm
package.json
  • @types/jquery 3.5.14
  • braces 3.0.2
  • jquery 3.6.0
  • kind-of 6.0.3
  • minimist 1.2.6
  • node-qunit-phantomjs 2.1.1
  • qunitjs 2.4.0
  • minimist 1.2.6
  • braces 3.0.2

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.