Selecting specific element within a div? - javascript

I am building a contact form, and I am having problems with jQuery. I want to select specific input fields that have an error and apply the class err. Unfortunately, my code selects all inputs when there is an error. I am having trouble identifying which part of my logic is wrong.
$('#send_mail').click(function(){
$("#contact_body").find('label').each(function(){
var contact_label = $('input[required=true], textarea[required=true]');
var label_check = $(this).find(contact_label);
$(contact_label).removeClass('err');
if (!$.trim($(label_check).val())){
$(contact_label).addClass('err');
}
});
});
The order of my HTML goes something like so:
#contact_body
<label>
<input>
</label>

This selects all input and textarea elements:
var contact_label = $('input[required=true], textarea[required=true]');
Instead, you should restrict it to the elements within the label:
var contact_label = $(this).find('input[required=true], textarea[required=true]');
Note that $(contact_label) and contact_label are equivalent in your code, as well as $(label_check) and label_check.
Also, you can use the state parameter of toggleClass() to simplify this:
contact_label.removeClass('err');
if (!$.trim(label_check.val())){
contact_label.addClass('err');
}
… to this:
contact_label.toggleClass('err', !$.trim(label_check.val()));
Here's the updated event:
$('#send_mail').click(function(){
$('#contact_body').find('label').each(function(){
var contact_label = $(this).find('input[required=true], textarea[required=true]');
var label_check = $(this).find(contact_label);
contact_label.toggleClass('err', !$.trim(label_check.val()));
});
});

I think your original code would work if you just changed this line:
$(contact_label).addClass('err');
To this:
$(label_check).addClass('err');
Because $(contact_label) references all the required inputs, whereas $(label_check) references only the input being checked.
But your code could be simplified, and you make unnecessary calls to $(), giving it an argument that is already a JQuery object.
I also do not see that you need to loop through the labels. You could loop through the required inputs instead.
$('#send_mail').click(function(){
$("#contact_body").find(':input[required]').each(function() {
var $input = $(this);
$input.removeClass('err');
if (!$.trim($input.val())){
$input.addClass('err');
}
});
});
Which could be shortened by using the .toggleClass() function:
$('#send_mail').click(function(){
$("#contact_body").find(':input[required]').each(function() {
$(this).toggleClass('err', !$.trim($input.val()));
});
});
Notes:
The selector ':input' matches <input>, <select> and <textarea> elements.

This is a slightly different approach. Gives a bit more flexibility.
arr = ['first', 'last', 'email', 'msg']; //IDs of fields to check
$('#send_mail').click(function(){
$('input, textarea').removeClass('err');
for (var i=0; i<arr.length-1; i++) { //Loop through all field IDs
if ( $('#'+arr[i]).val() == '' ) {
$('#'+arr[i]).addClass('err').focus();
return false;
}
}
//AJAX to send email goes here
alert('Email sent');
});
.err{background:yellow;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label for="first">First Name:</label>
<input id="first" type="text" required /><br>
<label for="last">Last Name:</label>
<input id="last" type="text" required/><br>
<label for="email">Email:</label>
<input id="email" type="email" required /><br>
<label for="msg">Message:</label>
<textarea id="msg" required></textarea>
<button id="send_mail">Send</button>

you can simplify the code, there will be less mistakes:
$('#send_mail').click(function(){
$("#contact_body").find('label').each(function(){
var field = $(this).find('[required=true]');
if ($.trim($(field).val())){
$(this).removeClass('err');
}
});
});

Related

Selecting all textbox at once with javascript

In my work we have to fill a lot of textboxes to do some validations. After all, we need to erase all - one by one - to restart the process.
Has some way to erase all textbox content with javascript (the only one method we can use now)? A for loop maybe?
You should put all the input fields in a form and then reset the form by the .reset() method.
document.getElementById("reset").onclick= ()=>{
document.getElementById("form").reset()
}
<form id="form">
<input/>
<input/>
</form>
<button id="reset">Reset</button>
See an example on W3Schools or the docs on MDN
If you want to restore the fields to their initial value, reset the form as suggested by #dota2pro's answer.
OTOH, if you want to clear the elements regardless of their initial value, you can query the elements using a type (aka "tag") CSS selector via Document​.query​SelectorAll()
and iterate through the elements as below:
function go() {
let inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
}
<input type="text" value="a"><br>
<input type="text" value="b"><br>
<input type="text" value="c"><br>
<br>
<button onclick="go()">click to clear</button>
Note that:
document.querySelectorAll('input') fetches all <input>s regardless of their type attribute.
document.querySelectorAll('input[type="text"]') fetches all <input type="text">.
document.querySelectorAll('textarea') fetches all <textarea>.
If you want to combine, you can use the comma combinator:
document.querySelectorAll('input[type="text"],textarea')
You can get in different ways in javascript:
By ID : document.getElementById("id")
By class: document.getElementsByClassName("class")
By tag:
document.querySelectorAll("input")
or Jquery
By ID : $("#id")
By class: $(".class")
By tag: $("input")
Read documentation about that here
tru
[...document.querySelectorAll('input')].map(x=>x.value='')
var clean = () => [...document.querySelectorAll('input')].map(x=>x.value='');
<button onclick="clean()">Clear</button><br>
<input type="text" value="some"><br>
<input type="text" value="short"><br>
<input type="text" value="text"><br>
Bellow code will select all editable text-boxes
document.querySelectorAll('input[type="text"]:not(:disabled):not([readonly]))')
If you have JQuery available, you can do:
$('input[type="text"]').val('');
Or, if you prefer native:
for(var i = 0; i < document.getElementsByTagName('input').length; i++){
document.getElementsByTagName('input')[i].value = '';
}

how to get input array value by key with javascript function?

Here is sample code i try to create input array with key and on change i want to get the value of individual input array value.
<input type="text" name="items[1]" value="443" onchange="get_items(1)">
<input type="text" name="items[2]" value="233" onchange="get_items(2)">
<script>
function get_items(key)
{
alert($("items["+key+"]").val());
}
</script>
Simply pass this context as argument and get value.
<input type="text" name="items[1]" value="443" onchange="get_items(this)">
<input type="text" name="items[2]" value="233" onchange="get_items(this)">
<script>
function get_items(ele) {
alert(ele.value);
}
</script>
Refer fiddle
HTML:
<input type="text" name="items[1]" value="443" onchange="get_items(1)">
<input type="text" name="items[2]" value="233" onchange="get_items(2)">
JS:
function get_items(key)
{
alert($('input[name="items['+key+']"]').val());
}
You can get the event's target from event,
function get_items(e) {
console.log(e.target.value);
}
<input type="text" name="items[1]" value="443" onchange="get_items(event)">
<input type="text" name="items[2]" value="233" onchange="get_items(event)">
or, better, attach your listener in javascript:
function get_items(e) {
console.log(e.target.value);
};
var inputs = document.querySelectorAll("input");
for (var i = 0, el; i < inputs.length; i += 1) {
el = inputs[i]
el.addEventListener("change", get_items);
};
<input type="text" name="items[1]" value="443">
<input type="text" name="items[2]" value="233">
Here is some code that does what (I think) you are trying to do:
<input type="text" name="item1" value="443" onchange="javascript:get_items(1)">
<input type="text" name="item2" value="233" onchange="javascript:get_items(2)">
<script>
function get_items(key)
{
//alert($("items["+key+"]").val());
var input = $('input[name="item' + key + '"]');
var value = input.val();
alert(value);
}
</script>
jsfiddle: https://jsfiddle.net/9kvv2q7p/4/
You can use this
function get_items(key) {
alert($("input[name='items[" + key + "]']").val());
}
I hope I was helpfull
Your HTML is missing a closing quote for the name attributes.
The name attribute should not contain [ or ]
characters. Adding these characters will complicate matters.
You should hook up your event handlers in JavaScript, not HTML.
When practical, elements should have unique id attributes added to them, which will make accessing and identifying them much easier in JavaScript and CSS
Rather than trying to identify the textboxes with indexes, just gather them up and place them into an array or array-like container, where indexes will be automatically assigned to them.
Here is a working example of how to get values by index:
// This will scan the DOM and place all matched elements into a node list
// which is an array-like object
var textBoxes = document.querySelectorAll("input[type=text]");
// Or, you can get references to them individually:
var txt1 = document.getElementById("txt1");
var txt2 = document.getElementById("txt2");
// And, put them into an array on your own:
var ary = [txt1, txt2];
// No matter how you got your references to them, it's best to hook
// them up to event handler in JavaScript, not HTML
txt1.addEventListener("change", get_items2);
txt2.addEventListener("change", get_items2);
function get_items(key) {
// You can certainly pass a key to this function
// to identify which element you are talking about
alert(textBoxes[key].value);
}
function get_items2(evt) {
// But, event handlers are automatically passed
// a reference to the object that fired the event
alert(evt.target.value);
}
get_items(0); // Call the function to get first textbox value
get_items(1); // Call the function to get second textbox value
<input type="text" id="txt1" name="txt1" value="443">
<input type="text" id="txt2" name="txt2" value="233">

How to have unique suggestion on input in SAPUI5

I am trying to get suggestions from input box, but if model has multiple values in wheelName like "wheel1", "wheel1", "wheel2", and with this, when I enter "wheel1" in inputbox, i get 2 suggestions as wheel1, wheel1, but i want unique suggestion i.e. wheel1 to be shown only once.
Input declaration looks like below:-
<Input
id="wheelInput"
type="Text"
placeholder="Enter Wheel..."
showSuggestion="true"
maxLength="40"
startSuggestion="3"
suggestionItems="{wheel>/results}" >
<suggestionItems>
<core:Item text="{wheel>wheelName}"/>
</suggestionItems>
</Input>
Assuming your results list differs with every character you type into your input, you can attach a function to the liveChange of the Input field.
You can then put your custom logic (e.g. no double names) into a separate model property. I haven't tested the code but Ii should work (provided I didn't make a typo).
View:
<Input
id="wheelInput"
type="Text"
placeholder="Enter Wheel..."
showSuggestion="true"
maxLength="40"
liveChange="filterWheelList"
startSuggestion="3"
suggestionItems="{wheel>/filteredWheelList}" >
<suggestionItems>
<core:Item text="{wheel>wheelName}"/>
</suggestionItems>
</Input>
Controller:
filterWheelList: function(){
var wheelModel = sap.ui.getCore().getModel("wheelModel");
var wheelList = wheelModel.getProperty("/results");
var uniqueNames = [];
var filteredWheelList = wheelList.filter(function(wheel){
if (uniqueNames.indexOf(wheel.wheelName) === -1){
uniqueNames.push(wheel.wheelName);
return true;
} else {
return false;
}
});
wheelModel.setProperty("/filteredWheelList", filteredWheelList);
}

making all form elements with class "form-control" editable

I'm trying to use javascript to make all elements in a given form with the readonly attribute editable on a click of a button.
so for i've only managed to get one input element to change as I was using the getElementById but as it is ID this is unique in HTML eyes.
How do I change this so I it targets all input elements with readonly?
see my code:
HTML:
Edit
<input class="form-control" type="text" id="editable" name="" value="someValue" readonly>
<input class="form-control" type="text" id="editable" name="" value="someValue2" readonly>
JAVASCRIPT:
document.getElementById('edit').onclick = function() {
document.getElementById('editable').readOnly = false;
};
Seeing as how you're open to a jQuery solution you could use:
$('#edit').click(function (e) {
e.preventDefault();
$('.form-control').removeAttr('readonly')
})
jsFiddle example
Note that since IDs must be unique I removed them and used the class to select the elements. The preventDefault is used to stop the link from being followed.
Try this
$("#edit").click(function() {
$("input.form-control").removeAttr("readonly");
});
If you use jQuery
Here is a plain javascript solution:
document.getElementById('edit').onclick = function(event) {
event.preventDefault();
var edits = [];
edits = document.getElementsByClassName('editable');
for(var i = 0; i<edits.length; i++){
edits[i].readOnly = false;
}
};
Notice
You had id='editable', I change it into class, cause you know ID is UNIQUE.
Here is a FIDDLE

Clone form and increment ID

Consider the following form:
<form>
<input type="button" value="Input Button"/>
<input type="checkbox" />
<input type="file" id="file"/>
<input type="hidden" id="hidden"/>
<input type="image" id="image" />
<input type="password" id="password" />
<input type="radio" id="radio" />
<input type="reset" id="reset" />
</form>
Utilizing Javascript (and jQuery), what would be the easiest way to clone the entire form and increment each individual id within, to ensure uniqueness.
Using jQuery I would assume you would clone the form initially via clone() and iterate through the cloned objects id and add the new id fieldname1, fieldname2 etc. However, my knowledge of jQuery isn't too great and this project is almost killing me.
Any help would be great!
You would clone() it, and before attaching the cloned element to the DOM, you'd run through and add the number to each id attribute.
(function() {
var count = 0;
window.duplicateForm = function()
var source = $('form:first'),
clone = source.clone();
clone.find(':input').attr('id', function(i, val) {
return val + count;
});
clone.appendTo('body');
count++;
};
})();
jsFiddle.
This one starts with 0, but you could easily start count with 1.
You could also use a closure if you wanted, i.e.
var cloneForm = function(form, start) {
start = start || 0;
return function() {
var clone = form.clone();
clone.find(':input').attr('id', function(i, val) {
return val + start;
});
start++;
return clone;
};
};
Then you would do...
var cloneContactForm = cloneForm($('#contact-form'), 5);
// Now I want to clone it and put it somewhere.
$(cloneContactForm()).appendTo('body');
jsFiddle.
Here's a solution without updating any ids:
Give all forms the same class
Give all fields a name
Refer to cloned forms relative to all the forms with the class
Refer to fields with their name
Example:
How about giving each cloned form a different id, and then using names for each input element?
<form class="theForm">
<input type="password" name="password" />
</form>
Then Clone it with
container.append($('.theForm:first').clone());
(or cache the first form in a variable).
Finally, access the input fields with:
$('form.theForm:eq(0) [name=password]') // password from first form
$('form.theForm:eq(1) [name=password]') // password from second form
...
If the selector lookup efficiency is a factor here then there are several trivial ways to speed it up, such as caching variables with the different forms, caching $('.theForm') and using the eq() method, etc.
Sample jsFiddle is here: http://jsfiddle.net/orip/dX4sY

Categories