Dynamic-Forms problem

Issue #1 resolved
Tim Ammons created an issue

Hi – Dynamic-Forms looks like a great tool – just what I was looking for.

I have an Angular application that I have been trying to integrate Dynamic-Forms into. I have attached some code to show the issue, and a screenshot that shows the controls.

The problem arises whenever I type a character into the first text box. I get this error:

TypeError: Unable to set property 'first' of undefined or null reference

Also, when I click the Submit button, it does nothing.

Thanks for your help!

Tim

Comments (32)

  1. Hennik Hunsaker repo owner

    Your form's data will be set in keys of the form's model. In the case of your code, that's $scope.formData. So you'll want to set $scope.formData = {}; and $scope.formData.first = 'Fred';. That should fix the problem.

  2. Tim Ammons reporter

    That definitely helped - the 2 textboxes work now. The button still does not respond - I thought it would run processForm when I clicked it.

            <dynamic-form template="formTemplate"
                          ng-model="formData"
                          ng-submit="processForm()">
            </dynamic-form>
    

    I also tried setting up a callback for it, but that didn't work either:

    ... "submit": { "type": "submit", "label": "Submit this section", "callback": "buttonClicked" } }; $scope.formData = {}; $scope.formData.buttonClicked = function () { alert('Button was clicked!'); }

    Thank you for your help!

  3. Hennik Hunsaker repo owner

    Your callback goes into ng-click, which uses Angular Expressions - so you'll need to write it "callback": "buttonClicked()". No idea why ng-submit isn't working for you, though.

  4. Tim Ammons reporter

    Thanks - by changing to "callback": "buttonClicked()" and also changing $scope.formData.buttonClicked to $scope.buttonClicked, it worked!

    Do you plan to add support for ng-show and ng-hide?

  5. Hennik Hunsaker repo owner

    Glad it's working now!

    Not as such. What I do plan on doing is adding support for arbitrary attributes. That will allow the use of ng-show, ng-hide, and any number of other directives that require attributes to work. That'll cover almost every directive it makes sense to use in a form, when paired with class, which is already supported. It'll be down to element-based directives, which I'm not certain fit the scope of this project and so don't currently plan to support, and comment-based ones, which are rarely used in practice, based on my experience.

  6. Tim Ammons reporter

    Is there any way to place elements into a table structure, so the page can be formatted properly?

    I need to decide on a solution to use pretty quickly since the project is already underway - and I wonder if you could share a) your timeline for adding arbitrary attributes, b) formatting in a table, and c) whether you consider this code "ready for primetime" use.

    Thanks!

  7. Hennik Hunsaker repo owner

    A) I'm going to try to have this in place sometime today (US Mountain Daylight).

    B) The only thing I can offer for table-like layout is the purely CSS kind. Indeed, the demo file is set up that way, thanks to Bootstrap. I'm not sure how I would even implement such a thing otherwise...

    C) This is far from my best work, has a few improvements suggested on GitHub which would make it more flexible and useful, and is solidly in the version 0 range. So no, I don't think it's ready for prime time. That won't, however, stop me from using it in various projects, many of them public and/or high-profile. So really that's going to be your call.

  8. Hennik Hunsaker repo owner

    As an update to A) - Arbitrary attribute support is now in place. Consult the README for details.

  9. Tim Ammons reporter

    I successfully used the "arbitrary attribute" support - so that's good.

    Since we have a lot of users still on IE8, I tested there, and found that it did not work. I have already done some work to try to fix the problems. To fix the use of indexOf on an array, I used es5-shim.min.js, which fixed that problem.

    Now I am getting the following: Error: Unexpected call to method or property access. I don't know what line it bombs on, but if I comment out the <dynamic-form...> the error goes away.

    I have tried using the IEshiv from the Angular site, but that doesn't help.

    Do you know what I can do to make this work for IE8?

    Thanks,

    Tim

  10. Tim Ammons reporter

    I also added this code in the page:

      <!--[if lte IE 8]>
        <script>
          document.createElement('ng-include');
          document.createElement('ng-pluralize');
          document.createElement('ng-view');
          document.createElement('nn-header');
          document.createElement('nn-care-team');
          document.createElement('nn-pre-diagnostic-findings');
          document.createElement('nn-activity');
          document.createElement('dynamic-form');
          document.createElement('ng-list');
          document.createElement('input');
    
          // Optionally these for CSS
          document.createElement('ng:include');
          document.createElement('ng:pluralize');
          document.createElement('ng:view');
        </script>
      <![endif]-->
    

    And one more thing: I tried adding replace: true into the directives, but that didn't help either.

  11. Hennik Hunsaker repo owner

    There's no use of an access method or property anywhere in the directive's code... So I'm not sure what's introducing this... I don't personally support IE, of any version (Chrome Frame's disappearance still makes me sad), so I'm not sure where I'd recommend looking. I'd say it might be the ES5 shim, but it's minimized, so the method/property name would be unintelligible. The only other thing I can think of is that it's your own code, but I hate telling people that because it feels lazy.

    I'm also not sure what the createElement()s would actually do to help, but again, I don't support IE, so I don't know its quirks. I'll obviously need to change that stance somewhat for this project. 😁

  12. Tim Ammons reporter

    Error: Unexpected call to method or property access means that it can't access a method or property of an object. So that could mean virtually any object and any method or property - it is hard to track down.

    A non-minimized version of ES5shim is shown here: https://github.com/es-shims/es5-shim/blob/master/es5-shim.js.

    The createElement() entries are necessary to allow Angular directives to be used as "E" elements - otherwise IE 8 and below balk at them. That is from the Angular website at https://docs.angularjs.org/guide/ie.

    One thing I found is this: http://stackoverflow.com/questions/17932470/determine-which-custom-html-tag-is-offending-ie8. It claims that if you run the following code after your page loads, you can detect the problem object. I put that in the page's $(document).ready(function - but it didn't report anything.

    var list = document.getElementsByTagName('*');
    for (var i = 0, len = list.length; i < len ; i++) {
      if (list[i].tagName.indexOf('/') === 0)
        alert(list[i].tagName.substr(1));
    } 
    

    We have a significant percentage of customers on IE 8. Since you're not an IE guy, and I'm not sure how to get this debugged, I may have to move on to another solution.

  13. Hennik Hunsaker repo owner

    Oh. IE's console error messages are just useless. Got it.

    I'll try to pull this up on a machine with IE8 and see what I can figure out from here, but it will be a bit (an hour or two) before I can start. I'll need access to your project, or at least enough code to reproduce the error.

  14. Tim Ammons reporter

    Thanks for your offer! I'm getting a small care package ready for you, so you'll have what you need.

  15. Tim Ammons reporter

    I'd like to send that info to you more privately - any suggestions?

    I can also do a GotoMeeting with you if needed.

    • Tim
  16. Hennik Hunsaker repo owner

    I think I may have found the issue... Line 328 of dynamic-forms.js contains code where the contents of the original form are copied into the new form (which hasn't yet been added to the DOM) as a psuedo-transclusion. The error happens at this point, and there are two things I learned in the process of tracking it down:

    First, is that the error message you've been seeing was actually generated by Angular, which has intercepted the exception and handled it in a fashion that doesn't halt the entire script. That's why it was less-than-helpful in tracking down the error.

    Second, the error is because the dynForms module (this project) replaces the original element with a real <form> element - unless it's sitting inside another <form> already, in which case that would be invalid HTML, so it uses an <ng-form> instead. Not a big problem for most (real) browsers, but in the case of IE8, it means the browser blows up in your face. Try adding document.createElement('ng-form'); somewhere near your document.createElement('dynamic-form'); line and see if that helps. (The reason your "find offending tags" script didn't raise any flags about this is that the new form hadn't yet been added to the DOM... Luckily, you'd tried it, or I wouldn't have recognized what IE was doing with a </ng-form> opening tag...)

  17. Tim Ammons reporter

    Well, I tried that and it still has the same error - no difference. Here is the code now:

          <!--[if lte IE 8]>
            <script>
              document.createElement('ng-include');
              document.createElement('ng-pluralize');
              document.createElement('ng-view');
              document.createElement('nn-header');
              document.createElement('nn-care-team');
              document.createElement('nn-pre-diagnostic-findings');
              document.createElement('nn-activity');
              document.createElement('dynamic-form');
              document.createElement('ng-form');
              document.createElement('ng-list');
              document.createElement('input');
    
              // Optionally these for CSS
              document.createElement('ng:include');
              document.createElement('ng:pluralize');
              document.createElement('ng:view');
            </script>
          <![endif]-->
    
  18. Tim Ammons reporter

    When I sent you the previous message, I had tested it only on my dev system - I just copied that .aspx file up to the test server too, so you have the latest/greatest.

  19. Hennik Hunsaker repo owner

    I'm still seeing that extra /ng-form element... I'm not certain the hack on the Angular site is actually working... Still digging deeper (this is tedious with minimized code), so I'll update if I find anything new.

  20. Hennik Hunsaker repo owner

    Aha. That's ... awkward. Seems that IE8 doesn't like doing element.appendChild() if it doesn't recognize the element. Anything intreduced in HTML5, and any custom tags we introduce, don't support the method, because IE doesn't propagate it. I suspect this has been worked around in a more recent jQuery (because Angular is using jQeury under the hood, if it's loaded by the time Angular starts), but in case it hasn't, you'll simply need a shim that introduces this method to unrecognized elements. Not certain where to find one of those, but I intend to look in the morning if someone else hasn't reported in with one already.

    How annoying! I'll be updating the README to include our findings as a "to use this with IE<9" blurb. Thanks for "forcing" me to explore this!

  21. Tim Ammons reporter

    Daniel,

    Looks like you were on a roll while I was getting some rest!

    I eliminated the minimized code for both Angular and the ES5shim, to make it easier. If you need anything else non-minimized, let me know.

    I suspect the reason you got the error that you posted on dropbox was that the system had timed out and you lost session.

    I've been looking for shims and I'm going to try this: https://github.com/aFarkas/html5shiv.

  22. Tim Ammons reporter

    I'm not sure how this is supposed to work, but.... When I look at the html5shiv.js file, I don't see anything that appears to replace appendChild - it does use that function once.

  23. Hennik Hunsaker repo owner

    Oi vey. Let's try something a bit different, then. I'm going to push a change to dynForms in a few minutes (once I work out the best way to approach it) that might fix this. Apparently $('<custom-element></custom-element>') (angular.element is the jQuery $ object itself, or jqLite's if jQuery isn't present) isn't something IE<9 likes to play nice with (something in the implementation it disagrees with, I suppose), so you have to create the DOM element directly, then pass it into $() to get the jQuery extensions, rather than doing it all in one step.

    I'll comment again when I have the change pushed so you know when to grab the update.

  24. Hennik Hunsaker repo owner

    OK, new code is up. Let's give that a spin and see what it does?

    As to the Dropbox screenshot, yes and no. The tool I'm using to get IE8 access remembers the last URL I was at when I end the session, so it navigates directly to it on load. Since I was starting a brand new session with a never-before-used VM on the other end, I had no session to report to your servers, so it had the same effect as a session timeout. The reason I sent the screenshot was because you probably want the page to actually perform the redirection, rather than throwing an error from the server's side, in cases where the session times out or the user bookmarks the wrong URL.

    Still, unrelated. 😁

  25. Hennik Hunsaker repo owner

    Oh, one other thing. I looked a bit deeper and discovered that I was mistaken. IE does propagate the appendChild() method to DispHTMLUnknownElement, but it also marks the element as incapable of containing children, which is the real source of the problem. The IE hack presented by the Angular folks forces IE to treat them as DispHTMLGeneralElement instead, which is an IE DOM type which is allowed to have children.

    The More You Know... (TM)

  26. Tim Ammons reporter

    That's a winner! Nice job on tracking down and squashing that nasty issue.

    I will follow-up with a few questions that have occurred to me.

  27. Hennik Hunsaker repo owner

    Sounds good. I'll update the README and tag a new release. Thanks for pointing this out!

  28. Log in to comment