adding two validators to Parsley.js - javascript

What i basically want to do is have check values that user entered in an input field against two separate arrays. One is an Array of words that would create an error , other is an Array of words that would raise a warning.
I have created these 2 functions and they seem to work fine when they are bound with two different fields
, warning: function () {
var that = this;
return {
validate: function (val,arrayRange) {
var warningWords = new Array();
warningWords[0]="Cricket";
warningWords[1]="Football";
for (var i = 0; i < warningWords.length; i++) {
if(val.toLowerCase()===warningWords[i].toLowerCase())
return false;
}
return true;
}
, priority: 32
}
}
, wrong: function () {
var that = this;
return {
validate: function (val,arrayRange) {
var errorWords = new Array();
errorWords[0]="Justin";
errorWords[1]="Chester";
for (var i = 0; i < errorWords.length; i++) {
if(val.toLowerCase()===errorWords[i].toLowerCase())
return false;
}
return true;
}
, priority: 32
}
}
and the HTML
<label for="email">ERROR :</label>
<input name="message1" id="error" parsley-trigger="keyup" parsley-wrong="" ></input>
<label for="message">Warning</label>
<input name="message" parsley-trigger="keyup" parsley-warning=""></input>
<button type="submit">Submit</button>
Is it possible to bind both of these functions to the same input field?
And secondly i want that in case of warning the input fields background would turn yellow and in case of wrong it should turn red
I have over ridden the parsley-error class . But can i create another class that would be triggered when warning function invalidates the form.
Thirdly is it possible to submit the form even if warning functions causes the field to be invalidated?
It is easy to achieve through JS , so can we some how block parsley from stopping the form validation.

For Q1, you should be able to have multiple custom validators on the same input, just like you can use more than one of parsley's built-in validators. Raise or lower the priorities if you want to force one to validate first.
In response to Q2, you could add additional classes to the input to modify the parsley-error styling. Here's an example:
input.parsley-error {
background-color: #f00;
}
input.parsley-error.warning {
background-color: #ff0;
}
So if you were to have both validators on the same input field you could have the warning validator add a .warning class when it returns false and remove that class when returning true.
For Q3, you should be able to submit the form despite validation issues by overriding the 'onFormValidate' listener and have it return true, even if the 'isFormValid' parameter is false.
$('#formId').parsley({
listeners: {
onFormValidate: function(isFormValid, event, ParsleyForm) {
return true;
}
}
});

Related

Change reductive search to search submit

After having a few small wins with JS (still very much a learner) I have now inherited a task which is to change a reductive search of sorts.
Users now want to have the search work from a submit button, instead of a keyup after 3rd character. I have completed submit forms before where the form would post, but I have never come across something as complex as this before.
I have had a look through the large JS file, and located the search function which contains the keyup function.
F.initSearch = function(opts){
if(!opts || !opts.ele){
return;
}
if(!opts.start_length){
this.opts.search.start_length = 2
}
this.$search_ele = $(this.opts.search.ele);
if(this.$search_ele.length){
this.has_search = true;
this.searchFn = this.buildSearchFn(opts.fields);
this.bindEvent(opts.ele, 'keyup');
}
};
However, I am having difficulty with changing over from keyup to button click.
This is what I have done:
I have updated the form to include the button
<form>
<div class="searchBox">
<input type="text" id="search" class="search__text-input" placeholder="Search"/>
</div>
<div class="formBox">
<button id="searchbtn">Search</button>
</div>
</form>
I have tried to update the script with some jquery which follows the same pattern
$( "#searchbtn" ).this.bindEvent(opts.ele, 'click');
Lastly, I have attempted to then update the existing - which is now leaving me somewhat defeated:
F.initSearch = function(opts) {
if(!opts || !opts.ele) {
return;
}
if(!opts.start_length) {
this.opts.search.start_length = 2
}
this.$search_ele = $(this.opts.search.ele);
if(this.$search_ele.length) {
this.has_search = true;
this.searchFn = this.buildSearchFn(opts.fields);
// this.bindEvent(opts.ele, 'keyup');
/* Trying to swap keyup for button click */
$( "#searchbtn" ).this.bindEvent(opts.ele, 'click');
}
};
Link to JSFiddle: https://jsfiddle.net/mcmacca002/bo0y3u7p/2/
Clearly I am approaching this wrong, and some guidance would be greatly appreciated.

JavaScript: dynamically changing values of data range rule

I have an input field that either allows negative and positive numbers, or only positive numbers based on a value of a select.
When changing the value of the select option, I'm trying to modify the rule of the input field like this:
const id = '#myId';
$(id).attr("data-val-range-min", -10000);
removeRules(id);
addRules(id);
$(id).change(); // trying to trigger the validation of the rule
The removeRules is a function:
let removeRules = function removeRules(field) {
$(field).rules('remove');
}
And so is the addRules:
let addRules = function addRules(field) {
let $field = $(field);
if ($field.attr("data-val-required")) {
$field.rules("add", {
required: true,
messages: {
required: $field.attr("data-val-required")
}
});
}
if ($field.attr("data-val-number")) {
$field.rules("add", {
number: true,
messages: {
number: $field.attr("data-val-number")
}
});
}
if ($field.attr("data-val-range")) {
$field.rules("add", {
range: [$field.attr("data-val-range-min"), $field.attr("data-val-range-max")],
messages: {
range: $field.attr("data-val-range")
}
});
}
}
When I change the select in the UI, the data-val-range-min attribute is set correctly, but the rule is not reapplied.
Only when I manually click into the input-field and deselect it again, the rule is applied...
What am I doing wrong here?
Thanks in advance
Only when I manually click into the input-field and deselect it again, the rule is applied...
There's a validation trigger you expect that isn't part of the plugin.
By default, this plugin triggers validation on:
onfocusout - when you leave an element
onkeyup - when you're typing inside a text box
onclick - interactions with radio, checkbox, and select
Adding and removing the rules though is not enough... you'll also need to force a validation test after adding or removing the rule.
Simply call the .valid() method on the element or form when you want to programmatically force validation. Since your OP contains zero HTML markup or working demo, I cannot be more specific with a solution.

How do I stop the form submitting with invalid fields in a form?

I've been using this Background colors on Luhn Algorithm - JavaScript to help build a similar webpage. However unlike the original poster I would like the code not to submit if there is any invalid inputs across any of the fields. I would still like the input fields to change colour (either green for valid or red for invalid).
I believe that I can fix both the name and email using a mixture of pattern (for the name - "[A-Za-z!#$%&'*+-/=?^_`{|}~]+") and using the input type of email for the email section. This is in addition to using 'required' for all the input fields. However it is with the card section that I am having the most trouble with. At the moment, I cannot figure out a way to not allow the form to submit if the card field is red. For example using the code in the original post, I can input '1', the input field will turn red, but I can still submit the form. I am assuming it is something to do with the section below but I am not sure what to change/add:
cardNumberInput.addEventListener("keyup", e => {
const isCardValid = valid_credit_card(e.target.value);
if (isCardValid) {
cardNumberInput.style.backgroundColor = "green";
} else {
cardNumberInput.style.backgroundColor = "red";
}
})
Any help would be greatly appreciated and I apologise for any missing details that you may need, it is my first question here.
Make isCardValid global and add a submit event listener on your form like this
let isCardValid = false
const cardNumberInput = document.getElementById('your-input')
const cardForm = document.getElementById('your-form')
cardNumberInput.addEventListener("keyup", e => {
isCardValid = valid_credit_card(e.target.value);
if (isCardValid) {
cardNumberInput.style.backgroundColor = "green";
} else {
cardNumberInput.style.backgroundColor = "red";
}
})
cardForm.addEventListener('submit', e => {
if(!isCardValid)
e.preventDefault()
})
And the form won't be submitted until the isCardValid is true, if you want to submit the form manually instead of the default HTML submit behaviour, do this
yourForm.addEventListener(e => {
// To prevent default submission always.
e.preventDefault()
if(!isCardValid) return
// Do anything here...
})

How to reflect change made in a component's variable to the view in Angular 2?

I have (n) check boxes and a button in my angular2 view . When I click on one of them a function is called. When I click on the button every checkbox must be unchecked. How to do it?? (n) may vary dynamically.
enter image description here
I will give you an example from a table, since I have no idea what your code actually looks like, but it should work for what you need.
You need some object defined for all of your checkboxes. They likely all have certain properties in common, like labels. Here is an example of such an object:
myData = {
content: [
{
some_string: '',
some_number: 0,
type: '',
selected: false
}
]
};
With this object you can create checkbox instances and push each one to an array, which will hold all of your checkbox objects.
Create your checkboxes in your html in a loop using the objects you have defined above. In your html have your checkboxes call a function. In the case below the checkToggle() function is called.
<input id='{{row.id}}' class='bx--checkbox bx--checkbox--svg'
type='checkbox' name='checkbox' (change)="checkToggle($event,
row.id)" [checked]="row.selected">
checkToggle() has been defined as follows:
//select or deselect this check box
checkToggle(event, nodeId) {
const id = this.findNode(nodeId);
this.myData.content[id].selected = !this.myData[id].selected;
}
Your button should end up calling a function to check all of the boxes
<button (click)="checkToggleAll($event)">Your Button Title</button>
Finally, have your checkToggleAll() function go through the entire array of checkboxes and set them. Here is an example:
//select or deselect all the check boxes
checkToggleAll(event) {
for (let i = 0; i < this.myData.content.length; i++) {
if (this.controls[this.myData.content[i].type]) {
this.myData.content[i].selected = event.target.checked;
}
}
}
This is not something you can plug into your code but it should give you some idea of how to accomplish what you're after.

jQuery settings for form validation

I'm building a basic jQuery form validator. The code below is just to validate the name. I have several functions to validate mail, password, credit card, date etc. I want the user to be able to easily edit the error messages and classes. Let's say the user want to change the name of the class "error" or "success". Now the user needs to search and replace everywhere in the code where it says "error" or "success".
Is there any way to use an array or object at the top of the code to edit the error messages for each if-statement, and apply the classes?
Something like what's shown here: http://learn.jquery.com/plugins/basic-plugin-creation/#accepting-options (but at the top of the code, outside the function). Or could I use the same method but type like this (outside the function, at the top of the file)?
var settings = $.extend({
color: "#556b2f",
errorClass: "error"
}, options );
I also want the user to be able to add ID's and classes directly to the form element and type "true" in the setting "required" so the form element will be required. Is there some good way to do this?
var name = $("[data-name]");
var nameMsg = $("#nameMsg");
name.on("blur", function() { $(this).validateName() });
$.fn.validateName = function() {
if(name.val().length < 5) {
name.removeClass("success")
.addClass("error");
nameMsg.removeClass("success")
.addClass("error")
.text("Not that short, at least 5 characters.");
return false;
} else {
name.removeClass("error")
.addClass("success");
nameMsg.removeClass("error")
.addClass("success")
.html("Correct");
return true;
}
}
Solution
var defaults = {
errorClass: "error",
successClass: "success",
successMessage: "<i class='fa fa-check-circle'></i>",
errorMessageName: "Not that short, at least 5 characters.",
};
var settings = $.extend({}, defaults);
Special thanks to Martin Adámek for his help!
$.extend just creates new object merged with values from both arguments, you can use it to extend default options object with user given (anywhere you want).
I'm not sure if I understand you correctly, is this what you want?
var defaults = { // maybe you do not need extend at all?
errorClass: "error",
successClass: "success",
messageError: "Not that short, at least 5 characters.",
messageCorrect: "Correct"
};
var name = $("[data-name]");
var nameMsg = $("#nameMsg");
name.on("blur", function() { $(this).validateName() });
$.fn.validateName = function() {
var userOpts = {...}; // you can store it eg in data attribute on the element
// extend options with user given values
options = $.extend(defauts, userOpts);
if(name.val().length < 5) {
name.removeClass(options.successClass)
.addClass(options.errorClass);
nameMsg.removeClass(options.successClass)
.addClass(options.errorClass)
.text(options.messageError);
return false;
} else {
name.removeClass(options.errorClass)
.addClass(options.successClass);
nameMsg.removeClass(options.errorClass)
.addClass(options.successClass)
.html(options.messageCorrect);
return true;
}
}
The user given options would be stored as a JSON string (to allow merging with default options), so you would need to call JSON.parse() on in first.
EDIT:
Example of options JSON object in data attribute:
HTML:
<input type="text" data-options='{"messageCorrect": "Bingo! That is the right choice!", "errorClass": "my-error-class"}' ...>
and then in $.fn.validateName() you will do simply:
var userOpts = JSON.parse($(this).data('options'));

Categories