JavaScript onBlur for multiple fields - javascript

I have a table that consists of many text input fields which the user can assign values to. My goal is that if the user "onBlur"s any of the fields then a function will activate. I could resolve the issue by marking each cell individually, however it would be very repetitive and i'm sure there's a more efficient way around this.
To demonstrate:
<table>
<tr>
<td>I</td>
<td><input type="text" id="whatever1"></td>
</tr>
<tr>
<td>Love</td>
<td><input type="text" id="whatever2"></td>
</tr>
<tr>
<td>Stack Overflow</td>
<td><input type="text" id="whatever3"></td>
</tr>
</table>
With JS:
var e1 = document.getElementById('whatever1');
e1.onblur = alias;
function alias() {
alert('started');
}
and then repeat this for each input box another 2 times. Or hopefully there's an easier way.

You can delegate the event and put a listener on a containing element:
var e1 = document.getElementById('containing-table');
e1.addEventListener('blur', function(e){
alert(e.target);
}, true);
and the modified html:
<table id="containing-table">
<tr>
<td>I</td>
<td><input type="text" id="whatever1"></td>
</tr>
<tr>
<td>Love</td>
<td><input type="text" id="whatever2"></td>
</tr>
<tr>
<td>Stack Overflow</td>
<td><input type="text" id="whatever3"></td>
</tr>
</table>
here's a fiddle: http://jsfiddle.net/oj2wj1d6/7/
The advantage of this is that you can actually remove and add input elements and the listener will capture events on new nodes. You can add conditional statements inside of the function in addEventListener in order to further filter how you would want to respond to different types of event targets.
with jQuery, you could do something as simple as:
$("table").on("blur", "input", function(e){
alert(e.target);
});
Some useful documentation to learn more:
The blur event, scroll down for details about event delegation.
addEventListener.
more about doing event delegation in vanilla JS

<table>
<tr>
<td>I</td>
<td><input class="blurMe" type="text" id="whatever1"></td>
</tr>
<tr>
<td>Love</td>
<td><input class="blurMe" type="text" id="whatever2"></td>
</tr>
<tr>
<td>Stack Overflow</td>
<td><input class="blurMe" type="text" id="whatever3"></td>
</tr>
</table>
Then in javascript
//inputs as NodeList
var inputs = document.querySelectorAll(".blurMe");
//Convertion to Array
var inputsArr = Array.prototype.slice.call(input);
// Loop to asign event
inputsArr.forEach(function(item){
item.onBlur = alias;
});

Add a common class to all your element and use this for select all element getElementByClassname. if you want see exact what if your curent element add parameter event your function. and e.target give you DOM element.

how about this ?
<script>
document.getElementById()
var arr = document.getElementsByClassName('whatever');
for(var i=0;i<arr.length;i++)
{
arr[i].onblur=alias;
}
function alias() {
alert('started');
}
</script>
<table>
<tr>
<td>I</td>
<td><input type="text" class="whatever"></td>
</tr>
<tr>
<td>Love</td>
<td><input type="text" class="whatever"></td>
</tr>
<tr>
<td>Stack Overflow</td>
<td><input type="text" class="whatever"></td>
</tr>
</table>

Related

Javascript / Jquery extract whole CLASS descriptor from a partial selection descriptor

I have a Javascript / Jquery function that controls groups of checkboxes.
The checkboxes are created on PHP form from a database call so I am iteratively going through a recordset and creating checkboxes in html.
For each checkbox I assign it a class of "checkboxgroup" + a numeric identifier to create a group of 'like' records.
I end up with multiple checkboxes like this:
<tr class="tablebody">
<td><input name="contactresolveid2048" id="contactresolveid2048" type="checkbox" class="checkboxgroup0"/></td>
<td>David Smith</td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19145" id="contactresolveid19145" type="checkbox" class="checkboxgroup0"/></td>
<td>graham Foots</td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19146" id="contactresolveid19146" type="checkbox" class="checkboxgroup0"/></td>
<td>Tom Silly</td>
</tr>
As you can see, these 3 checkboxes have a class of 'checkboxgroup0'
The following function detects a click on ANY of the checkbox groups on a form (of which there may be many) and unchecks any checkboxes (belonging to the same group) that are not the clicked one.
$('[class^="checkboxgroup"]').click(function() {
var thisClass = $(this).attr('class');
var $checkboxgroup = $('input.'+thisClass);
$checkboxgroup.filter(':checked').not(this).prop('checked', false);
});
Under most circumstances this works fine when the only class is 'checkboxgroup0'.
However when validation takes place JQuery validate appends a 'valid' or 'error' class to the class list of any fields that pass or fail validation, so I can endup having an .attr(class) of 'checkboxgroup0 valid'.
My question is this:
How do I return the whole class name of the partially selected class WITHOUT any extraneous classes?
By using the selector $('[class^="checkboxgroup"]') I need the whole part of that selector 'checkboxgroup0' and no other classes that may be assigned to it.
This issue you've encountered is one of the reasons why using incremental id/class attributes are not good practice.
To work around this issue with your JS you can instead use the same class on every checkbox. You can then group them by a data attribute instead. Using this method means that the number of classes on an element or their position within the class attribute string does not matter.
Try this example:
$('.checkboxgroup').click(function() {
let $this = $(this);
let $group = $(`.checkboxgroup[data-group="${$this.data('group')}"]`);
$group.not(this).prop('checked', false);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="tablebody">
<td><input name="contactresolveid2048" id="contactresolveid2048" type="checkbox" class="checkboxgroup" data-group="0" /></td>
<td><label for="contactresolveid2048">David Smith</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19145" id="contactresolveid19145" type="checkbox" class="checkboxgroup" data-group="0" /></td>
<td><label for="contactresolveid19145">graham Foots</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19146" id="contactresolveid19146" type="checkbox" class="checkboxgroup" data-group="0" /></td>
<td><label for="contactresolveid19146">Tom Silly</label></td>
</tr>
</table>
However, it's worth noting that what you're attempting to do can be far better achieved using HTML alone. Simply use a radio input and give them all the same name attribute, then you get the behaviour you're trying to create for free:
<table>
<tr class="tablebody">
<td><input name="contactresolve" id="contactresolveid2048" type="radio" /></td>
<td><label for="contactresolveid2048">David Smith</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolve" id="contactresolveid19145" type="radio" /></td>
<td><label for="contactresolveid19145">graham Foots</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolve" id="contactresolveid19146" type="radio" /></td>
<td><label for="contactresolveid19146">Tom Silly</label></td>
</tr>
</table>

sum of column using jquery [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I need to sum of column With OnKeyup or OnChange
Here's my code:
$(document).ready(function() {
$(".expenses").on('keyup change', calculateSum);
});
function calculateSum() {
var $input = $(this);
var $row = $input.closest('tr');
var sum = 0;
$row.find(".expenses").each(function() {
sum += parseFloat(this.value) || 0;
});
$row.find(".expenses_sum").val(sum.toFixed(2));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr>
<th>sl</th>
<th>TA</th>
<th>DA</th>
</tr>
<tr>
<td>1</td>
<td><input class="expenses"></td>
<td><input class="expenses"></td>
</tr>
<tr>
<td>2</td>
<td><input class="expenses"></td>
<td><input class="expenses"></td>
</tr>
<tr>
<td>Total</td>
<td><input class="expenses_sum"></td>
<td><input class="expenses_sum"></td>
</tr>
</table>
This is when the "context" of the input that matters: you want to update the sum that is in the same column where the input element was updated.
What you can do is:
Get the index of the <td> element the input belongs to
Calculate the sum of all expenses belonging to the same column. This is done by filtering (using .filter()) all .expenses elements to ensure that their parent's <td> index matches that you've determined in step 2
Set the sum on the corresponding .expenses_sum element in the same column. This is again, done by filtering all .expenses_sum elements and only getting the one whose parent <td> index matches
Some additional pro-tips:
Listen to the onInput event. For input elements, that covers onKeyUp and onChange events, for convenience.
Use <input type="number" /> to prevent users from erroneously entering non-numerical characters
Use <input readonly /> on the .expenses_sum element, so that users don't fiddle with that sum by their own
Remember to cast the value of the input elements to a number. This can be done by using the + operator, i.e. +this.value. Remember that as per spec, all input elements, regardless their type, always has their value in type of string
Chain .each(calculateSum) to your original selection, so that you also compute the sum when the page is first loaded, i.e. $(".expenses").on('input', calculateSum).each(calculateSum);. This is very helpful when the .expenses elements might be pre-populated with values from the server-side (or if you have manually defined value="..."), for example.
See proof-of-concept below:
$(document).ready(function() {
$(".expenses").on('input', calculateSum).each(calculateSum);
});
function calculateSum() {
// Get the index of the parent `<td>` element
var cellIndex = $(this).closest('td').index();
// Get the values of expenses in the same column as the `<td>` element
var allExpensesInSameColumn = $('.expenses').map(function() {
if ($(this).closest('td').index() !== cellIndex)
return;
return +this.value;
}).get();
// Calculate the sum from returned array of values
var sumOfExpensesInSameColumn = allExpensesInSameColumn.reduce(function(acc, curVal) {
return acc + curVal;
});
// Set the sum on the `.expenses_sum` element in the corresponding column
$('.expenses_sum').each(function() {
if ($(this).closest('td').index() !== cellIndex)
return;
this.value = sumOfExpensesInSameColumn;
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr>
<th>sl</th>
<th>TA</th>
<th>DA</th>
</tr>
<tr>
<td>1</td>
<td><input class="expenses" type="number" /></td>
<td><input class="expenses" type="number" /></td>
</tr>
<tr>
<td>2</td>
<td><input class="expenses" type="number" /></td>
<td><input class="expenses" type="number" /></td>
</tr>
<tr>
<td>Total</td>
<td><input class="expenses_sum" readonly></td>
<td><input class="expenses_sum" readonly></td>
</tr>
</table>

Get reference to element nested within another element

How do I go about getting a reference to an element nested inside another element I can find by getElementByID()?
I have this so far:
<table>
<tr id="templateRow" style="display: none;">
<td><input name="f_name[]" type="text"></td>
<td><textarea name="f_description[]" rows="4"></textarea></td>
<td><input name="f_category[]" type="text"></td>
</tr>
</table>
and have some JS that adds in copies of that to build out the table (removing the id and style attributes as I go).
Assuming I have a reference to the <tr>, how do I reference the input named f_name[] within that table row?
Background: For the moment I have temporary id's on the nested elements, removing them too as I go. The tricky situation I have is that I have a function that adds 1 row (and returns a reference to it), and another function that adds multiple rows (calling the addOneRow function) .. and I want the addManyRows function to end up setting the focus on the first row added.
In any reasonably recent browser, you can use the querySelector method to query for children of the element.
Example:
var templateRow = document.getElementById('templateRow');
var f_name = templateRow.querySelector('[name="f_name[]"]');
var f_description = templateRow.querySelector('[name="f_description[]"]');
var f_category = templateRow.querySelector('[name="f_category[]"]');
console.log(f_name.outerHTML);
console.log(f_description.outerHTML);
console.log(f_category.outerHTML);
<table>
<tr id="templateRow" style="display: none;">
<td><input name="f_name[]" type="text"></td>
<td><textarea name="f_description[]" rows="4"></textarea></td>
<td><input name="f_category[]" type="text"></td>
</tr>
</table>
Use Element#querySelector method and where use attribute equals selector to get based on the attribute.
tr.querySelector('td input[name="f_name[]"]')
var tr = document.getElementById('templateRow');
tr.querySelector('td input[name="f_name[]"]').style.color = 'red';
<table>
<tr id="templateRow" style="">
<td>
<input name="f_name[]" type="text">
</td>
<td>
<textarea name="f_description[]" rows="4"></textarea>
</td>
<td>
<input name="f_category[]" type="text">
</td>
</tr>
</table>

jQuery: How to check if certain checkboxes are checked, and change styles accordingly?

I've been trying to figure this out, but am not sure in which way to approach it using jQuery. I have a table of classes, and according to the classes that are checked, I want to change the background of tbody to reflect that this requirements are met.
<tbody>
<tr class="active header">
<th colspan="5"><b>Math (3 Courses)</b></th>
</tr>
<tr>
<td>MAC2311</td>
<td>Calculus I w/ Analytic Geometry</td>
<td>4</td>
<td></td>
<td><input type="checkbox" name="math" value="MAC2311"></td>
</tr>
<tr>
<td>MAC2312</td>
<td>Calculus II w/ Analytic Geometry</td>
<td>4</td>
<td>MAC2311 or MAC2281</td>
<td><input type="checkbox" name="math"value="MAC2312"></td>
</tr>
<tr>
<td>MAC2281</td>
<td>Calculus for Engineers I</td>
<td>4</td>
<td></td>
<td><input type="checkbox" name="math" value="MAC2281"></td>
</tr>
<tr>
<td>MAC2282</td>
<td>Calculus for Engineers II</td>
<td>4</td>
<td>MAC2311 or MAC2281</td>
<td><input type="checkbox" name="math" value="MAC2282"></td>
</tr>
<tr>
<td>Math Elective</td>
<td>(Math Elective)</td>
<td>4</td>
<td>MAC2312 or MAC2282</td>
<td><input type="checkbox" name="math" value="math_elective"></td>
</tr>
</tbody>
so, for example, if MAC2311, MAC2312, and math_elective are checked, tbody's background color can change green to signify completion of the section.
You can select all of the checked inputs with the :checked selector:
$("input[type=checkbox]:checked")
To see if any of the checkboxes are checked:
var isAtLeastOneChecked = ($("input[type=checkbox]:checked").length > 0);
if (isAtLeastOneChecked) {
// color your tbody
}
You can use the change handler like
.selected {
background-color: green;
}
then
jQuery(function ($) {
$('input[name="math"]').change(function () {
var $tbody = $(this).closest('tbody');
$tbody.toggleClass('selected', $tbody.find('input[name="math"]:checked').length == 3)
})
})
Demo: Fiddle
Here we adds the class selected to the tbody if there is 3 checked checkboxes
$(document).ready(function(){
$("#youTableId input").click(function () {
//Now $(this) will point to the element that has raised the event
and you can do something like this
alert($(this).is(':checked'));
//Now you now $(this) is the element that raised the event.
//You can get all the attributes of the element like name, id value, whether its check or not etc by using attr() function.
$(this).attr("value");
});
}
You probably want to assign ID's to your input and td elements.
var MAC2311 = document.getElementById('idOfThatInput');
var 2311td = document.getElementById('idOftd');
if (MAC2311.checked)
("#2311td").css("background", "green");
or use an Array containing the elements desired to be checked, and do the comparison in a for loop instead of individually.

if input field has a value found in array, do this (jQuery/Javascript)

I've got a page with a handful of input fields.
I need to find the fields with an array of values, and if so, .remove() the closest('tr')
The markup is similar to this
<table>
<tr>
<td>
<input type="text" value="this">
</td>
</tr>
<tr>
<td>
<input type="text" value="that">
</td>
</tr>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
I need to find "this" and "that", and if they are there, remove their <tr> container (and themselves) so I'd end up with:
<table>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
I've tried this:
jQuery(document).ready(function($){
var badfields = ['this', 'that'];
var fieldvalue = $('input[type="text"]').val();
if($.inArray(fieldvalue, badfields) > -1){
$(this).closest('tr').remove();
}
});
but it doesn't seem to want to work?
You need to iterate over all the fields using .each, so something like this:
$('input[type="text"]').each(function() {
var fieldvalue = $(this).val();
if ($.inArray(fieldvalue, badfields) > -1) {
$(this).closest('tr').remove();
}
});
Example: jsfiddle
You can be very concise sometimes with jQuery. jQuery has content selectors you can use for this type of purpose:
$("input[type=text][value=this], [value=that]").parents("tr").remove();
since you don't necessarily know this or that beforehand, you can do something like this:
var badfields = ['this', 'that'];
$(badfields).each(function(i) {
$("input[type=text][value=" + this + "]").parents("tr").remove();
});
You can use each to iterate through the selector. this in your inArray scope is not the element you were looking for.
DEMO: http://jsfiddle.net/
html:
<table>
<tr>
<td>
<input type="text" value="this">
</td>
</tr>
<tr>
<td>
<input type="text" value="that">
</td>
</tr>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
js:
jQuery(document).ready(function($){
var badfields = ['this', 'that'];
$('input[type="text"]').each(function(){
if( $.inArray(this.value, badfields) > -1 ){
$(this).closest('tr').remove();
}
});
});

Categories