jquery.dirtyforms icon indicating copy to clipboard operation
jquery.dirtyforms copied to clipboard

Unable to preset a form dirty manually

Open eskhool opened this issue 8 years ago • 7 comments

Is there a way to set a form dirty manually? Especially when a form is first loaded? The use case is a form returned pre filled from the server but with errors so that the user can correct but there is unsaved data in that form since it was never saved due to the errors?

eskhool avatar Nov 08 '15 06:11 eskhool

This use case is a bit unusual. Normally, if JavaScript is enabled you would use a library such as jquery Validation to ensure the data is valid before posting back to the server. If JavaScript is not enabled, then Dirty Forms won't function anyway.

However, there are some cases where this makes sense. For example, when you need to validate something using a 3rd party server (such as submitting payment information for processing).

In this case you can rebuild the state of the form on the server side.

  1. On initial load, add a field data-df-orig with the original value of each field on the server side.
  2. If the field is empty, add a field data-df-empty="true" on the server side. This will prevent Dirty Forms from storing the original value when the field is focused.
  3. When posting the form to the server, read these fields on the server side, and ensure they are kept in place when the response is built.
  4. If the data-df-orig field doesn't match the value of the field, set the CSS class on the server to the dirtyClass.
  5. If the dirtyClass is set on any field, also set it on the corresponding form that the field is in.

That's really all there is to it - you just need to mimic what Dirty Forms does to manage state on the server.

NightOwl888 avatar Nov 09 '15 09:11 NightOwl888

Can you please elaborate on how the field is to be added with the naming etc? If its documented somewhere a link would help

The use case does exist where there is a lot of data which needs to be validated against 3rd party or internal. While you could ajax validate it, that just adds a lot of JS and server endpoints which the application may not require. Its a completely server validated form with the additional idea of not losing changes when server returns with errors.

eskhool avatar Nov 09 '15 12:11 eskhool

Usually, client-side validation can be simplified to missing fields, min/max field lengths, and formats (usually using a regular expression). This does not typically involve any round trip to the server. You are just getting tripped up because you have an unusual case where you have validation on the server side only instead of the normal case where you put it both on the client and server side.

This is not documented, except as I mentioned above. I will try to be more specific.

On initial load, you will need to set the initial values of the fields. This is so the client-side functionality will know what changed. This is normally done on the client by Dirty Forms, but when it is done there you will not be able to read the fields on the server. But if you add data- attributes to your fields, it will override what is set on the client side and allow you to read the settings on the server.

So, your initial loaded form should look something like this:

<form action="/" id="watched-form" method="post">
    <!-- Fields that are empty should have a data-df-empty="true" attibute -->
    <input id="username" name="username" type="text" data-df-empty="true" />
    <!-- Fields that have values should have a data-df-orig attibute set 
    to the same value as the value attribute -->
    <input id="password" name="password" type="password" value="DefaultPassword" data-df-orig="DefaultPassword" />
    <input id="passwordconfirm" name="passwordconfirm" type="password" value="DefaultPassword" data-df-orig="DefaultPassword" />
</form>

Now, when the data is posted to the server again, these fields will be in the request. You simply need to read their original values and ensure they are put into the response.

You should also check whether the class attribute contains the dirtyClass and ensure the response includes it if it does.

Here is a sample of the data posted to the server:

<form action="/" id="watched-form" method="post" class="dirty">
    <input id="username" name="username" type="text" data-df-empty="true" value="NightOwl888" class="dirty" />
    <input id="password" name="password" type="password" value="MyPassword" data-df-orig="DefaultPassword" class="dirty" />
    <input id="passwordconfirm" name="passwordconfirm" type="password" value="MyPassword" data-df-orig="DefaultPassword" class="dirty" />
</form>

If you have validation issues on the server, you will need to rebuild the form and fields with their dirty status and original values. This will ensure that the dirty state as well as original values are preserved across the post back.

<!-- validation messages -->
Passwords must contain a number

<form action="/" id="watched-form" method="post" class="dirty">
    <input id="username" name="username" type="text" data-df-empty="true" value="NightOwl888" class="dirty" />
    <input id="password" name="password" type="password" value="MyPassword" data-df-orig="DefaultPassword" class="dirty" />
    <input id="passwordconfirm" name="passwordconfirm" type="password" value="MyPassword" data-df-orig="DefaultPassword" class="dirty" />
</form>

But as I mentioned, it is usually much simpler just to take the post back out of the equation and use client-side validation exclusively when JavaScript is enabled.

NightOwl888 avatar Nov 16 '15 20:11 NightOwl888

I should have specified I am trying to use this with the Django auto generated admin (are you familiar with it?) which exclusively does server side validation...and returns a dirty form with data that the user has entered. SInce the CRUD is auto generated on the server side in python code, I will have to write all of it manually for the client side. Hence the need to enhance it using the method you have outlined above.

eskhool avatar Nov 17 '15 11:11 eskhool

I am not familiar with Django, sorry. Sounds like using client side validation might be difficult, but it would strike me as strange if you can't add attributes to the HTML, being that many frameworks such as Bootstrap require you to do that also.

Let me know if you run into any trouble with this, as it is not something I have tested. If it doesn't work like I specified, try adding both the data-df-orig and data-df-empty attributes to every field on initial load.

NightOwl888 avatar Nov 17 '15 18:11 NightOwl888

Were you able to resolve this issue?

NightOwl888 avatar Jun 01 '16 06:06 NightOwl888

Not ideally, but was able to apply some quick, dirty workarounds. At some stage, I would like to implement a full django app around this. WIll let you know in case you want to add it to your usage page.

On Wed, Jun 1, 2016 at 12:00 PM, Shad Storhaug [email protected] wrote:

Were you able to resolve this issue?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/snikch/jquery.dirtyforms/issues/90#issuecomment-222904891, or mute the thread https://github.com/notifications/unsubscribe/AAhDLbin4uU8sUDXpe85QbQXmgT4m6aNks5qHScZgaJpZM4GeGef .

eskhool avatar Jun 01 '16 08:06 eskhool