Changing DOM with Select Option and checking no of required fields - javascript

There is a webpage with certain number of required fields that needs to be filled in order to submit a form successfully.
The biggest indicator of required field is that it has a * and its label has a class 'required' in it.
The number of required fields change when we change dropdown value. I have written some javascript and jquery code that changes the dropdown value and then checks the number of required fields but for some reason(most probably DOM changes is taking time and code executes before that so actually the change in number of required fields is not reflected in page). However if I change the dropdown value manually and then run the checkRequired() function, it works fine but I want to automate the procedure. How can I achieve that?
var count = 0;
var allRequired = []; // total number of required fields in the page
var newRequired = []; // change in the no. of required fields
$('select').each(function(){
var id = $(this).attr('id');
$('#'+id+' option').each(function() {
$(this).attr('selected','selected');
if(count == 0){
getAllRequiredFields();
}
else{
setTimeout(() => {
checkRequired();
for (let index = 0; index < allRequired.length; index++) {
console.log('for else',allRequired[index]);
if(!newRequired.includes(allRequired[index])){
console.log('allRequired',allRequired[index]);
}
}
}, 3000);
}
count++;
})
});
function getAllRequiredFields(){
$('span.required').each(function () {
var text = $(this).parent().text()
var id = $(this).closest("td").attr('id').split("_label")[0];
allRequired.push(id);
});
}
function checkRequired() {
newRequired = [];
$('span.required').each(function () {
var text = $(this).parent().text()
var id = $(this).closest("td").attr('id').split("_label")[0];
newRequired.push(id);
});
for (let index = 0; index < allRequired.length; index++) {
console.log('for else',count);
if(!newRequired.includes(allRequired[index])){
console.log('allRequired',allRequired[index]);
}
}
}

Just added change event fixed my problem
$('#'+id+' option').each(function() {
$(this).attr('selected','selected');
$('#'+id).change();
if(count == 0){
getAllRequiredFields();
}
else{
setTimeout(() => {
checkRequired();
for (let index = 0; index < allRequired.length; index++) {
console.log('for else',allRequired[index]);
if(!newRequired.includes(allRequired[index])){
console.log('allRequired',allRequired[index]);
}
}
}, 3000);
}
count++;
})

Related

How to keep duplicates from being added to an array

var reservations = [];
function addReservation() {
//Gets Input from textboxes.
var nameChosen = document.getElementById("txtName").value;
var roomChosen = document.getElementById("selRoom").value;
//adds input into the array.
reservations[reservations.length] = roomChosen + " ";
reservations[reservations.length] = nameChosen + " ";
//Gets input from radio button.
for (i = 0; i < document.getElementsByName("Day[]").length; i++) {
if (document.getElementsByName("Day[]")[i].checked) {
reservations.push(document.getElementsByName("Day[]")[i].value);
}
}
for (i = 0; i < document.getElementsByName("Time[]").length; i++) {
if (document.getElementsByName("Time[]")[i].checked) {
reservations.push(document.getElementsByName("Time[]")[i].value);
}
}
}
How do I ensure that if the time and day cannot be added twice to the array?
Or easier yet, How do I ensure that the same name cannot be added twice to the array?
Test if the item is in the array first
if (!item in array) { array.push(item); }
I think that you are looking for a way to break out of the for loop after you hit the first match. One way to do this is to set i to the termination condition inside the if statement, which will exit the loop.
//Gets input from radio button.
for (i = 0; i < document.getElementsByName("Day[]").length; i++) {
if (document.getElementsByName("Day[]")[i].checked) {
reservations.push(document.getElementsByName("Day[]")[i].value);
i = document.getElementsByName("Day[]").length
}
}
for (i = 0; i < document.getElementsByName("Time[]").length; i++) {
if (document.getElementsByName("Time[]")[i].checked) {
reservations.push(document.getElementsByName("Time[]")[i].value);
i = document.getElementsByName("Time[]").length
}
}

Function to display returned results count isn't working as expected

My jQuery checkbox filter works normally:
http://jsfiddle.net/EducateYourself/Lmehmj26/3/
Under checkbox form I want to show the number of results. It is 7 by default.
When I filter the results, it does not show the correct number of displayed results.
Could you please help me to find my mistake?
I commented the lines in my jsfiddle code where I added variable n to achieve the result I want.
$('.category').on('change', function () {
var n; //declare variable n
var category_list = [];
$('#filters :input:checked').each(function () {
var category = $(this).val();
category_list.push(category);
});
if (category_list.length == 0) {
$('.resultblock').show();
} else {
$('.resultblock').hide();
});
$('#count').text(n); // change the results qunatity
}
});
The problem is that you are incrementing n multiple times for a single element if it contains multiple matching tags.
You should only increment n once, at most, for each element:
Updated Example
$('.resultblock').each(function() {
var item = $(this).data('tag'),
itemArray = item.split(' '),
hasTag = false;
for (var i = 0; i < category_list.length; ++i) {
if (itemArray.indexOf(category_list[i]) >= 0) {
hasTag = true;
}
}
if (hasTag) {
$(this).show();
n++; // Only increment n once, at most, for each element.
}
});
Here is a cleaner, simplified version of your code:
Updated Example
$('.category').on('change', function() {
var categoryList = $('#filters :input:checked').map(function() {
return this.value;
}).get();
var count = 0;
$('.resultblock').hide().each(function() {
var itemTagsArray = $(this).data('tag').split(' ');
var hasTag = false;
categoryList.forEach(function(tag) {
if (itemTagsArray.indexOf(tag) > -1) {
hasTag = true;
}
});
if (hasTag) {
$(this).show();
count++;
}
});
$('#count').text(count);
});
You're counting doubles, a very easy fix is to add a check for visibility in your for loop like so
for (i = 0; i < category_list.length; ++i) {
if (itemArray.indexOf(category_list[i]) >= 0 && !$(self).is(":visible")) {
$(self).show();
n=n+1; //increase the value of n if found a result
}
}
As shown in this fiddle, that works
As a sidenote, your numbering breaks when you've selected one or more checkboxes and then deselect all. To prevent this you should change your check if there's been any checkboxes checked to
if (category_list.length == 0) {
$('.resultblock').show();
$('#count').text($('.resultblock').length);
}

How to delete 2 rows at a time using JavaScript

How to delete two rows at a time using JavaScript even though only for first row radio button exist?
Something like this:
1st row: (radiobutton) some textfield
2nd row: text field
On click of delete button, both the row should get deleted but the code which I have written is deleting only 1st row not 2nd one.
JavaScript code looks something like this:
function deleteReserveDetails() {
if (!document.forms[0].reserveRadiobutton) {
return;
} else {
var hidValue = parseInt(document.forms[0].Hd1Value.value);
var reserveRows = document.getElementById('reserveTable').getElementsByTagName('tr');
var headerNo = 1;
var radio = eval("document.forms[0].reserveRadiobutton");
if (radio.length == undefined) {
if (radio.checked) {
var hidValue1 = parseInt(document.forms[0].Hd1Value.value) - 1;
document.forms[0].Hd1Value.value = hidValue1;
document.getElementById('reserveTable').deleteRow(headerNo);
}
return;
}
var k = 0;
for (var j = 0; j < radio.length; j++) {
if (radio[j].checked) {
if (j == hidValue - 1) {
var hidValue2 = parseInt(document.forms[0].Hd1Value.value) - 1;
document.forms[0].Hd1Value.value = hidValue2;
}
document.getElementById('reserveTable').deleteRow(j + headerNo);
}
}
}
}
Could you please show me how to modify it to delete 2 rows at a time?

How do I highlight a javascript listbox item?

I have a function that swaps the selected item in a select box (listbox) with the item above it which works ok but I want to make it so that the item is still selected afterwords. So if the user wanted to keep moving the item upwards in the box he could keep pressing the Move Up button.
function moveUp() {
var list = document.getElementById('listbox');
var numSelected = list.selectedIndex;
var itemSelected = list.options;
if (itemSelected[numSelected].id == 0) {
alert("Can't move this up the list!");
} else {
if (poiArrayList[numSelected - 1] != null) {
var tempPOI = poiArrayList[numSelected];
poiArrayList[numSelected] = poiArrayList[numSelected - 1];
poiArrayList[numSelected - 1] = tempPOI;
//The line below is what I have but that doesn't seem to work.
list.selectedIndex = numSelected;
} else {
alert("The listbox is empty!");
}
}
}
Full code
Have a look here: http://jsfiddle.net/2ae9B/1/
I've added an optional parameter to generateListBox(), where you can set the index to be highlighted once the list is generated. For example:
function moveUp() {
var list = document.getElementById('listbox');
var numSelected = list.selectedIndex;
...
...
// regenerate the list passing the item to select
generateListBox(numSelected - 1);
}
and
function generateListBox(selectedIndex) {
var selectBox = document.getElementById("listbox");
selectBox.innerHTML = "";
for (var i = 0; i < poiArrayList.length; i++) {
lbAddItem(poiArrayList[i].name, i);
}
// you should also check that is a valid integer here
if(selectedIndex)
selectBox.selectedIndex = selectedIndex;
}
Hope it helps

Making a row editable based on a checkbox in HTML

I have a table in HTML. The contents of this table are dynamically populated. Every row of the table has text boxes and one checkbox. When the page is loaded, all the text boxes in the rows will be in a read-only state.
Now, i want to change the state of the text boxes in a particular row to editable, if the check-box in that row is selected. Also, the text boxes should be made read-only if the check box is de-selected.
How could I accomplish this using Javascript? Please help me.
stating this with plain javascript would be pure pain :)
i suggest using jQuery, eg:
$(':checkbox').click(function() {
var checkbox = $(this);
var row = checkbox.closest('tr');
var inputText = $('input[type=text]', row);
if (checkbox.is(':checked')) {
inputText.attr('readonly', 'readonly');
}
else {
inputText.removeAttr('readonly');
}
});
otherwise
function HandleClickOnCheckbox() {
var checkbox = this;
var row;
var iter = checkbox;
while (!row) {
iter = iter.parent;
if (iter == window) {
break;
}
if (iter.tagName == 'tr') {
row = iter;
break;
}
}
if (!row) {
alert('row not found');
return false;
}
var textBoxes = GetTextBoxes(row);
var method;
if (checkbox.checked) {
var disabledAttribute = document.createAttribute('disabled');
disabledAttribute.nodeValue = 'disabled';
method = function(textBox) {
textBox.setAttributeNode(disabledAttribute);
};
}
else {
method = function(textBox) {
textBox.removeAttribute('disabled', 0);
}
}
for (var i = 0; i < textBoxes.length; i++) {
var textBox = textBoxes[i];
method(textBox);
}
}
function GetTextBoxes(element) {
var textBoxes = new Array();
for (var i = 0; i < element.children.lenght; i++) {
var child = element.children[i];
if (child.tagName == 'input') {
if (child.type == 'text') {
textBoxes.push(child);
}
}
if (child.tagName == 'td') {
var childTextBoxes = GetTextBoxes(child);
if (childTextBoxes.length) {
for (var j = 0; j < childTextBoxes.length; j++) {
var childTextBox = childTextBoxes[j];
textBoxes.push(childTextBox);
}
}
}
}
return textBoxes;
}
this is not tested!
Perhaps, you can start by handling the click event of the checkbox using an if/else statement to check if the checkbox is actually checked. If it is you can use the row within which the checkbox resides to find all the textboxes in the different cells and enable/disable them.
Are you using JQuery or plain Javascript?
If you don't mind using jQuery, you could do:
$('checkbox').click(function() {
if ($(this).attr('checked')) {
$(this).parents('tr').children('input[type="text"]').each().attr('readonly', 'readonly');
} else {
$(this).parents('tr').children('input[type="text"]').each().removeAttr('readonly');
}
})
Or something like that. I'd have to test it to be sure.
Edited to reflect Andreas's comment.
Try this snippet (assumes that the checkbox has a class called "checkbox") if you are using Jquery.
jQuery('tr.checkbox').click(function() {
if (jQuery(this).is(":checked")) {
jQuery('td', this).removeAttr('disabled');
} else {
jQuery('td', this).attr('disabled', '');
}
});`

Categories

Resources