I am working on a project. So when ever i edit the names stored in an array, the select box value wont update o the new name.
The select box names where all appended with a java script loop and its in same array witht the names.
Can any one solve this problems.
Here is my code for generating and filling the select box.
function displaycurrentName() {
for (let g = 0; g < arrMain.length; g++) {
const selectBx = document.createElement("option");
selectBx.text = arrMain[g][1];
selBox.options.add(selectBx)
// renameMe.value = selBox.value;
matchMe();
}
}
It works only once and wont work again when I make edits...
Related
I am trying to make a dynamic dropdown list and Section Navigation in Google Form. However, my script can auto delete the choice when the quota has been met, the choice can’t navigate to the related page for other selections.
I am planning a health check event for my hospital. It needs to reserve by timeslot and date due to the crow control policy. The links below are my Google Spreadsheet for the form and my daft Google Form of the function.
https://forms.gle/ZV9Djni8hyQGdAd86
https://docs.google.com/spreadsheets/d/1F1dpGCTSlpEOUMh5txsZouhx784JmJvh66IsiGfDTtg/edit?usp=sharing
Reference:
How to set the go to sections on a Google Forms question using app script
https://www.pbainbridge.co.uk/2019/04/dynamically-remove-google-form-options.html
function appointmentSlots() {
var form = FormApp.openById("1VqFBKBD_-iKYk_3Ze40j2tvRIi093-alaoCDsXpFi8k");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var date1timelist = form.getItemById("2101588132").asListItem();
var optionsSheet = ss.getSheetByName('Date Options');
var dateoptions = optionsSheet.getRange('A2:A3').getValues();
var dateleft = optionsSheet.getRange('C2:C3').getValues();
var day1sheet = ss.getSheetByName('9/3');
var day1timeoptions = day1sheet.getRange('A2:A4').getValues();
var day1left = day1sheet.getRange('C2:C4').getValues();
var formFieldsArray = [
["9/3", 2061926149],
["10/3", 1632977105]
];
for(var h = 2; h < formFieldsArray.length; h++) {
var datelist = form.getItemById(formFieldsArray[h][2]).asListItem();
var avaibledateoptions = [];
var sectionday1timeslots = form.getItemById("2101588132").asPageBreakItem();
var sectionday2timeslots = form.getItemById("1630116063").asPageBreakItem();
var datechoice = datelist.getChoices();
var optionsDataLength = dateoptions.length;
for (var i=0; i<optionsDataLength; i++) {
var choice = dateoptions[i][0];
var left = dateleft[i][0];
if ((choice != '') && (left > 0) == formFieldsArray[h][2]) {
if (formFieldsArray[h]= "9/3") {
datechoice.push(datelist.createChoice(avaibledateoptions,sectionday1timeslots));
}
else {
datechoice.push(datelist.createChoice(avaibledateoptions,sectionday2timeslots));
datelist.setChoices(avaibledateoptions);
}
}
}
}
var day1avaibledateoptions = [];
var optionsday1Length = day1timeoptions.length;
for (var i=0; i<optionsday1Length; i++) {
var day1timechoice = day1timeoptions[i][0];
var day1timeleft = day1left[i][0];
if ((day1timechoice != '') && (day1timeleft > 0)) {
day1avaibledateoptions.push(day1timechoice);
}
}
date1timelist.setChoiceValues(day1avaibledateoptions)
}
//etc for day2 timeslots choice and day3 timeslots
}
}
}
In order to modify your form depending on the changing cell values in your Spreadsheet (caused by new form submissions) you will need to set up an installable onChange trigger that will basically run your function when a change on your Spreadsheet is done (like one coming from a form submission). To create such a trigger, please access your trigger pannel and then click on Create trigger and select as the event type onChange assigning it to the function you will be using to create/delete the form items.
Once a user submits a new form and you do certain calculations on your Spreadsheet to determine how many slots are free for that time slot, you can take the value of the cell that tells you how many free appointments are free for that time and if that number is 0 you can proceed to delete that question element using the method deleteItem().
If you eventually end up resetting the form (because your time slot is free again or someone cancels the meeting), you can undo this by creating back the element.
The following piece of code is a basic example on how to delete and create form items based on the changes of a Spreadsheet cell. It has self explanatory comments:
function onChange() {
// Get the different sheets where you have all your left places in your time slots
var sheet = SpreadsheetApp.getActive().getSheetByName('A');
// Get your form
var form = FormApp.openById('FORMID');
// Here you would get each element that might depend on whether there are any
// appointments left or not
var element = form.getItems()[2];
// Get the cell value that tells you if the time slot is already full (full=0)
var value = sheet.getRange('C2').getValue();
// If the value is 0 it means that this time slot is all completed and nobody
// should be able to select it again
if (value == 0) {
// delete this item
form.deleteItem(element);
// if it is not full yet, it might be because your reset the time slot and therefore
// the element does not exist any more
} else {
// if the element exists dont do anything but if it doesnt and there are available
// apointments create it again
if (!element) {
form.addMultipleChoiceItem().setTitle('B').setChoiceValues(['Cats', 'Dogs']);
}
}
}
If you want to remove a choice option rather than an Item, you can look for the item, get all the choices as an array and then remove the choice you don't want any more from this array. Finally, you can update the item with your updated options with setChoices(). Here is a code example on how to achieve this:
function myFunction() {
// This is an example where I only have a single multiple choice item
var choiceItem = FormApp.getActiveForm().getItems(FormApp.ItemType.MULTIPLE_CHOICE)[0].asMultipleChoiceItem();
// Get current choices array
var choices = choiceItem.getChoices();
// Get choice you want to delete, this would be your times or dates obtained from
// the cell values
var choiceToBeRemoved = "A";
// remove choice from array
choices = choices.filter(function(choice){return choice.getValue() !== choiceToBeRemoved});
// Set updated choices
choiceItem.setChoices(choices);
}
References
setChoices
Javascript filter()
Hello I am having a small problem, I have about 4 select boxes each with different values in them for the user to choose from these are created dynamically in a loop within java script so they all share the same id.
I want to print each value selected dynamically so when you select from select box 1 print its value then when selecting box 2's option the first value is overridden.
The code I have now only works for the first select box, can anyone help me get it working for them all?
for(var i=0; i<5; i++){
var a=document.createElement("select");
aa.setAttribute('id', 'boxes');
//..addoptions in another loop then in the same loop I have
aa.onchange = function(){ tester();};
}
function tester(){
var i = document.getElementById("boxes");
var ii = i.selectedIndex;
document.getElementsById("pTag").innerHTML=i.options[ii].value
}
Javascript only please
Modify your code as follows it should fix your problem. Notice that aa.onchage = tester and not aa.onchange = tester() the reason is because you are assigning aa.onchange to the function tester and not its return value.
for(var i=0; i<5; i++){
var a=document.createElement("select");
aa.setAttribute('id', 'boxes'+i);
//..addoptions in another loop then in the same loop I have
aa.onchange = tester;
}
function tester(event){
document.getElementsById("pTag").innerHTML = event.target.value;
}
I have a form with radio buttons that I'm using javascript to loop through and return the sum of all the radio buttons to an input element at the bottom of the page. The script I'm using is this and it works fine.
<script type="text/javascript">
function checkTotal() {
var radios = document.querySelectorAll('input[type=radio]'),
sumField = document.querySelector('input[type=text]');
var sum = 0;
for (var i = 0, len = radios.length - 1; i <= len; i++) {
if (radios[i].checked) {
sum += parseInt(radios[i].value);
}
}
sumField.value = sum;
}
</script>
Here's my form http://cognitive-connections.com/Prefrontal_Cortex_Questionnaire.htm
However I need to build another form where there are several questions in different groups and I need to sum the totals for each group separately and post them to their corresponding input elements on the page accordingly. Here's my new form http://cognitive-connections.com/Prefrontal_Cortex_Questionnaire100913.htm
I'm not an advanced javascript user but do have a pretty good understanding of programming itself (I think, lol) My head tells me that I should be able to simply declare a unique var for each different group and a unique element to post it's results to and use the same loop (with correct vars for each group) for each group. But when I add [name="elements name"] as the identifier for the document.querySelectAll it grabs the elements with that name only and if I name the elements themselves the same name the radio buttons loose their inherent property of only letting one radio button per question be selected at a time? I've also tried creating a class id for each group and tried to use it as the identifier in the document.querySelectAll and it doesn't seem to work at all then. Any help is greatly appreciated..
As per my understanding of question, below is my answer. And here is the fiddle http://jsfiddle.net/8sbpX/10/.
function enableQ(cls) {
var ele = document.querySelectorAll('.' + cls)[0],
ev = (document.addEventListener ? "#addEventListener" : "on#attachEvent").split('#');
ele[ev[1]](ev[0] + "change", function () {
var radios = ele.querySelectorAll('[type="radio"][value="1"]:checked').length;
ele.querySelector('[type="text"]').value = radios;
});
}
enableQ("rad-grp");
So, I'll admit to being a bit of a JS noob, but as far as I can tell, this should be working and it is not.
Background:
I have a form with 3 list boxes. The list boxes are named app1, db1, and db2. I'm using javascript to allow the user to add additional list boxes, increasing the name tag for each additional select box.
When I add additional app named boxes, the value increments properly for each additional field. If I try to add addtional db named selects, it fails to recognize the 2nd tag on the first loop through the array. This causes me to end up with 2 elements named db2. On each subsequent tag, it is recognized properly and is properly incremented.
Here is the HTML for the db1 tag:
<select name="db1">
*options*
</select>
And db2:
<select name="db2">
*options*
</select>
The tags are identical. Here is the function that I am using to figure out the next number in the sequence (note: tag is either app or db, tags is an array of all select tag names in the DOM, if I inspect tags, it gives me ['app1', 'db1', 'db2', '']):
function return_select_name(tag, tags) {
matches = new Array();
var re = new RegExp(tag + "\\d+", "g");
for (var i = 0; i < tags.length; i++) {
var found = re.exec(tags[i]);
if (found != null) {
matches.push(found[0]);
}
}
matches = matches.sort();
index = parseInt(/\d+/.exec(matches.last())) + 1;
index = tag + index;
return index;
}
If I add an app tag, it will return 'app2'. If I search for a db tag, it will return 'db2' on the first time through, db3 on the 2nd, etc, etc.
So basically, I'm sure I'm doing something wrong here.
I'd handle it by keeping a counter for db and a counter for app to use to generate the names.
var appCounter = 1;//set this manually or initialize to 0 and
var dbCounter = 2;//use your create function to add your elements on pageload
Then, when you go to create your next tag, just increment your counter and use that as the suffix for your name:
var newAppElement = document.createElement('select');
newAppElement.name = 'app' + (++appCounter);
..
// --OR for the db element--
var newDbElement = document.createElement('select');
newDbElement.name = 'db' + (++dbCounter );
..
The problem you are getting is that regex objects are stateful. You can fix your program by putting the regex creation inside the loop.
function return_select_name(tag, tags) {
matches = new Array();
// <-- regex was here
for (var i = 0; i < tags.length; i++) {
var re = new RegExp(tag + "\\d+", "g"); //<--- now is here
var found = re.exec(tags[i]);
if (found != null) {
matches.push(found[0]);
}
}
matches = matches.sort();
index = parseInt(/\d+/.exec(matches[matches.length-1])) + 1; //<--- I dont think matches.last is portable, btw
index = tag + index;
return index;
}
In any case, if I were to do this myself, I would probably prefer to avoid the cmplicated text matching and just store the next tag indices in a variable or hash map.
Another suggestion: if you put parenthesis in your regex:
// /tag(\d+)/
var re = new RegExp(tag + "(\\d+)", "g");
Then you can use found[1] to get your number directly, without the extra step afterwards.
I know this has already been answered, but I put this together as a proof of concept.
http://jsfiddle.net/zero21xxx/LzyTf/
It's an object so you could probably reuse it in different scenarios. Obviously there are ways it could be improved, but I thought it was cool so I thought I would share.
The console.debug only works in Chrome and maybe FF.
With reference to the question regarding replicating values from one textbox to another
Replicating the values to another textbox
The solution works well if there are only two text boxes. But it fails when the index is running on loop.
For Ex - let us consider the table has list of text boxes in each row
1st row textbox1 textbox2
2nd row textbox3 textbox4
the id for each box is generated based on the status index. When I update the value in textbox1 textbox2 gets updated. But when I update textbox3 , instead of updating textbox4.textbox2 is updated.
Because the linked code updates textbox2 directly. Put the ids in an array and iterate over it to set the value of each text box, e.g.
function updateTextareas(el) {
var value = el.value;
for (var i=1, iLen=arguments.length; i<iLen; i++) {
document.getElementById(arguments[i]).value = value;
}
}
Then you can call it like:
document.getElementById('input1').onkeyup = function () {
updateTextareas(this,'textbox2','textbox3',...);
};
or some similar strategy.
Give all elements in the set the same name (or classname, and use getElementsByClassName). Then do the following pseudocode in javascript:
// onmodify:
var name = thisTextarea.name;
var newText = thisTextarea.text;
var elementsToUpdate = document.getElementsByName(name);
for each textarea in elementsToUpdate {
if (textarea != thisTextarea) // may not even need this line
textarea.text = newText;
}