Guru Advice: Tracking "IsDirty" with InfoPath Forms Services - InfoPath Dev
in

InfoPath Dev

Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

Last post 02-12-2010 08:39 AM by Alec Pojidaev. 8 replies.
Page 1 of 1 (9 items)
Sort Posts: Previous Next
  • 02-18-2008 02:28 PM

    Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    I have spent the last few days banging my head against the wall with this one.  I am looking for fresh ideas, or maybe a "thinking" outside of the box experienced InfoPath person that might have an idea I can leverage.

    These are the facts:

    1) I have a huge InfoPath form which is browser enabled and I am using the XmlFormView control in a custom web part.  I have over 500 fields (yes, that many, and about 8 Views).

    2) We have a make or break requirement which entails being able to track if the form is dirty, or basically if the user tries to navigate away from the current web page we prompt them "The form is not saved, are you sure you want to leave, etc".  Again, this is within a web part zone and I need to figure out a way to resolve isdirty so any navigational link or attempt to close this web part page prompts the user.

    This is what I've thought about/ruled out:

    1) Using the Schema_Changed event (or root level node) and the FormState object within managed code at the client object/form level, I can verify when a change occurs.  The problem is, I can't use this.NotifyHost() or a SubmitToHost.Execute() connection, since there has been no postback.  This is not a UI button driven event, basically the client object form needs to tell the host or Server, "hey I'm dirty" with no user interaction or button even to drive post back.  And there appears to be no way to simulate a button click on an InfoPath form (as a lessor hack of doom...).

    2) At the browser level, I can write javascript to check some hidden field within the window.onbeforeunload event hander, but the problem is, I have no way to set it, given point 1.  Handing the browser prompting is not the issue, its resolving the dirty status.

    3) I can NOT have every field on the form auto post back to the server (under Browser settings in design view of InfoPath)and leverage a  managed code changed event  since its over 500 fields, this isn't practical since the IIS server would lag and every time the user changed a field value, it would re-send to the server, not a good user experience and we just can't do it.

    4) Writing javascript to get the client rendered  data array (var g_objCurrentFormData) that the XmlFormViewer uses.  Basically get the array.ToString() MD5 hash it via javascript and then compare AGAIN against the data array resolved on window unload.  Unfortunately, Forms Services scrubs through the data array and makes changes between window.onload and window.beforeunload, so I can't do this either...

    So, I'm struggling and I'm not sure how else I can do this.

    Any ideas?  Can I extend Forms Services to use a new post back agent or trigger?  Custom javascript that fires when a "tracker field" such as "Dirty_Field_Tracker"  is updated to do a postback?

    Has anyone been able to track the is dirty state of an InfoPath form through InfoPath Forms Services, some way of tracking if the form has changed?

    Thanks for reading and any ideas are appreciated.

    MK

  • 03-03-2008 03:59 PM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    If you are writing this in javascript on the page that hosts forms server, you could inspect the data tree (say, in your onunload handler) and find out if the data is dirty or not in the following way:

    // Checks if user actions have changed data
    function CheckIfDirty()
    {
     var objViewDataNode;
     // Get the root of the data tree
     objViewDataNode = CurrentFormData.ViewDataTree();

     while (objViewDataNode != null)
     {
      // Get the actual data object
      var objDatum = ViewDataNode.GetDatum(objViewDataNode);

      if (objDatum.IsDirty())
      {
       // your code here
      }

      // Get the next element  
      objViewDataNode = ViewDataNode.FindNext(objViewDataNode);
     }
    }

    Disclaimer: this is not public OM and so it's subject to change - use it at your own risk.
    Warning: this can be very performance-intensive for large views.

    Let me know if this approach works for you.

    David Airapetyan / Software Services Architect
    Qdabra® Software / Streamline data gathering to turn process into knowledge
  • 03-04-2008 03:26 PM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    Well this is resolved for now--what I wound up doing is grabbing the MD5 hash against the data array which is rendered to the client (g_objCurrentFormData). It didn't work at first, since InfoPath Forms Services runs its own "InfoPath Onload" event AFTER the window.onload event.  I was able to piece together the proper methodology to get the proper MD5 hash of the client rendered data array, which does update each time a field is changed.

    In the Window onload event I get the hash and store it in a hidden field and then in the window unload event I get the hash again, using a javascript variable to check against postback, since we don't want to check in this case, by registering a submit block handler via ASP.net and managed code.  If they do not match a change occured within THIS view.  InfoPath forms services renders the views dynamically and also note, I have 8 views and this form is massive (the XSN is about 500 KB in size). As the user switches views, I still need to track the dirty state, etc.

     So what I wound up doing is using two hidden fields and a server and client side approach.  This data array hashing has good performance but I also used the schema_changed event (top level, could NOT use individual control level onchange events because I have over 600 fields).  I would ONLY flag the first change in the schema_changed event, by leveraging the FormState dictionary object and some booleans and other logic.  When the user switches views, which is a command button on my form, this invokes a postback.  After this postback, the .NotifyHost() call I have when IsDirty is true (at InfoPath object/VSTO level) is invoked. Now the SERVER can track a hidden field on postback when the views switch. The XmlFormViewer control then would set a FormState property back to false, signifying the InfoPath Object to start trackking is dirty again, given a change occurs after this notification, etc. The solution needed to be tiered, because of the number of views, complexity and number of potential "Is dirty" options which could occur, etc.

    This solution works great and it took me a while to resolve the proper mix.  Of course, my client level MD5 hashing is not supported, but no javascript, client level solution would be - - so I picked the best performance option.

     Thanks for your feedback

     MK

  • 01-04-2009 08:40 AM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    The code is executed every time the form unloaded? Is it possible to capture the change in real time? Like that of event handlers?

    Regards,

    Sam

  • 07-07-2009 12:10 PM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

  • 07-07-2009 10:59 PM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    Hey, that's some killer xpath dude! :)

    Our free qRules 1.7 (due out next week) will have an IsDirty rule which will use InfoPath's IsDirty bit and doesn't require an InitialState node, but while it's less work, it's not as clever as your approach. :)

     

    Patrick Halstead
    Project Manager at Qdabra
  • 07-08-2009 07:01 AM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    >but while it's less work...

    I don't think Installing 3rd party admin approved assembly to the server is less work than creating 2 fields and copying 2 XPath expressions especially when you are not wearing admin hat too. The thing has to have much more value/functionality to a form than ability to track Dirty status to justify installations of itself.

  • 07-08-2009 07:25 AM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    Alec, it does have far more, and it does not get installed to the server.  It's just a local installation, and you inject to your own forms.  The only administrative interaction would be if you use qRules for browser forms.  There are at least 6 qRules in 1.7 that I will be using regularly, and the others I just haven't tested yet to figure out where I'd use them.

    I use all of your codeless stuff, and this one you saw me test, but it does not check for invalid fields (data validation, etc), so it is limited only to checking changes in the form unless I missed something.

  • 02-12-2010 08:39 AM In reply to

    Re: Guru Advice: Tracking "IsDirty" with InfoPath Forms Services

    warrtalon:
    so it is limited only to checking changes in the form unless I missed something

    Yes you did missed somthing. It also not launching spaceships to the Moon and not doing many more other useful things. It only does exactly what topic starter wants. It's unacceptable I know. :)

Page 1 of 1 (9 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.