1

I have a pretty typical form with some inputs and a submit button, however when I try to use jQuery's find() method, I get some annyingly inconsistent results. The are as follows:

$("#frmContact").find(":submit") -> undefined is not a function  
$("#frmContact").find(".btn") -> works
$("#frmContact").find(".btn.secondary") -> undefined is not a function
$("#frmContact").find("input[type=submit]") -> works
$("#frmContact input:submit") -> undefined is not a function
$("input[type=submit]", "#frmContact") -> undefined is not a function
$("form").find("input") -> works
$("form").find("input[type=submit]") -> undefined is not a function

What's going on here and how do I fix this?

I'm using jQuery 1.11 after upgrading from 1.9 hoping that it will fix the issue. There's also Angular on the page and I'm calling this code from the console after everything is loaded.

My form, just in case you need it is as follows [EDIT] updated to show actual HTML output with Angular classes and directives:

<form ng-submit="saveContact($event, '/applicants/update_contact?id=1593')" class="ng-pristine ng-valid" _lpchecked="1" id="frmContact">
   <h4 class="section-header">Applicant Contact Information</h4>

   <field id="email" type="text" model="applicant.email" label="Email address" class="ng-isolate-scope">
     <div ng-class="['field', isRequired()]" class="field"> <!-- Text/File/Password Field -->
        <label ng-bind="label" class="ng-binding">Email address</label>
        <input type="text" ng-model="model" class="ng-pristine ng-valid">
      </div>
   </field>


  <div class="field">
     <input type="submit" value="Save" class="btn secondary">
  </div>
</form>

My JavaScript libraries are loaded in this order:

  1. jQuery 11
  2. jQuery UI
  3. Angular
  4. My app.js

Scripts are loaded at the bottom of the page.

kshep92
  • 841
  • 1
  • 11
  • 22

2 Answers2

0

AngularJS comes with JQLite, a lightweight smaller verison of jQuery, which is the one you are using here and that gives you unexpected results.

In order for Angular to works with the full jQuery, you need to make sure that you load jQuery before Angular. So watch your <script> tags order.

floribon
  • 19,175
  • 5
  • 54
  • 66
  • But even under jQLite, an unsupported selector shouldn't give "undefined is not a function" .... should it? – Roamer-1888 Apr 17 '15 at 00:13
  • Well it's possible if somehow internally it tries to dynamically create a function based on the selector or any shadowy things like that. Is it the `find` method itself which is undefined or the error happens deeper into angular code? Try to log simply `$("#frmContact").find` to see if the function itself exsists. – floribon Apr 17 '15 at 00:39
  • There's something that the OP isn't telling us because even an invalid/ unsupported selector should give rise to an empty jQuery selection. – Roamer-1888 Apr 17 '15 at 00:50
  • @Roamer-1888 not really, JQLite doesn't behave exactly the same and an empty selector returns `null` if I'm correct. Try to open an empty tab in the Chrome browser and write `$('.nothing');`, it should give you null. However I am not certain that Chrome defaults to JQLite or yet another jQuery subset. – floribon Apr 17 '15 at 01:05
  • floribon, interesting, thanks, If I had Chrome available, I would try, and If the OP would post some feedback, we would know if your tag order theory was correct. – Roamer-1888 Apr 17 '15 at 04:15
  • @floribon jQuery is loaded before Angular. See my edits. – kshep92 Apr 17 '15 at 15:15
0

So it turns out the hand that held the knife to my throat was my own.

Earlier in the application's development it was useful to add a couple helper methods on the Object prototype by doing Object.prototype.findId = function() { ... }. Turns out this raised all sorts of hell when trying to perform the find() method in jQuery.

I fixed it by turning this:

Object.prototype.myMethod = function() { ... }

into this

var specialObject = function(object) {
   return {  
     myMethod: function() { ... }
   }
}

I didn't realize that my earlier approach was such bad practice until I read this: Extending Object.prototype JavaScript

Thank you all for your help, guys.

Community
  • 1
  • 1
kshep92
  • 841
  • 1
  • 11
  • 22