Get selected checkbox(dynamically created) value in javascript - javascript

I'm using the following code snippet for create a dynamic checkbox.
This code snippet is inside of the for loop.based on the for loop the check boxes will create.The main function is called in the html onload.
This functionality is working fine.But if I choose the check box I need to get the value of the check box.I use the addEventListener its not working fine.
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.name = "name";
checkbox.value = teamIds;
checkbox.id = i;
checkbox.addEventListener("click",setTeamIdsinTextBox(teamNamesToShow),false);
body.appendChild(checkbox);
Now I need, if I select the two checkboxes and I want to pass the both values to the setTeamIdsinTextBox function with comma separate string.
How can I do this? I need to achieve this with the javascript alone.
so I need to frame the selected checkbox values like
var teamNamesToShow ="firstselectedcheckboxvalue,secondselectedcheckboxvalue"
Thanks in Advance.

The click listener needs to iterate over the checkboxes and collect the ids of those that are checked. You can use a selector to get just the checked ones, or filter the checked ones later which allows for a less complex selector.
The following uses the more complex selector but simpler map callback:
window.onload = function(){
var form = document.forms['form0'];
for (var i=0; i<10; i++) {
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = 'name' + i;
checkbox.value = 'value' + i;
checkbox.id = 'cb' + i;
checkbox.addEventListener("click",
setTeamIdsinTextBox,
false);
form.appendChild(checkbox); // add checkboxes to form, not body
}
}
function setTeamIdsinTextBox() {
var form = this.form;
var cbs = Array.from(form.querySelectorAll('input[type="checkbox"]:checked'));
var ids = cbs.map(function(cb) {return cb.id});
form.ta0.value = ids.join(', ');
}
<form id="form0">
<textarea id="ta0" name="ta0"></textarea>
</form>
The body of the function could be:
this.form.ta0.value = Array.from(this.form.querySelectorAll('input[type="checkbox"]:checked')).map(function(cb) {return cb.id}).join(', ');
but I think splitting it over a couple of lines is more sensible.
Edit
Array.from was introduced in ECMAScript 2015 so may not be available in all implementations in use. There's a polyfill at MDN that can be included to provide support where lacking. Also, it can be replaced with Array.prototype.slice, which has ubiquitous support.
Instead of:
Array.from(form.querySelectorAll('input[type="checkbox"]:checked'));
use:
[].slice.call(form.querySelectorAll('input[type="checkbox"]:checked'));
however that may fail in IE 8 as (from memory) it doesn't allow calling built–in methods with a host object as this. In that case, go directly to map and provide a polyfill for IE 8:
[].map.call(form.querySelectorAll('input[type="checkbox"]:checked'), function(cb) {return cb.id});
That will work in IE 8 as the polyfill for map means that it's a native function, not built–in so using a NodeList as this is OK. Versions of IE with map are OK with the host object thing.

In the for loop which you are iterating maintain an int variable which gives you the exact no. of checkboxes which you are going to create.And then using that again iterate through a for loop for that int variable and check for each checkbox whether it is checked or not.
int countCheckBox=0;
var listOfCheckBoxVal='';
function setTeamIdsinTextBox(){
for(int i =1; i<=countCheckBox;i++){
if(document.getElementById(i).checked==true){
listOfCheckBoxVal += document.getElementById(i).value+",";
}
}
Now this listOfCheckBoxVal variable will have the list of values of checked checkboxes seperated by a comma.

Related

Sharepoint Multiline Values on Load

I am trying to capture all of the fields of a SharePoint form using JavaScript during the initial load of the edit form. Somehow, only the first two multi-line fields are being captured properly. When I change the order of the fields this works. For example:
Field 1
Field 2
Field 3
Fields 1 & 2 are captured.
If I change the order they appear:
Field 2
Field 3
Field 1
Fields 2 & 3 are captured.
This doesn't appear to be affected by the code itself, but something to do with loading in SharePoint. But here is the code anyways:
$(window).load(function()
{
if(document.readyState === 'complete')
{
getFields();
getValues();
var myStatement = $("textarea[Title='Problem Statement']").closest("span").find("iframe[Title='Rich Text Editor']").contents().text();
var myScope = $("textarea[Title='Scope']").closest("span").find("iframe[Title='Rich Text Editor']").contents().text();
}
});
I am also using SPUtility to capture values and am having difficult getting support elsewhere.
SPUtility code:
scope = SPUtility.GetSPField('Scope');
scopeVal = scope.GetValue();
All of the fields are being captured per the above code in getFields() and getValues() called in the above code during window.load.
Any help or advice is appreciated.
Every field is embedded in a <td> that contains the following HTML comment:
<!-- FieldName="Field1"
FieldInternalName="Field1"
FieldType="SPFieldNote"
-->
While you can't explicitly query the DOM for this comment, you can query to get all the fields on the form and then loop through them, checking their innerHTML property to see if they contain the desired comment string.
By this means, you can determine the exact parent <td> element for any desired field. This allows you to be more precise than by using jQuery's .closest() function.
The other thing to keep in mind is that enhanced rich text, rich text, and plain text multiline fields are each rendered differently, and will thus require different query selector parameters to obtain their values.
The following example code gets the values of multiline fields with internal names of Field1, Field2, or Field3, and stores the values in an object.
var richTextFieldNames = ["Field1","Field2","Field3"];
var richTextFieldValues = {};
var fieldRows = document.querySelectorAll(".ms-formtable td.ms-formbody");
for(var i = 0, len = richTextFieldNames.length; i<len; i++){
currentFieldName = richTextFieldNames[i];
for(var j = 0, jlen = fieldRows.length; j<jlen; j++){
var currentRow = fieldRows[j];
if(currentRow.innerHTML.indexOf("FieldInternalName=\""+currentFieldName+"\"") > -1){
var element = currentRow.querySelector(".ms-rtestate-field[role=\"textbox\"]"); // enhanced rich text
if(!element){
var iframe = currentRow.querySelector("iframe[title=\"Rich Text Editor\"]");
if(iframe){
element = iframe.contentDocument.querySelector("body"); // rich text
}else{
element = currentRow.querySelector("textarea"); // plain text
}
}
richTextFieldValues[currentFieldName] = element.innerText ? element.innerText : element.textContent;
break;
}
}
}
The values can then be accessed as properties of the richTextFieldValues object by using array or dot notation, e.g. var myScope = richTextFieldValues["Scope"]; or richTextFieldValues.Scope; (assuming Scope is the internal name of a multi-line field).

Dynamic dictionary using Javascript from two sources

I'm new to JavaScript, and I think at this point I may have bit off more than I could chew. Essentially, I'm trying to make a dictionary (which will eventually be serialized to JSON, if that's relevant) that allows the user to define any number of entries and set both the key and value as they wish. I'm up for another implementation ideas, but this is how I've tried to solve it so far.
I have a button that calls the following code, which is mimicked exactly for newVariableDescription class. This creates the text input boxes on the web form.
var nameElement = document.createElement("input");
nameElement.type = "text";
nameElement.className = "newVariableName";
var nameDiv = document.createElement("div");
nameDiv.type = "div";
nameDiv.appendChild(nameElement);
var newVariableNamesDiv = document.getElementById("newVariableNamesDiv");
newVariableNamesDiv.appendChild(nameDiv);
var descriptionElement = document.createElement("input");
descriptionElement.type = "text";
descriptionElement.className = "newVariableDescription";
var descriptionDiv = document.createElement("div");
descriptionDiv.type = "div";
descriptionDiv.appendChild(descriptionElement);
var newVariableDescriptionsDiv = document.getElementById("newVariableDescriptionsDiv");
newVariableDescriptionsDiv.appendChild(descriptionDiv);
Now, this part works. I get all of the text boxes showing up just like I want, and can type into them. However, I can't figure out how to dynamically get access to this list AND pair them together.
This thread is very similar to what I want to do: dynamic dictionary using javascript
But I can't figure out how to get this code to do what I want:
var dictionary = {};
$('.newVariableName).each(function (index) {
dictionary['['+index+'].Key'] = $(this).val();
dictionary['['+index+'].Value'] = //access corresponding newVariableDescription here
});
I can obviously create a second loop with the other class (newVariableDescription), but that won't tie them together properly. I could store each of them in their own separate lists, and then combine those two lists into a dictionary, but I'm concerned about order remaining consistent and that's not an elegant solution.
Thanks in advance for any help.
If i understand right you want something like this with :eq selector
var dictionary = {};
$('.newVariableName').each(function (index) {
dictionary['['+index+'].Key'] = $(this).val();
dictionary['['+index+'].Value'] = $('.newVariableDescription:eq('+index+')').val();
});

Javascript reference element created from appendchild?

I am creating tables with the appendchild method. They contain checkboxes. I would like to be able to have the user to click a checkbox and have it run a function. I need the function to access the other checkbox and see if its checked or not. Currently I can' seem to reference the table or checkboxes at all.
My code for creating the table is:
function makeTable() {
var ItemA = Item.ItemName.options[Item.ItemName.options.selectedIndex].text;
var myParagraph=document.getElementById("myLine");
myForm = document.createElement("FORM");
mytable = document.createElement("TABLE");
mytablebody = document.createElement("TBODY");
var CB_Format = document.createElement('input');
CB_Format.type = 'checkbox';
CB_Format.name= "CB_Test";
CB_Format.value= 1;
CB_Format.setAttribute("name", "CBTest2");
CB_Format.onclick = changeColor;
theCell.appendChild(CB_Format);
var CB_Delete = document.createElement('input');
CB_Delete.type = "checkbox";
CB_Delete.name = "CB_Test";
CB_Delete.setAttribute("name", "CBTest2");
CB_Delete.value = 2;
CB_Delete.onclick = answer;
theCell.appendChild(CB_Delete);
My understanding is that my solution should be as simple as alert(document.form.checkbox.checked) but no matter what combination of possible names I try I get the error that it is null or not an object in both ie8 and firefox.
Thank you for your help
> function makeTable() {
> var ItemA = Item.ItemName.options[Item.ItemName.options.selectedIndex].text;
> var myParagraph=document.getElementById("myLine");
> myForm = document.createElement("FORM");
> mytable = document.createElement("TABLE");
> mytablebody = document.createElement("TBODY");
If you don't declare variables with var, they become global variables when first evaluated. Always declare variables.
> var CB_Format = document.createElement('input');
> CB_Format.type = 'checkbox';
> CB_Format.name= "CB_Test";
> CB_Format.value= 1;
> CB_Format.setAttribute("name", "CBTest2");
The above line changes the name property from the value assigned a couple of lines earlier, why do both? Just assign the correct value to the name property once:
CB_Format.name = "CBTest2";
The same goes for the use of setAttribute later. Note that setting the value of a property doesn't always change the associated attribute in some browsers, so always use properties unless there is a specific reason to use setAttribute,
[...]
My understanding is that my solution should be as simple as
alert(document.form.checkbox.checked) but no matter what combination
of possible names I try I get the error that it is null or not an
object in both ie8 and firefox. Thank you for your help
Form controls are made available as named properties of the form element. If there is more than one control with the same name, they are in a collecion. Assigning different values to the name property and attribute is asking for trouble. It should be that the second assignment overwrites the first, but no doubt there is a browser somewhere that will keep both values (one for the attribute and the other for the property).
The simple solution is to always use properties and only assign one value. If you want the name to be CBTest2 (since that is the second one assigned), then when the input is added to the form and the form to the document it will be available as:
document.forms['formName'].elements['CBTest2']
If the names are valid identifiers, then shorthand dot notation can be used:
document.formName.CBTest2
Since you have two elements with that name, the returned value will be a collection (a little like an array), so to get the first one, use:
document.formName.CBTest2[0]
You could use some code similar to...
var checkboxes = document.querySelectorAll('#some-form input[type="checkbox"]');
Array.forEach(checkboxes, function(checkbox) {
checkbox.addEventListener(function() {
var hasOtherCheckedCheckbox = Array.every(checkboxes, function(checkbox) {
return checkbox.checked;
});
});
});
Of course, for complete browser support, you'll need to modify this code a bit.

Why doesn't this javascript work assign .cells[] properly?

Why doesn't this work?
var row = document.getElementById(currentRow);
var otherRow = document.getElementById(targetRow);
row.cells[0] = otherRow.cells[0];
This works with
row.cells[0].innerHTML = otherRow.cells[0].innerHTML;
However, there are attributes attached to the cell which I also want to move over without having to manually recreate them.
Solution (Note: more is being done in my actual implementation, but this is the framework):
for (var i = 0; i < 4; i++) {
var copyTo = row.cells[i];
var copyFrom = otherRow.cells[i].cloneNode(true);
copyTo.parentNode.replaceChild(copyFrom, copyTo);
}
You should be able to use cloneNode() to actually clone the node and its attributes.
Each entry in cells refers to a DOMElement. When you typed row.cells[0] = otherRow.cells[0], you are saying that you want row.cell[0] to reference the same DOMElement as otherRow.cells[0].
I'm guessing you want row.cells[0] to have the same text or HTML as otherRow.cells[0]; in which case, the second code snippet will do just that, since you are actually modifying the DOMElement, and not just changing which DOMElement you are referencing.

problem with dynamicallly adding values to dropdown box

i want to dynamically add options to drop down boxes
var x =document.getElementById("c");
var optn = document.createElement("OPTION");
optn.text="hhh"
optn.value="val"
x.options.add(optn);
I am doing it inside a loop,with diff values of for val and hhh.Bur sometime i dont see any any values in drop down box , what may be the problem?
Try this one:
var objSelect = document.getElementById("subComponentOSID");
objSelect.options[objSelect.options.length] = new Option('1','1');
objSelect.options[objSelect.options.length] = new Option('2','2');
add is a method of HTMLSelectElement objects, not of HTMLCollection objects.
x.add(optn)
Assuming the element with the id "subComponentOSID", the only apparent issues in your javascript are missing semicolons on the lines where you assign values to optn.text and optn.value. Also, while most browsers will resolve what you mean when calling the add function on an options collection for a select element, you should move your add to the select itself. See the Mozilla reference for HTMLSelectElement, which provides an example.
In the meantime, try replacing the code snippet you provided with this:
var x =document.getElementById("subComponentOSID");
var optn = document.createElement("OPTION");
optn.text="hhh"; //Added semi-colon
optn.value="val"; //Added semi-colon
x.add(optn); // Moved add to HTMLSelectElement

Categories

Resources