jQuery focus on first form field in div after using .addClass - javascript

I have the following example (simplified to help others) where an error class is added if fields don't meet basic validation requirements:
var email = $("input#email").val();
if (email == "") {
$("#emailblock").addClass("has-error")
var prevent = 1;
}
var org = $("input#organisation").val();
if (org == "") {
$("#orgblock").addClass("has-error")
var prevent = 1;
}
// if no entry, prevent submission and highlight first field
if (prevent == '1') {
$(".has-error:first").focus();
}
However, using the above code doesn't focus on the first instance of .has-error after using addClass().
How can you select the first instance of has-error or any other dynamically assigned class after using .addClass to a <div> that contains a form element?

You can only focus() on <input>, <select>, <a href> etc
change $(".has-error:first").focus(); to $(".has-error:first input").focus();
Here is a demo

Related

Javascript form using regex not validating correctly

JS Fiddle: https://jsfiddle.net/bcon865y/5/
Sorry if this is a little vague..
Trying to create a javascript form which validates each field using a onblur function once a field gets tested as correct the background of the field will turn green.
The submit button has a function which if all fields are green it will submit the form, however all fields are green but the form is not passing validation. I have no idea why this is happening any insight would be greatly appreciated, Hope i explained it well enough.
Below is the function in question, view the js fiddle to get the full context.
function validate() {
// Gets all the elements in the form with id="form1"
var elements = document.getElementById("form1").elements;
// loops through all elements in the form
for (var i = 0, element; element = elements[i++];) {
// Checks if the element in the form is either <input> or <select> && not green
if ((element =='[object HTMLInputElement]' || element == '[object HTMLSelectElement]') && (element.style.backgroundColor !='rgb(204,255,204)')) {
if (element.type!='color' && element.type!='submit') {
alert("Please enter data for any fields that are not green");
return false;
}
}
}
// to test the color picker
if (document.getElementById("color").value !='#000000') {
alert("please select a colour from the colour picker");
document.getElementById("The ID for your color picker goes here").focus();
return false;
}
}
It seems you're looking for a combination of the pattern field (on the input element) and the :valid & :invalid pseudo css selectors.
input[type="text"]:valid {
background: #BCED91;
}
input[type="text"]:invalid {
background: #F08080;
}
<form>
<input type="text"
id="name"
name="name"
required
pattern="[01]+">
<input type="submit">
</form>
The example above colors any text fields red if their values doesn't match the regex [01]+, and green if they do match it.
You can read more about form validation here: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation

How to find which child element is invalid in an HTML form

Is there a way to find which child elements in the form is invalid using the html5 automatic form validation?
I know we can check element by element, by calling checkValidity() method. What I'm seeking is, if there's a shorter way.
For example,
var contactForm = document.getElementById('contact-form');
if (contactForm.checkValidity() == false) {
// something like contactForm.getInvalidChildren() and apply
// different style and error message based on the child type
}
I found this method in MDN which satisfies my requirement. But I'm not sure if it's the best way to do this.
var contactForm = document.getElementById('contact-form');
if (contactForm.checkValidity() == false) {
var list = contactForm.querySelectorAll(':invalid');
for (var item of list) {
item.setAttribute("style", "background-color: red;")
}
}

jQuery change element on select - global script for multiple select inputs

I am creating a form builder script. I have a select input where the user can select the form element they want to use, depending on their selection ("select", "checkbox" or "radio") another form field is displayed allowing users to input their options.
Users can create as many instances of form elements as they want, so each select input has a dynamically created id that corresponds to the id of the hidden form field. I then use jQuery to determine whether the "options" field should be hidden or not (triggered on change of the form elements select input).
Currently, for every instance, I have the following code addedabove the select input:
<script>
jQuery(document).ready(function($) {
var arr = ['select', 'checkbox', 'radio'];
var thisForm = 'select.input-type-118';
function showHideSelect() {
var val = $(thisForm + ' option:selected').val();
var selectOptions = $('#select-options-118')
if (arr.indexOf(val) >= 0) {
selectOptions.show();
} else {
selectOptions.hide();
}
}
showHideSelect();
$(thisForm).change(function() {
showHideSelect();
});
});
</script>
Where var thisForm and var selectOptions are added dynamically and refer to the select option below this script.
I'm wondering if there is a better way to do this rather than repeat several instances of this, at the moment, a users page cold look like this:
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
...etc...etc
My concern is that I don't think it's best practice to have so many instances of the same script, but I'm unsure how to write a global script that will allow me to show/hide the textarea on an individual basis.
I have shown a more accurate depiction of my workings on this jsfiddle here:
https://jsfiddle.net/46stb05y/4/
You can use Event Delegation Concepts. https://learn.jquery.com/events/event-delegation/
With this you can change your code to
$(document).on('change','select',function() { //common to all your select items
showHideSelect($(this)); // passing the select element which trigerred the change event
});
This will work even on the select items that are added dynamically
You must change your function to receive the element as the parameter.
function showHideSelect($selectElement) {
var val = $selectElement.val();
var selectOptionsId = $selectElement.attr('class').replace('input-type','select-options');
var selectOptions = $("#"+selectOptionsId);
if (arr.indexOf(val) >= 0) {
selectOptions.show();
} else {
selectOptions.hide();
}
}
Here is the Working JsFiddle

Select Radio Button Using Javascript with No ID

I am trying to select a radio button on a webpage using Javascript inside an Applescript. For this particular button, there is no element ID, so I'm no really sure how to select this radio button.
There's really no other identifying elements for this form (or that I see, at least).
Note: There's several radio buttons on this page, and the only unique identifier between them is the "value."
HTML:
<input type="radio" size="4" name="Level" value="p;29">
Javascript/Applescript:
do JavaScript "document.getElementById('p;29').checked = true;" in doc
If you have no other input elements, you can safely use
document.getElementsByTagName("input")[0]
Otherwise, you can do:
for (i=0; i<document.getElementsByTagName('input').length; i++) {
var myInput = document.getElementsByTagName('input')[i];
if (myInput.type == 'radio')
{
//myInput is the radio element. Do something with it
}
}
I ended up using the value and name fields to target the element and check it. Here is the working script:
do JavaScript "var elements = document.getElementsByName('Level');
for (i=0;i<elements.length;i++) {
if(elements[i].value == 'p;29') {
elements[i].checked = true;
}
}" in doc

How to append Span to input field dynamically using native javascript

I have 5 input box in my page. I want to check if any field is blank, i will show the error message using a span tag appending to that input field.
Here is my code:
function validateForm() {
// Declare all the local variable
var inputElements, inputId, inputType, i, inputLength, inputNode;
// Get all the input tags
inputElements = document.getElementsByTagName("input");
for(i = 0, inputLength = inputElements.length; i < inputLength; i++) {
inputId = inputElements[i].id; // Get the input field ID
inputType = inputElements[i].type; // Get the input field type
// We will ONLY look for input[type=text]
if(inputType === "text") {
inputNode = document.getElementById(inputId);
if(inputNode.value === "") {
var spanTag = document.createElement("span");
spanTag.innerHTML = inputFieldBlankErrorMessage;
console.log(inputNode.appendChild(spanTag));
}
}
}
return false; // Do Nothing
}
This is what i am getting
It should append after the input tag. I am getting a weird tag which i don't need. Please help!!!
You can't .appendChild() anything to an input node, since an input can have no descendants.
Instead, you should insert the new node after it, or something similar.
inputNode.parentNode.insertBefore(spanTag, inputNode.nextSibling);
DEMO: http://jsfiddle.net/hMBHT/
Simply put you are not supposed to append any elements to input elements.
What you probably want is something like this:
<div class="field">
<input type="text" name="bla"/>
<span class="error">This field can't be blank!</span>
</div>
So you need to insert the span before or after the input element.
Here is an answer that shows you how.
I believe that your issue is that you are trying to append the span as a child of the input, not a sibling (which, I believe, is what you really want).
I can't to be sure without seeing your actual HTML, because I don't know how your inputs are situated in the DOM, but if they have separate parent elements, then you would replace:
inputNode.appendChild(spanTag);
. . . with
inputNode.parentNode.appendChild(spanTag);
Edit: FYI, the code that squint gave below (inputNode.parentNode.insertBefore(spanTag, inputNode.nextSibling);) would be how you could do it if all of the inputs are under the same parent element. It all depends on how the DOM structure is set up.

Categories