Dynamically initialise multiple input fields in plugin - javascript

I've many forms on one page. Each of the forms should have a phone number field. Those fields are driven by JS plug-in.
So I'm getting a big number of fields which should be properly initialized.
If I will do it manually I will get:
forms * phone input fields = number of initializations.
At this moment I only have the very first field working. Other doesn't initialize.
My markup looks like:
<input type="tel" class="phone_flag" name="phone_tab1[main]" required="">
<input type="tel" class="phone_flag" name="phone_tab2[main]" required="">
<input type="tel" class="phone_flag" name="phone_tab3[main]" required="">
xxx
...
I got a piece of advice: in order to make in properly work, I should have querySelectorAll with forEach loop. Then I should call PhoneDisplay function, don't pass the class name, instead pass in the element itself. Afterward, initialize the plugin on that element directly.
I only came to this solution, but it only inits the first element.
JS init code:
document.querySelectorAll('.phone_flag').forEach(el => {
PhoneDisplay(el.className);
});
function PhoneDisplay(ClassName){
var input = document.querySelector('.' + `${ClassName}`);
var iti = window.intlTelInput(input, {
hiddenInput: "full",
initialCountry: "auto",
geoIpLookup: function(callback) {
$.get('proxy.php', function() {}).always(function(resp) {
var countryCode = (resp && resp.country) ? resp.country : "";
callback(countryCode);
});
},
hiddenInput: "full_phone",
utilsScript: "intlTelInput/js/utils.js"
});
var reset = function() {
input.classList.remove("error");
errorMsg.innerHTML = "";
errorMsg.classList.add("hide");
validMsg.classList.add("hide");
};
input.addEventListener('blur', function() {
reset();
if (input.value.trim()) {
if (iti.isValidNumber()) {
validMsg.classList.remove("hide");
} else {
input.classList.add("error");
var errorCode = iti.getValidationError();
errorMsg.innerHTML = errorMap[errorCode];
errorMsg.classList.remove("hide");
}
}
});
input.addEventListener('change', reset);
input.addEventListener('keyup', reset);
}

document.querySelector returns the first query, so var input is always the first input. You should just pass in the element itself in the forEach loop: PhoneDisplay(el); and then function PhoneDisplay(input) and remove the 'var input=' line.

jQuery(document).ready(function($) {
var input = $("input[name=phone]");
input.each(function() {
intlTelInput($(this)[0], {
initialCountry: "auto",
nationalMode: false,
separateDialCode: true,
preferredCountries: ["ua", "pl", "us"],
geoIpLookup: function(success, failure) {
$.get("https://ipinfo.io", function() {}, "jsonp").always(function(resp) {
var countryCode = (resp && resp.country) ? resp.country : "us";
success(countryCode);
});
},
});
});
});

Related

intl-tel-input is not adding country code with phone Number

I am using intl-tel-input plugin in my contact form. Plugin is running fine and dropdown is appearing well with all country codes and flags. but when i submit form, i can see only phone number i have added without any country code in start. here is what i am doing.
<input class="cfos_field" autocomplete="off" type="tel" name="number" id="cfos-number" placeholder="Your Number">
and here is my Jquery code
jQuery(document).ready(function () {
var rhInput = document.querySelector("#cfos-number");
window.intlTelInput(rhInput, {
initialCountry: "auto",
geoIpLookup: function (callback) {
jQuery.get('https://ipinfo.io', function () {
}, "jsonp").always(function (resp) {
var countryCode = (resp && resp.country) ? resp.country : "";
callback(countryCode);
});
},
});
});
I dont know what i am doing wrong.

Why does this form get submitted even if the required fields value Incorrect or validation fail?

I am Apply Javascript validation, When form validation fail why it is
Submitting. Here I am using following code.
var FormValidation = function () {
var isbnForm = function() {
// for more info visit the official plugin documentation:
// http://docs.jquery.com/Plugins/Validation
var form1 = $('#isbnForm');
var error1 = $('.alert-danger', form1);
var success1 = $('.alert-success', form1);
form1.validate({
errorElement: 'span', //default input error message container
errorClass: 'help-block help-block-error', // default input error message class
focusInvalid: false, // do not focus the last invalid input
ignore: "", // validate all fields including form hidden input
messages: {
select_multi: {
maxlength: jQuery.validator.format("Max {0} items allowed for selection"),
minlength: jQuery.validator.format("At least {0} items must be selected")
}
},
rules: {
isbn: {
required: function(){
var isbn = $("#isbn").val();
if(isbn){
var resultData10 = isValidIsbn10 (isbn);
if(resultData10 != 1){
$(".errorData").show();
$(".errorData").html("<p style='color:#A94442;'>ISBN number is not valid</p>");
return true;
}
else{
$(".errorData").hide();
return false;
}
}
else{
$(".errorData").hide();
return true;
}
function isValidIsbn10 (isbn) {
isbn = isbn.replace(/[^\dX]/gi, '');
if(isbn.length != 10){
return false;
}
var chars = isbn.split('');
if(chars[9].toUpperCase() == 'X'){
chars[9] = 10;
}
var sum = 0;
for (var i = 0; i < chars.length; i++) {
sum += ((10-i) * parseInt(chars[i]));
};
return (0 === (sum % 11)) ? 1 : false;
}
}
},
name: {
required: true
},
},
invalidHandler: function (event, validator) { //display error alert on form submit
success1.hide();
error1.show();
Metronic.scrollTo(error1, -200);
},
highlight: function (element) { // hightlight error inputs
$(element)
.closest('.form-group').addClass('has-error'); // set error class to the control group
},
unhighlight: function (element) { // revert the change done by hightlight
$(element)
.closest('.form-group').removeClass('has-error'); // set error class to the control group
},
success: function (label) {
label
.closest('.form-group').removeClass('has-error'); // set success class to the control group
},
submitHandler: function (event,form) {
success1.show();
error1.hide();
form.submit();
}
});
}
return {
//main function to initiate the module
init: function () {
isbnForm();
}
};
}();
When I type Wrong value into ISBN input type then Error message will be show But After that form submitted.I want if value is wrong Form should not be submitted.
Your isbn: required rule only determines if the isbn is required or not. If you enter an invalid isbn, isValidIsbn10() will return false, and your required rule will return false. So it means an isbn is not required, that's all. That does not stop the form being submitted.
What you want is a rule that only validates if the isbn is valid. You'll need a custom validation method to do that.

Knockout: automatic push for an array

I have a div bound to an observable array like so:
<div data-bind="foreach: currentSelected().Tags " contenteditable="true">
<span data-bind="text:$data"></span>
</div>
I made the div's content editable so that any changes (user input) get reflected in the Tags array, but that isn't working as I assumed. There seems to be no automatic push for observable arrays. My question is, how do I get new values inside the Tags array using binding?
Here is how I am setting currentSelected:
var newBlogEntry = new NewBlogEntry();
var newBlogEntryObservable = new NewBlogEntryObservable(newBlogEntry);
self.currentSelected(newBlogEntryObservable);
The function for NewBlogEntry is as follows:
function NewBlogEntry()
{
return { "Id": 0, "Title": "Title", "Description": "Description", "Tags": [] };
}
I managed to solve the problem by adding an extra input field:
<input type="text" placeholder="new tag" data-bind="value:newTag, valueUpdate: 'afterkeydown', enterkey: addNewTag" id="addTag" />
The binding for the enter key is as follows:
ko.bindingHandlers.enterkey = {
init: function (element, valueAccessor, allBindings, viewModel) {
var callback = valueAccessor();
$(element).keypress(function (event) {
var keyCode = (event.which ? event.which : event.keyCode);
if (keyCode === 13) {
callback.call(viewModel);
return false;
}
return true;
});
}
};
And this is the observable for the newTag:
self.newTag = ko.observable();
self.addNewTag = function () {
if (self.newTag() == '')
alert("Enter something in input field");
else {
var tag = self.newTag();
self.currentSelected().Tags.push(tag);
$("#addTag").val("");
}
}

Javascript validation - group validation - if one entered, then all required

Using just jQuery (not validation plugin) I have devised a way to do a "if one, then all" requirement, but it's not at all elegant.
I'm wondering if someone can come up with a more elegant solution? This one uses some loop nesting and I'm really not pleased with it.
if ($("[data-group]")) {
//Store a simple array of objects, each representing one group.
var groups = [];
$("[data-group]").each(function () {
//This function removes an '*' that is placed before the field to validate
removeCurError($(this));
var groupName = $(this).attr('data-group');
//If this group is already in the array, don't add it again
var exists = false;
groups.forEach(function (group) {
if (group.name === groupName)
exists = true;
});
if (!exists) {
var groupElements = $("[data-group='" + groupName + "']");
var group = {
name: groupName,
elements: groupElements,
trigger: false
}
group.elements.each(function () {
if (!group.trigger) {
group.trigger = $(this).val().length !== 0;
}
});
groups.push(group);
}
});
//Now apply the validation and alert the user
groups.forEach(function (group) {
if (group.trigger) {
group.elements.each(function () {
//Make sure it's not the one that's already been filled out
if ($(this).val().length === 0)
// This function adds an '*' to field and puts it into a
// a sting that can be alerted
appendError($(this));
});
}
});
You don't have to store the groups in an array, just call the validateGroups function whenever you want to validate the $elements. Here is a working example http://jsfiddle.net/BBcvk/2/.
HTML
<h2>Group 1</h2>
<div>
<input data-group="group-1" />
</div>
<div>
<input data-group="group-1" />
</div>
<h2>Group 2</h2>
<div>
<input data-group="group-2" value="not empty" />
</div>
<div>
<input data-group="group-2" />
</div>
<div>
<input data-group="group-2" />
</div>
<button>Validate</button>
Javascript
function validateGroups($elements) {
$elements.removeClass('validated');
$elements.each(function() {
// Return if the current element has already been validated.
var $element = $(this);
if ($element.hasClass('validated')) {
return;
}
// Get all elements in the same group.
var groupName = $element.attr('data-group');
var $groupElements = $('[data-group=' + groupName + ']');
var hasOne = false;
// Check to see if any of the elements in the group is not empty.
$groupElements.each(function() {
if ($(this).val().length > 0) {
hasOne = true;
return false;
}
});
// Add an error to each empty element if the group
// has a non-empty element, otherwise remove the error.
$groupElements.each(function() {
var $groupElement = $(this);
if (hasOne && $groupElement.val().length < 1) {
appendError($groupElement);
} else {
removeCurError($groupElement);
}
$groupElement.addClass('validated');
});
});
}
function appendError($element) {
if ($element.next('span.error').length > 0) {
return;
}
$element.after('<span class="error">*</span>');
}
function removeCurError($element) {
$element.next().remove();
}
$(document).ready(function() {
$('button').on('click', function() {
validateGroups($("[data-group]"));
});
});
You might get some milage out of this solution. Basically, simplify and test your solution on submit click before sending the form (which this doesn't do). In this case, I simply test value of the first checkbox for truth, and then alert or check the required boxes. These can be anything you like. Good luck.
http://jsfiddle.net/YD6nW/1/
<form>
<input type="button" onclick="return checkTest()" value="test"/>
</form>
and with jquery:
checkTest = function(){
var isChecked = $('input')[0].checked;
if(isChecked){
alert('form is ready: input 0 is: '+isChecked);
}else{
$('input')[1].checked = true;
$('input')[2].checked = true;
}
};
//create a bunch of checkboxes
$('<input/>', {
type: 'checkbox',
html: 'tick'
}).prependTo('form');
$('<input/>', {
type: 'checkbox',
html: 'tick'
}).prependTo('form');
$('<input/>', {
type: 'checkbox',
html: 'tick'
}).prependTo('form');

jquery.form/validate plugin only allow submit if input is changed

I'd like to use the jQuery.Form/Validate plugins to only allow my form to be submitted if any of inputs were actually changed.
There is callback logic for this using beforeSubmit: : http://jquery.malsup.com/form/#options-object. However, I can't seem to make it work.
Here's what I have so far:
$(document.body).on('click', 'input[type="submit"]', function(){
var $form =$('form');
$form.validate({
submitHandler: function($form) {
$($form).ajaxSubmit({
beforeSubmit: function(arr, $form){
var value = '', storedValue='';
$($form+':input').each(function (index, el) {
value=$(el).val();
storedValue=$(el).data("stored");
if(value!=storedValue){
console.log("Changed"); return true;
}
else {
return false; console.log("NOT changed");
}
});
...success handling, etc..
beforeSubmit: function(arr, $form) {
var value = '', storedValue='';
$($form+':input').each(function (index, this) {
value=this.value;
storedValue=$(this).data("stored");
if(value!=storedValue){
console.log("Changed");return true;
}
else {
return false; console.log("NOT changed");
}
});
}
Here's the HTML:
<form id="myForm">
<input data-stored="my title" value="my title"/>
<textarea data-stored="my description">my description</textarea>
<input type="submit" value="submit/>
</form>
Currently the console.log shows, "Changed" regardless of whether the storedValue is equal or not to the input.
First of all it will never show "Not Changed" since it returns false before it hits that part. You should filter out the submit button too since you probably aren't checking its value.
$($form+':input').not(':submit').each(function(index, this) {
value = this.value;
storedValue = $(this).data("stored");
if (value != storedValue) {
console.log("Changed");
return true;
}
else {
console.log("NOT changed");
return false;
}
});
UPDATE
With great assistance from #wirey, together we've (#timrpeterson and #wirey) put together a solution. Instead of returning true/false within the each() loop, I incremented a value ,totalChanged, and assessed after the each() loop whether or not it was greater than 0.
here's the code:
beforeSubmit: function(arr, $form){
var value = '', storedValue='', totalChanged=0;
$('#myForm :input').not(':submit,:hidden').each(function (i, el) {
//console.log($(this));
console.log($($form));
value=$(el).val();
storedValue=$(el).data("stored");
if (value != storedValue) {
totalChanged++;
}
else {
}
}); //each
if(totalChanged>0){
console.log("at least one changed");
return true;
}
else{
console.log("All NOT changed");
return false;
}
} //beforeSubmit

Categories

Resources