I want to format both phone and credit card input using cleave.js (in rails). I've got the formatting working if I only declare one new Cleave
object, but I get this error if I attempt to declare two:
Uncaught Error: [cleave.js] Please check the element
Here's the relevant parts of the JS file:
var Global = {};
Global.onLoad = function(){
Global.setupDatepickers(); //unrelated function
Global.setupCleavePhone();
Global.setupCleaveCreditCard();
};
$(document).on('turbolinks:load', function(){
Global.onLoad();
});
Global.setupCleavePhone = function() {
new Cleave('.phone-input', {
phone: true,
phoneRegionCode: 'US',
delimiter: '-'
});
}
Global.setupCleaveCreditCard = function() {
new Cleave('.card-input', {
delimiter: '-',
blocks: [4,4,4,4]
});
}
I've tried a few remixes of this including assigning the Cleave objects to variables and declaring them in the same function, but no dice. Here's a jsfiddle of multiple cleave objects being delared at once, and I can't see any meaningful differences between my code and theirs. The selector classes are properly applied in the view. Any thoughts why I can't seem to format two fields at once?
SOLVED:
As it turned out it needs the objects to exist in order to run new Cleave
. If one of the elements doesn't exist on the page, the whole thing fails for some reason. I ended up going with wrapping each new Cleave
, checking if an element with that class existed or not, for example:
if ($('.card-input').length) {
new Cleave('.card-input', {
delimiter: '-',
blocks: [4,4,4,4]
});
}
UPDATE:
Or even better, if you're like me and need to format more than one object of the same class on a page (which causes cleave to only format the first one with the code above) retrieve the array of objects and run cleave on each. It performs the same 'does it exist' check as well as formatting each object. For example:
for(let field of $('.zip_code').toArray()){
new Cleave(field, {
numericOnly: true,
delimiter: ' ',
blocks: [5,4]
});
}
UPDATE AGAIN:
So as it turns out the above is less than ideal because, as I understand it, the above let-of
loop (like for-in
loops) will iterate across the enumerable objects of an array, instead of just over its indices. Have a look at this answer if you too would like interpret what that's about: For-each over an array in JavaScript?.
As well, I couldn't precompile my assets for production becasue it hated the use of let
, and while changing let-of
to for-in
also worked, I ended up going with the more specific forEach
loop.
$('.zip-code').toArray().forEach(function(field){
new Cleave(field, {
numericOnly: true,
delimiter: ' ',
blocks: [5,4]
})
});
this should work as well
$('.zip-code').each(function (index, ele) {
var cleaveCustom = new Cleave(ele, {
numericOnly: true,
delimiter: ' ',
blocks: [5, 4]
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With