VBA Cycle through check boxes in JavaScript Generated Table - javascript

I'm trying to check all of of the boxes in a JS generated table named tblItems
I have tried to getElementsByTagName("td") but it just loads everything as an HTML obj and I can't use InStr to find anything that differentiates them.
This is what I was trying to use to find a value I could use to pick out the check boxes.
Set AllChkBoxes = appIE.document.getElementById("tblItems").getElementsByTagName("td")
For Each box In AllChkBoxes
If InStr(UCase(box), "") <> 0 Then
MsgBox (box)
Else
MsgBox (box)
End If
Next box
End Sub
This is what the check boxes look like I was trying to cycle through the value but was unable to. there are a bunch of other td tag names but they are just values in the table or hrefs
<td align="center"><input type="checkbox" name="chkToPay" checked="" value="0"></td>
<td align="center"><input type="checkbox" name="chkToPay" checked="" value="1"></td>
<td align="center"><input type="checkbox" name="chkToPay" checked="" value="2"></td>
<td align="center"><input type="checkbox" name="chkToPay" checked="" value="3"></td>
Thanks to anyone that can help.

Would help to see more html. Looks like perhaps you can use an attribute = value selector for example. In the following I target the name attribute and associated value
Dim list As Object, i As Long
Set list = ie.document.querySelectorAll("[name=chkToPay]")
For i = 0 To list.Length - 1
Debug.Print list.item(i).Value
Next
You can also combine with a parent id if exists
Dim list As Object, i As Long
Set list = ie.document.querySelectorAll("#tableId [name=chkToPay]")
For i = 0 To list.Length - 1
Debug.Print list.item(i).Value
Next
You can also combine with another attribute to enhance specificity.
Dim list As Object, i As Long
Set list = ie.document.querySelectorAll("#tableId [type=checkbox][name=chkToPay]")
For i = 0 To list.Length - 1
Debug.Print list.item(i).Value
Next
You get the idea.
If you want to check a specific one add in the value attribute
ie.document.querySelector("#tableId [name=chkToPay][value='1']").Click

Might be below code help I am using jquery :
<table id="tableId">
<tr>
<td align="center"><input type="checkbox" name="chkToPay" value="0"></td>
<td align="center"><input type="checkbox" name="chkToPay" value="1"></td>
<td align="center"><input type="checkbox" name="chkToPay" value="2"></td>
<td align="center"><input type="checkbox" name="chkToPay" value="3"></td>
</tr>
$(document).on("click", '#tableId tbody :checkbox[name="chkToPay"]', function(event) {
var currentRows = $('#tableId');
$.each(currentRows, function() {
$(this).find(':checkbox[name=chkToPay]').each(function() {
if($(this). prop("checked") == true){
var parentTr = $(this).parents("tr");
$(this).prop('checked', true);
alert($(this).val());
// if you need text from another td you can access by below line
//alert(parentTr.children("td").eq(0).text());
}
});
});
});

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>

for statement keeps put first empty value

I'm trying to get only checked checkbox values
so I used for statement.
It goes well if I check from the first
but if I check from second It put empty value in array.
even I set this contidion, it still put empty value.
if (document.getElementsByName("check")[i].checked == true)
what is problem?
js
var arr_downloadName = new Array();
var chekced_download = 0;
$(".compress").click(function () {
var size = document.getElementsByName("check").length;
for (var i = 0; i < size; i++) {
if (document.getElementsByName("check")[i].checked == true) {
arr_downloadName[i] = document.getElementsByName("check")[i].value;
chekced_download++
}
}
});
html
<tr>
<td id="10Mb.dat"><input type="checkbox" name='check' value='10Mb.dat'
data-url="https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73751/world.topo.bathy.200407.3x21600x10800.jpg"/>File10MB
</td>
</tr>
<tr>
<td id="100mb.bin"><input type="checkbox" name='check' value='100mb.bin'
data-url="http://speedtest-ny.turnkeyinternet.net/100mb.bin"/>File100MB
</td>
</tr>
<tr>
<td id="500MB.test"><input type="checkbox" name='check' value='500MB.test'
data-url="http://nl.altushost.com/500MB.test"/>File500MB</td>
</tr>
<tr>
<td id="1000mb.bin"><input type="checkbox" name='check' value='1000mb.bin'
data-url="http://speedtest.tele2.net/1GB.zip"/>File1GB</td>
</tr>
<button class="btn btn-primary compress">압축하기</button>
This is happening because you're not specifying an element at index 0 (or previous indexes). Thus, if you try and add an element into an empty array at index 1 (which happens when you check the second checkbox) then you're array needs to put in an empty value in at index 0 so that it can add an element into index 1.
A solution to this would be to use .push which appends items to the end of your arr_downloadName array:
let chekced_download = 0;
$(".compress").click(function() {
let arr_downloadName = [];
var checkElem = document.getElementsByName("check");
var size = checkElem.length;
for (var i = 0; i < size; i++) {
if (checkElem[i].checked == true) {
arr_downloadName.push(checkElem[i].value);
chekced_download++
}
}
console.log(arr_downloadName);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr>
<td id="10Mb.dat"><input type="checkbox" name='check' value='10Mb.dat' data-url="https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73751/world.topo.bathy.200407.3x21600x10800.jpg" />File10MB
</td>
</tr>
<tr>
<td id="100mb.bin"><input type="checkbox" name='check' value='100mb.bin' data-url="http://speedtest-ny.turnkeyinternet.net/100mb.bin" />File100MB
</td>
</tr>
<tr>
<td id="500MB.test"><input type="checkbox" name='check' value='500MB.test' data-url="http://nl.altushost.com/500MB.test" />File500MB</td>
</tr>
<tr>
<td id="1000mb.bin"><input type="checkbox" name='check' value='1000mb.bin' data-url="http://speedtest.tele2.net/1GB.zip" />File1GB</td>
</tr>
<button class="btn btn-primary compress">압축하기</button>
As a side note, while it isn't needed, I recommend that you add a variable such as checkElem which holds your collection of elements. Then, instead of having to re-query the DOM each time you can instead just reference your element list, which will improve overall performance.
Also, I noticed that you're not making use of jQuery to it's fullest. Instead, you can get all the elements with the name check which are checked using a different selector:
$("[name='check']:checked")
and then .map all the elements selected to an to their values:
$(".compress").click(function() {
let arr_downloadName = $("[name='check']:checked").toArray().map(function(e) {
return e.value;
})
console.log(arr_downloadName);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr>
<td id="10Mb.dat"><input type="checkbox" name='check' value='10Mb.dat' data-url="https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73751/world.topo.bathy.200407.3x21600x10800.jpg" />File10MB
</td>
</tr>
<tr>
<td id="100mb.bin"><input type="checkbox" name='check' value='100mb.bin' data-url="http://speedtest-ny.turnkeyinternet.net/100mb.bin" />File100MB
</td>
</tr>
<tr>
<td id="500MB.test"><input type="checkbox" name='check' value='500MB.test' data-url="http://nl.altushost.com/500MB.test" />File500MB</td>
</tr>
<tr>
<td id="1000mb.bin"><input type="checkbox" name='check' value='1000mb.bin' data-url="http://speedtest.tele2.net/1GB.zip" />File1GB</td>
</tr>
<button class="btn btn-primary compress">압축하기</button>
try
if (document.getElementsByName("check")[i].checked != null)
seems your code will work. you are using incorrect variable to put the values in array. Make minor correction. i.e use 'chekced_download' instead of i as below, to push the values in array
arr_downloadName[chekced_download] = document.getElementsByName("check")[i].value;
Checked is a very sneaky HTML attribute
where if checked looks like
<input checked />
<input checked="checked" />
and produces true result
where if NOT checked looks like
<input />
which produces NULL - because there is no checked attribute. So check for the checked check. McCheck Check!
.checked != null
Hence you getting empty value.

How to clone form elements with auto increamented id to all elements

I have a form under a . I want to clone this and append dynamically in another and so on dynamically. Also I need to assign auto incremented id to all form elements too. Apart from pure javascript I can not use any jQuery or any other library.
Here is my HTML
<tr id="repeat">
<td><input type="text" id="fieldName" /></td>
<td>
<select name="fieldType" id="fieldType">
<option value="string">String</option>
</select>
</td>
<td><input type="radio" id="mandatory" name="mandatory" value="true" /><input type="radio" id="mandatory" name="mandatory" value="false" /></td>
<td>Delete Button</td>
</tr>
Here is my JavaScript
var i = 0;
this.view.findById("start").addEventHandler("click", function () {
var original = document.getElementById('repeat');
var clone = original.cloneNode(true);
original.parentNode.appendChild(clone);
})
Presently I can cloned the form elements in <tr id="repeated1"> dynamically and so on, but unable to assign auto incremented id to input box and select box . Also unable to assign auto incremented name to the radio buttons dynamically
You can change Id or another attribute as you want.
but for your code my solution is using querySelectorAll to get element and change it's Id, something like below code, it is tested and works nice:
Based on this HTML design code and JS function:
function MakeElementsWithDifferentId() {
for (var i = 1; i < 10; i++) {
var original = document.getElementById('repeat');
var clone = original.cloneNode(true);
clone.id="repeat"+i;
clone.querySelectorAll('[id="fieldName"]')[0].id ="fieldName"+i;
clone.querySelectorAll('[id="fieldType"]')[0].id ="fieldType"+i;
clone.querySelectorAll('[id="mandatory"]')[0].id ="mandatory"+i;
clone.children[2].children[0].name="mandatoryName"+i; //To change the radio name also
original.parentNode.appendChild(clone);
}
}
MakeElementsWithDifferentId();
<table>
<tr id="repeat">
<td><input type="text" id="fieldName" /></td>
<td>
<select name="fieldType" id="fieldType">
<option value="string">String</option>
</select>
</td>
<td><input type="radio" id="mandatory" name="mandatory" value="true" /> </td>
<td>Delete Button</td>
</tr>
</table>
the MakeElementsWithDifferentId() function make 10 batch elements with different Ids.
the JSFiddle Test
after run you can right click on element that you want and see the Id by inspect element.
Note:
Instead of clone.querySelectorAll('[id="fieldName"]')[0] it's better to get element by querySelector like clone.querySelector('[id="fieldName"]')
Hope will help you.

How to retrieve references from group Checkbox name arrays using JS or jQuery

I have a hard JS/jQuery riddle ! Hard because I couldn't find it on Google nor here, neither now, nor months ago when I was looking for it previously.
A large framework is using checkboxes in a table:
<table class="ListTable">
<tr>
<td><input name="blnChecked[70_20]" type="checkbox" value="1" id="some_unusable_gobbledy_gook" /></td>
<td></td>...
</tr>
<tr>
<td><input name="blnChecked[71_20]" type="checkbox" value="1" id="some_more_unusable_gobbledy_gook" /></td>
<td></td>...
</tr>
<tr>
<td><input name="blnChecked[70_25]" type="checkbox" value="1" id="some_further_unusable_gobbledy_gook" /></td>
<td></td>...
</tr>
</table>
I now need to collect all checkbox name references into an array: 70_20, 71_20 and 70_25 in the above example. Then join them up, and submit them as a URL parameter to a different page (although this joining is not essential to my question).
Question: Using JS/jQuery on the same page, how do I get these references from the name strings in these (checked) checkboxes in an array ?
I prefer not to use regexes (a bit messy, or 'overkill' for such a seeming trivial matter imho), although such a solution is not off my table.
(If someone asks why the table is structured as such: This is not my doing. But I can see that when such a form, in which this table is submitted to a PHP page, the PHP stores all such checkboxes into a single array, which is very nice, and I wanted to achieve a similar effect with JS/jQuery.)
A way to create on client side the array is based on using:
.map()
string .replace()
$('#btn').on('click', function(e) {
var retVal = $('table.ListTable :checkbox[name^="blnChecked["]:checked').map(function(idx, ele) {
//
// if the name value has always the same format...
//
return ele.name.replace('blnChecked[', '').replace(']', '');
//
// or....
//
// return ele.name.split('[').pop().replace(']', '');
// return ele.name.substr(11, 5);
//return ele.name.replace(/blnChecked\[(.*?)\]/g, '$1')
}).get();
var param = $.param({'param': retVal.join(',')});
console.log('Array: ' + retVal);
console.log('URL param: ' + param);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="ListTable">
<tr>
<td><input name="blnChecked[7125_2355]" type="checkbox" value="1" id="some_unusable_gobbledy_gook" /></td>
<td></td>
</tr>
<tr>
<td><input name="blnChecked[71_20]" type="checkbox" value="1" id="some_more_unusable_gobbledy_gook" /></td>
<td></td>
</tr>
<tr>
<td><input name="blnChecked[70_25]" type="checkbox" value="1" id="some_further_unusable_gobbledy_gook" /></td>
<td></td>
</tr>
</table>
<button type="button" id="btn">Click Me</button>

Finding the next td element using j query?

How can i find the next td element using jquery.
I am trying to append a text or a div to the td element inside a particular tr.
my tr is a server side control with tag runat=server
here is my query it is not working
var cssdisable= function testcss(rowid) {
if ($('#testcss').width() != 3) {
var id = $(rowid).find('td');
id.append('The following is not valid');
}
}
this is how i am calling the function with in a click event
cssdisable('<%=tr_myrow.ClientID %>');
It doesn't does anything, neither gives any error. i am trying to add a text after the td elemnent next to the row id passed.
Any ideas
here is the HTML
there is a row named tr_myrow
<table id="tblstudysub_animal" class="bond_qbs_table" width="100%">
<tr>
<td valign="top">
<h3>
Select the study subject.<span class="red">*</span></h3>
<fieldset>
<legend class="hide">Select the study subject.</legend>
<table id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj" border="0">
<tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_0" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Humans" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_0">Humans</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_1" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Non-Human primates" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_1">Non-Human primates</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_2" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Rodents" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_2">Rodents</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_3" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_studysubj" value="Others" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_studysubj_3">Others</label></td>
</tr>
</table>
</fieldset>
</td>
</tr>
<tr id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_tr_myrow">
<td valign="top">
<div id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_studysub_popul">
<h3>
Select your study subject.<span class="red">*</span></h3>
<fieldset>
<legend class="hide">Select your study subject.</legend>
<table id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul" border="0">
<tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_0" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_study_popul" value="Individuals" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_0">Individuals</label></td>
</tr><tr>
<td><input id="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_1" type="radio" name="ctl00$m$g_c09fd465_0ae4_479b_8fc6_21a7de645003$ctl00$rdb_study_popul" value="Population" /><label for="ctl00_m_g_c09fd465_0ae4_479b_8fc6_21a7de645003_ctl00_rdb_study_popul_1">Population</label></td>
</tr>
</table>
<div id="testcss">
</div>
I ma trying to add that text to the td in that row...
i hope this makes more clear...
One issue is that you are trying to query for the td by its id but are not using the # at the start of the selector..
try cssdisable('#<%=tr_myrow.ClientID %>');
Also in order to stick to just the td child of the tr use .children() instead of .find('td') (which will find all descendant td elements)
so
var cssdisable = function testcss(rowid) {
if ($('#testcss').width() != 3) {
var id = $(rowid).children().first();
id.append('The following is not valid');
}
}
Demo at http://jsfiddle.net/D4z9b/ (using your example HTML)
Give your <td>..</td> elements meaningful ids during the table build phase (if you don't build it, just assign them before starting any processing using a separate call) and then generate the id. Something like tableName + '_' + row + '_' will probably should do you fine.

Categories