jessepollak / card

:credit_card: make your credit card form better in one line of code
MIT License
11.66k stars 1.48k forks source link

Cannot read property 'getAttribute' of undefined #342

Closed SimplySynced closed 3 years ago

SimplySynced commented 7 years ago

I've tried using both the jquery.card.js and the card.js files. I've tried to include them at the bottom of the page. I am trying to use this in a modal so I am wondering if this is the issue. Here is my modal.

and here is my script at the bottom of my php file.

As mentioned in the title I get the Cannot read property 'getAttribute' of undefined in the console. Am I missing something?

SimplySynced commented 7 years ago

Hello, so I've done some more testing and this is what I've come up with. When I use form it works fine but it doesn't seem to let me use names/ids/classes to choose the form. Only when I remove the name/id/class does it work. Is this something that can work or no?

BallisticPain commented 7 years ago

@SimplySynced I'm actually getting a similar error, and I'm hoping mine is simply because I wasn't using the CVC... however, I'm not setting the form selector, so not sure what our difference is to get the same error.

Thanks!

BallisticPain commented 7 years ago

@SimplySynced I believe my issue is related to using *ngIf and my elements don't exist yet...

ziemerz commented 7 years ago

I'm getting the same error. Also an Angular (4.x.x) application.

muneer-memon commented 7 years ago

@BallisticPain i have the same issue, if my element doesn't exist, it throws this error. Do we have the solution for this yet?

stefmabo commented 6 years ago

Any solution for Angular4+?

muneer-memon commented 6 years ago

you need to have all four fields on the form, if you wana skip any of them then you need to hide it. If you use *ngIf it wont render and it will complain. in order to hide it you can use [hidden]="anyExpression"

stefmabo commented 6 years ago

Thanks @muneer-memon

atakanaydin commented 6 years ago

You need to add ID to the form

new Card({ form: 'form', ----> new Card({ form: '#formID',

JoshuaNovak919 commented 6 years ago

I'm having this issues with normal Javascript and jQuery. Anyone solve this?

hamedbaatour commented 6 years ago

guys using Angular 5 just make sure to new up Card function in the ngAfterViewInit() lifecycle hook:

  ngAfterViewInit() {
    const card = new Card({
      form: '.card-form',
      container: '.card-wrapper',
    });
  }

@stefmabo @ziemerz

jcjollant commented 6 years ago

Same issue with Vue. Card() is invoked inside mounted() but it seems it's too soon.

yankolo commented 5 years ago

I had the same issue just now. I noticed I was loading the card before the DOM has loaded 🤣

edlgg commented 5 years ago

@jcjollant Do you know what do I need to do to make it work with Vue or Nuxt? Im getting an error, TypeError: Cannot read property 'getAttribute' of undefined

This is the code I have:

<template>
  <form>
    <input type="text" name="number" />
    <input type="text" name="first-name" />
    <input type="text" name="last-name" />
    <input type="text" name="expiry" />
    <input type="text" name="cvc" />
  </form>
</template>

<script>
const cardData = {
  // a selector or DOM element for the form where users will
  // be entering their information
  form: 'card-form', // *required*
  // a selector or DOM element for the container
  // where you want the card to appear
  container: '.card-wrapper', // *required*

  formSelectors: {
    numberInput: 'input#number', // optional — default input[name="number"]
    expiryInput: 'input#expiry', // optional — default input[name="expiry"]
    cvcInput: 'input#cvc', // optional — default input[name="cvc"]
    nameInput: 'input#name' // optional - defaults input[name="name"]
  },

  width: 200, // optional — default 350px
  formatting: true, // optional - default true

  // Strings for translation - optional
  messages: {
    validDate: 'valid\ndate', // optional - default 'valid\nthru'
    monthYear: 'mm/yyyy' // optional - default 'month/year'
  },

  // Default placeholders for rendered fields - optional
  placeholders: {
    number: '•••• •••• •••• ••••',
    name: 'Full Name',
    expiry: '••/••',
    cvc: '•••'
  },

  masks: {
    cardNumber: '•' // optional - mask card number
  },

  // if true, will log helpful messages for setting up Card
  debug: true // optional - default false
}
export default {
  head() {
    return {
      script: [
        {
          src: 'node_modules/card/dist/card.js'
        }
      ]
    }
  },
  data: function() {
    return {
      card: null
    }
  },
  mounted() {
    const $ = require('jquery')
    window.jQuery = $
    console.log('window.jQuery: ', window.jQuery)
    const Card = require('card')
    console.log('card', Card)
    this.card = new Card(cardData)
  }
}
</script>
muneer-memon commented 5 years ago

guys using Angular 5 just make sure to new up Card function in the ngAfterViewInit() lifecycle hook:

  ngAfterViewInit() {
    const card = new Card({
      form: '.card-form',
      container: '.card-wrapper',
    });
  }

@stefmabo @ziemerz

You can also use ngOnChanges to initialize the card object.

DerekCrosson commented 5 years ago

Same issue with Vue. Card() is invoked inside mounted() but it seems it's too soon.

I have the same problem, any idea how to fix it?

hvaughan3 commented 5 years ago

@DerekCrosson We have our init call in created and within a Vue.nextTick() call.

hounw commented 4 years ago

was anyone able to fix this?????

omansak commented 4 years ago

Check this in your html <div class='card-wrapper'></div>

hounw commented 4 years ago

Check this in your html <div class='card-wrapper'></div>

Yeah no, it is, but it needs to be inside it's own form for some reason in a woocommerce payment method.

I was able to fix it by creating a sub-form and then copying the element to hidden inputs inside the main woo form 🤷‍♂️

marcos-alexandre82 commented 4 years ago

@hounw can you put in the gist and post here the code you used in WooCommerce? I'm having trouble implementing it on WooCommerce too.

hounw commented 4 years ago

@marcos-alexandre82 I was wrong I must've been something else that I ended up fixing, it CAN be inside a simple div.

the standard code worked for me, what issue are you facing?

marcos-alexandre82 commented 4 years ago

@hounw are you using in a payment plugin for WooCommece? I'm trying to implement it in my plugin, but it doesn't work properly. It only displays the skins of the Hipercard and Troy cards. If I try to use another card it remains gray. For him to display the image of the card, I had to wrap the JS code with the jQuery function of WooCommerce, because otherwise, when the page is finished loading, the card disappears.

Can you help me?

These are the JS codes: card.js

woo-rede.js

And this is the PHP code for the form: integration-rede-for-woocommerce.php

Tks

hounw commented 4 years ago

@marcos-alexandre82 that's weird... by instinct I'm pretty sure it's some other issue but here's how I ended up doing it... we only have mc/visa/amex so I don't know about all others but those three seem to work

https://gist.github.com/hounw/2083e9b3e252222ed55987c9d20f3579

marcos-alexandre82 commented 4 years ago

@hounw Thank you! I will analyze your code and try to implement it in mine ;)

melloware commented 3 years ago

There are is now wrappers or documentation for Vue, Angular, React etc so closing this ticket

guhenrique007 commented 3 years ago

@jcjollant Do you know what do I need to do to make it work with Vue or Nuxt? Im getting an error, TypeError: Cannot read property 'getAttribute' of undefined

This is the code I have:

<template>
  <form>
    <input type="text" name="number" />
    <input type="text" name="first-name" />
    <input type="text" name="last-name" />
    <input type="text" name="expiry" />
    <input type="text" name="cvc" />
  </form>
</template>

<script>
const cardData = {
  // a selector or DOM element for the form where users will
  // be entering their information
  form: 'card-form', // *required*
  // a selector or DOM element for the container
  // where you want the card to appear
  container: '.card-wrapper', // *required*

  formSelectors: {
    numberInput: 'input#number', // optional — default input[name="number"]
    expiryInput: 'input#expiry', // optional — default input[name="expiry"]
    cvcInput: 'input#cvc', // optional — default input[name="cvc"]
    nameInput: 'input#name' // optional - defaults input[name="name"]
  },

  width: 200, // optional — default 350px
  formatting: true, // optional - default true

  // Strings for translation - optional
  messages: {
    validDate: 'valid\ndate', // optional - default 'valid\nthru'
    monthYear: 'mm/yyyy' // optional - default 'month/year'
  },

  // Default placeholders for rendered fields - optional
  placeholders: {
    number: '•••• •••• •••• ••••',
    name: 'Full Name',
    expiry: '••/••',
    cvc: '•••'
  },

  masks: {
    cardNumber: '•' // optional - mask card number
  },

  // if true, will log helpful messages for setting up Card
  debug: true // optional - default false
}
export default {
  head() {
    return {
      script: [
        {
          src: 'node_modules/card/dist/card.js'
        }
      ]
    }
  },
  data: function() {
    return {
      card: null
    }
  },
  mounted() {
    const $ = require('jquery')
    window.jQuery = $
    console.log('window.jQuery: ', window.jQuery)
    const Card = require('card')
    console.log('card', Card)
    this.card = new Card(cardData)
  }
}
</script>

@edlgg, me too, did you solve?