I am trying to create a message that shows "Correct" after user select a correct answer from options but I dont know why my code is not doing that. I have added the full code. After so many changes, I dont know why it is still not going through. The question and answer are in array of objects.
<script>
var questions = [{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"What does CPU stand for?","correct_answer":"Central Processing Unit","answers":["Central Process Unit","Computer Personal Unit", "Central Processing Unit", "Central Processor Unit"]},
{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"In the programming language Java, which of these keywords would you put on a variable to make sure it doesn't get modified?","correct_answer":"Final","answers":["Static", "Final", "Private","Public"]},
{"category":"Science: Computers","type":"boolean","difficulty":"easy","question":"The logo for Snapchat is a Bell.","correct_answer":"False","answers":["True", "False"]},
{"category":"Science: Computers","type":"boolean","difficulty":"easy","question":"Pointers were not used in the original C programming language; they were added later on in C++.","correct_answer":"False","answers":["True", "False"]},
{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"What is the most preferred image format used for logos in the Wikimedia database?","correct_answer":".svg","answers":[".svg", ".png",".jpeg",".gif"]},
{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"In web design, what does CSS stand for?","correct_answer":"Cascading Style Sheet","answers":["Counter Strike: Source","Corrective Style Sheet","Computer Style Sheet", "Cascading Style Sheet"]},
{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"What is the code name for the mobile operating system Android 7.0?","correct_answer":"Nougat","answers":["Ice Cream Sandwich", "Nougat", "Jelly Bean","Marshmallow"]},
{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"On Twitter, what is the character limit for a Tweet?","correct_answer":"140","answers":["120","160","100", "140"]},
{"category":"Science: Computers","type":"boolean","difficulty":"easy","question":"Linux was first created as an alternative to Windows XP.","correct_answer":"False","answers":["True", "False"]},
{"category":"Science: Computers","type":"multiple","difficulty":"easy","question":"Which programming language shares its name with an island in Indonesia?","answer":"Java","incorrect_answers":["Python","C","Jakarta", "Java"]}];
window.onload =function(){
var questionIndex = -1; // Not started
function submitAnswer() {
//document.body.innerHTML = '';
++questionIndex;
document.write(questions[questionIndex].question + "<br />");
for (var j=0; j < questions[questionIndex].answers.length; j++) {
document.write("<input type=radio id=myRadio name=radAnswer>" + questions[questionIndex].answers[j] + "<br />");
}
if (questionIndex < (questions.length - 1)) {
var nextButton = document.createElement("input");
nextButton.type = "button";
nextButton.value = "Submit Answer";
nextButton.addEventListener('click', submitAnswer);
document.body.appendChild(nextButton);
}
var userAnswer,
element = document.querySelector("#myRadio:checked");
if (element !== null) {
userAnswer = element.value;
} else {
userAnswer = null;
return "Select Answer"
}
if (userAnswer == questions[questionIndex].correct_answers) {
var message,
element = document.querySelector("#results");
if (element !== null) {
message = "Correct";
} else {
message = null;
return "Select Answer";
}
}
};
submitAnswer();
Everything is fine until this line:
document.body.appendChild(message);
You are trying to append a String value,but it's expecting a Node Object (i.e. parameter 1 is not of type 'Node'). Hence your code is not working properly.
Related
I have the following tag in my view.jsp:
<liferay-ui:input-localized id="message" name="message" xml="" />
And I know that I can set a XML and have a default value on my input localized. My problem is that I want to change this attribute with javascript. I am listening for some changes and call the function "update()" to update my information:
function update(index) {
var localizedInput= document.getElementById('message');
localizedInput.value = 'myXMLString';
}
Changing the value is only updating the currently selected language input (with the whole XML String). The XML String is correct, but I am not sure on how to update the XML for the input with javascript.
Is this possible?
PS: I have posted this in the Liferay Dev forum to try and reach more people.
After a week of studying the case and some tests, I think that I found a workaround for this. Not sure if this is the correct approach, but it is working for me so I will post my current solution for future reference.
After inspecting the HTML, I noticed that the Liferay-UI:input-localized tag creates an input tag by default, and then one more input tag for each language, each time you select a new language. Knowing that I created some functions with Javascript to help me update the inputs created from my liferay-ui:input-localized. Here is the relevant code:
function updateAnnouncementInformation(index) {
var announcement = announcements[index];
// the announcement['message'] is a XML String
updateInputLocalized('message', announcement['message']);
}
function updateInputLocalized(input, message) {
var inputId = '<portlet:namespace/>' + input;
var xml = $.parseXML(message);
var inputCurrent = document.getElementById(inputId);
var selectedLanguage = getSelectedLanguage(inputId);
var inputPT = document.getElementById(inputId + '_pt_PT');
inputPT.value = $(xml).find("Title[language-id='pt_PT']").text();
var inputEN = document.getElementById(inputId + '_en_US');
if (inputEN !== null) inputEN.value = $(xml).find("Title[language-id='en_US']").text();
else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
var inputLabel = getInputLabel(inputId);
if (selectedLanguage == 'pt-PT') inputLabel.innerHTML = '';
else inputLabel.innerHTML = inputPT.value;
if (selectedLanguage == 'pt-PT') inputCurrent.value = inputPT.value;
else if (inputEN !== null) inputCurrent.value = inputEN.value;
else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
}
function getSelectedLanguage(inputId) {
var languageContainer = document.getElementById('<portlet:namespace/>' + inputId + 'Menu');
return languageContainer.getElementsByClassName('btn-section')[0].innerHTML;
}
function getInputLabel(inputId) {
var boundingBoxContainer = document.getElementById(inputId + 'BoundingBox').parentElement;
return boundingBoxContainer.getElementsByClassName('form-text')[0];
}
function waitForElement(elementId, inputCurrent, inputId, xml) {
window.setTimeout(function() {
var element = document.getElementById(elementId);
if (element) elementCreated(element, inputCurrent, inputId, xml);
else waitForElement(elementId, inputCurrent, inputId, xml);
}, 500);
}
function elementCreated(inputEN, inputCurrent, inputId, xml) {
inputEN.value = $(xml).find("Title[language-id='en_US']").text();
var selectedLanguage = getSelectedLanguage(inputId);
if (selectedLanguage == 'en-US') inputCurrent.value = inputEN.value;
}
With this I am able to update the liferay-ui:input-localized inputs according to a pre-built XML String. I hope that someone finds this useful and if you have anything to add, please let me know!
To change the text value of an element, you must change the value of the elements's text node.
Example -
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue = "new content"
Suppose "books.xml" is loaded into xmlDoc
Get the first child node of the element
Change the node value to "new content"
I'm working in SharePoint 2013, and I have created a custom display template for a Content Search Web Part. Three of my fields use multi-select people pickers, and all three are returning the names in one string as shown below:
Brown, JohnSmith, MikeJones, Mary
I want to return the names in the format shown below but I just can't seem to get it to work:
Brown, John; Smith, Mike; Jones, Mary
I've tried the advice from these blog articles:
https://social.msdn.microsoft.com/Forums/en-US/ea0fe2fe-0757-4c1c-b3cc-2dd99b38bfa1/sharepoint-2013-custom-display-template-people-picker-field-separate-multiple-names-in-display?forum=sharepointdevelopment
https://sharedpointtips.blogspot.com/2015/01/sharepoint-2013-display-template.html
http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2014/02/26/useful-javascript-for-working-with-sharepoint-display-templates-spc3000-spc14.aspx
I've tried all the suggestions included in the first article - https://social.msdn.microsoft.com/Forums/en-US/ea0fe2fe-0757-4c1c-b3cc-2dd99b38bfa1/sharepoint-2013-custom-display-template-people-picker-field-separate-multiple-names-in-display?forum=sharepointdevelopment
In the Header:
'Response Preparer'{Response Preparer}:'ResponsePreparerOWSUSER'
In the body:
<script>
$includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
$includeScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Search/jquery-1.11.3.min.js");
$includeScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Search/splitNames.js");
RegisterSod('jquery-1.11.3.min.js', Srch.U.replaceUrlTokens("~sitecollection/_catalogs/masterpage/Display Templates/Search/jquery-1.11.3.min.js"));
RegisterSod('splitNames.js', Srch.U.replaceUrlTokens("~sitecollection/_catalogs/masterpage/Display Templates/Search/splitNames.js"));
//Register Dependencies
RegisterSodDep('splitNames.js', 'jquery-1.11.3.min.js');
AddPostRenderCallback(ctx, function () {
EnsureScriptFunc("splitNames.js", 'splitNames', function() {
var regulatorypartner = $getItemValue(ctx, "Regulatory Partner");
var splitregpartner = "";
splitregpartner = $splitNames(regulatorypartner);
});
});
</script>
In the JavaScript section I have tried this:
var regulatorypartner = ctx.RegulatoryPartnerOWSUSER;
var splitregpartner = splitNames(regulatorypartner);
This is my display code:
<td rowspan="2" colspan="4" style="text-align:center; border:0.5px solid #F88007;"> _#= splitregpartner =#_ </td>
The display should look like this:
Brown, John; Smith, Mike; Jones, Mary
Here is the output of regulatrypartner:
Brown, JohnSmith, MikeJones, Mary
Here is the splitNames code (file is included in the RegisterSod statement):
var newStr="";
for(var i=0;i<str.length;i++){
var char=str.charAt(i);
if(char==char.toUpperCase()){
newStr+=" "+char ;
}else{
newStr+=char;
}
}
return newStr;
}
Keep in your mind that it won't work for a person who has more then 2 capital letters in his name, there is no way to write something that works for all cases and converts to the format you are looking for unless you add an example for multiple words and unique names.
to_ReadableFormat("Brown, JohnSmith, MikeJones, Mary");
function to_ReadableFormat(regulatorypartner){
var counter = 0;
var fullString = "";
regulatorypartner.match(/[A-Z]/g).map(function (cap) { // loop through all the capitals
let regIndex = regulatorypartner.indexOf(cap);
if (counter != 0 && counter % 2 == 0) {
fullString += regulatorypartner.slice(0, regIndex) + ";";
regulatorypartner = regulatorypartner.slice(regIndex, regulatorypartner.length);
}
counter++;
});
fullString += regulatorypartner; // concat the remaining
return fullString;
}
I am looking for a solution to a novel problem I have encountered in applying google apps scripting to, specifically, the google form product.
Context
The company I work for currently performs Quality Assurance(QA) on software we create for our clients by sending feedback through email.
This software is composed of "Parents" and their "Children". I was asked to look into using Google Forms as a method of creating QA feedback for each piece of software created.
I was able to get very far along in this process leveraging the Google Apps Script documentation. However, I have hit a knowledge barrier when it comes to implementing this in the wild.
Problem
I have one script attached to a very basic form that asks for the Name of the Tool(how we track our QA requests), Name of the Parents, and the name of the children for this software. (Currently I am asking for email as well for ease, but will soon replace with the automatic email grabbing function google apps script has).
This script takes in the responses to this first form and creates a new one using the responses. Now, for building purposes, I have created a second google apps script in the script editor of a form that was created by a submission of the first form. This script takes in the responses of to this second form and creates a third (I know, "formception" right?).
After building all this out and being fairly satisfied with my results I realized a massive error in my thinking. Outside of testing purposes users will be making many new forms from that first one. Each of these new forms will not have the google apps script, that I created for the second form, associated with them and as such will not generate the needed third form.
I am know seeking help identifying a method that will let the code I have written for the second form be automatically added to each new form the first creates. If this is not possible, I am seeking any alternatives. I have considered methods of containing the second google apps script within the first's codebase but I could not find a way to trigger that function on submission of the second form from within the first's script. Any ideas or approaches to consider would be very much appreciated.
Code:
As a note; I do realize this code is a bit messy and very redundant. This was hacked together as a brief proof of concept. I plan to clean it up and modularize it if I can find a solution to the issue above. Before wasting time on that though, I want to determine if what I am trying to do is possible within the limits of Google Apps Script.
First Script
//A function to run this unweildy Formception beast
//Its set to be run on a submission event of the original "First QA Form" which resides in ********'s Drive -> QA -> Dynamic Google Form Project Folder
function onSubmit() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
//this whole loop just puts the responses into nested arrays
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
Logger.log('Response #%s to the question "%s" was "%s"',
(i + 1).toString(),
itemResponse.getItem().getTitle(),
itemResponse.getResponse());
}
}
//here we make another Form
var nextForm = FormApp.create('itemResponses[0].getResponse()');
//here we make a section for the questions that apply to the Tool as a whole
var generalSection = nextForm.addSectionHeaderItem();
generalSection.setTitle(itemResponses[0].getResponse());
//here we give the general section a checkbox item
var checkbox = nextForm.addCheckboxItem();
checkbox.setTitle('Which platforms did you test?');
checkbox.setChoices([
checkbox.createChoice('Chrome'),
checkbox.createChoice('FF'),
checkbox.createChoice('Safari'),
checkbox.createChoice('Vivaldi (Jokes)')
])
checkbox.setRequired(true);
//here we give the general section a multiple choice question and make it required
var generalLooks = nextForm.addMultipleChoiceItem()
.setTitle('Does this campaign look good in general?')
.setChoiceValues(['Yes','No'])
.setRequired(true);
//here we give the general section a place for comments
var generalComment = nextForm.addParagraphTextItem()
.setTitle('General comments:')
.setHelpText('Separate each comment with a return.')
.setRequired(false);
//here we give the general section a place for images to be submitted
var generalImg = nextForm.addParagraphTextItem()
.setTitle('General comment reference image links:')
.setHelpText('Separate each image link with a return.')
.setRequired(false);
//here we create a new section to conatin all the parents
var parentPage = nextForm.addPageBreakItem();
parentPage.setTitle(itemResponses[0].getResponse() + '| Parent(s)');
//here we create an array to conatain all the parent names
var parents = [{}];
//we populate this array with the responses to the second question of the "First QA Form" which asked for ther Parent names seperated by returns
parents = itemResponses[1].getResponse().split("\n");
//this for loop creates a section and series of questions related to each parent
for (var p = 0; p < parents.length; p++) {
//adds a section for each parent
var parentSection = nextForm.addSectionHeaderItem().setTitle(parents[p]);
//adds a yes or no question for each parent
var parentLooks = nextForm.addMultipleChoiceItem()
//sets the name of the question dynamically using the current parent
.setTitle('Does ' + parents[p] + ' look good in general?')
.setChoiceValues(['Yes','No'])
.setRequired(true);
//adds a comment section for each
var parentComment = nextForm.addParagraphTextItem()
.setTitle(parents[p] + ' comments:')
.setHelpText('Separate each comment with a return.')
.setRequired(false);
//adds an img section for each (there is potential to get into regex here and verify links)(there is also potential to replace with apps script UI stuff for direct upload)
var parentImg = nextForm.addParagraphTextItem()
.setTitle(parents[p] + ' image links:')
.setHelpText('Separate each image link with a return.')
.setRequired(false);
}
//end for loop
//makes a new page for the children
var childPage = nextForm.addPageBreakItem();
childPage.setTitle(itemResponses[0].getResponse() + '| Children');
var children = [{}];
children = itemResponses[2].getResponse().split("\n");
//this for loop creates a section and series of questions related to each child
for (var c = 0; c < children.length; c++) {
var childSection = nextForm.addSectionHeaderItem().setTitle(children[c]);
var parentSelect = nextForm.addListItem().setRequired(true);
parentSelect.setTitle('Which parent does this child belong to?');
parentSelect.setChoiceValues(parents);
//adds a yes or no question for each parent
var childrenLooks = nextForm.addMultipleChoiceItem()
.setTitle('Does ' + children[c] + ' look good in general?')
.setChoiceValues(['Yes','No'])
.setRequired(true);
//adds a comment section for each
var childrenComment = nextForm.addParagraphTextItem()
.setTitle(children[c] + ' comments:')
.setHelpText('Separate each comment with a return.')
.setRequired(false);
//adds an img section for each (there is potential to get into regex here and verify links)(there is also potential to replace with apps script UI stuff for direct upload)
var childImg = nextForm.addParagraphTextItem()
.setTitle(children[c] + ' image links:')
.setHelpText('Separate each image link with a return.')
.setRequired(false);
}
//end for loop
//we need the email of the account manager we want this to go to after we fill it out
var finalStep = nextForm.addSectionHeaderItem();
finalStep.setTitle('Final Step');
//this is a response field that grabs the email of the account manager, it is required.
var accountEmail = nextForm.addTextItem();
accountEmail.setTitle('What is the email of this account manager?').setRequired(true);
//grabs the form we just made's ID
var id = nextForm.getId();
//create the link that will be sent to the QAer to respond with content and images
var emailBody = 'https://docs.google.com/a/***********.com/forms/d/' + id + '/viewform';
//set the email of the QAer
var email = itemResponses[3].getResponse();
//set the subject of the email to the name of the Tool
var emailSubject = itemResponses[0].getResponse();
//send the email of the link to the new form to the QAer
MailApp.sendEmail({
to: email,
subject: emailSubject,
htmlBody: emailBody});
Second Form Script
//set to be run on a submission event of the second form "Next QA Form" which resides in ********'s Drive
function onLastSubmit() {
var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
//loop just puts the current responses into nested arrays
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
// Logger.log('Response #%s to the question "%s" was "%s"',
// (i + 1).toString(),
// itemResponse.getItem().getTitle(),
// itemResponse.getResponse());
}
}
//create a Form instance of our last(old) form. It will be usefull in accessing data like parent and child names
var previousForm = FormApp.openById('***********************');
var oldFormResponses = previousForm.getResponses();
//loop just puts the old responses into nested arrays
for (var i = 0; i < oldFormResponses.length; i++) {
var oldFormResponse = oldFormResponses[i];
var oldItemResponses = oldFormResponse.getItemResponses();
for (var j = 0; j < oldItemResponses.length; j++) {
var oldItemResponse = oldItemResponses[j];
// Logger.log('Response #%s to the question "%s" was "%s"',
// (i + 1).toString(),
// oldItemResponse.getItem().getTitle(),
// oldItemResponse.getResponse());
}
}
//some debugging and such
Logger.log(oldItemResponses[0].getResponse());
Logger.log(itemResponses[4].getResponse());
//oldItemResponses[0] = Name of Tool
var toolName = oldItemResponses[0].getResponse();
Logger.log(toolName);
//oldItemResponses[1] = parent names
var parentNames = oldItemResponses[1].getResponse();
Logger.log(parentNames);
//oldItemResponses[2] = child names
var childNames = oldItemResponses[2].getResponse();
Logger.log(childNames);
//oldItemResponses[3] = email of the QAer
var qaEmail = oldItemResponses[3].getResponse();
//newItemResponse[0] = tested platforms
var testedPlatforms = itemResponses[0].getResponse();
//make the last form
var lastForm = FormApp.create('Account Manager Response | ' + toolName);
//make a section for the general content
var generalSection = lastForm.addSectionHeaderItem();
generalSection.setTitle(toolName + ' | General Section');
//make a checkbox item for the CD to approve each of the platforms that the QAer says were tested
var testedCheckbox = lastForm.addCheckboxItem();
testedCheckbox.setTitle('If you agree a platform was accurately tested please check it off below.');
//use the array from the first response of the previous form (platforms that were tested) to generate a list of the tested platforms for the CD to approve
if ( Array.isArray(testedPlatforms)) {
testedCheckbox.setChoiceValues(testedPlatforms);
} else {
testedCheckbox.createChoice(testedPlatforms);
}
//set general section response variables
var genYesNo = itemResponses[1].getResponse();
var genComments = itemResponses[2].getResponse();
var genImgs = itemResponses[3].getResponse();
//if statement either says the general section looks good or makes a bunch of fields with the content the QAer left
if ( genYesNo == 'Yes') {
generalSection.setHelpText('Looks Good!')
} else {
//make a checkbox item for the CD to approve or not approve the general section QA feedback
if ( genComments != '') {
var generalCheckbox = lastForm.addCheckboxItem();
generalCheckbox.setTitle(toolName + ' | General Information and Comments');
generalCheckbox.setHelpText('Please check the boxes that you have fixed. Feel free to leave a note about any in the following section.');
if ( Array.isArray(genComments)) {
generalCheckbox.setChoiceValues(genComments);
} else {
generalCheckbox.createChoice(genComments);
}
}
//create a for loop to display image items for any linked images that were included by the QAer in the general section
if ( genImgs != '') {
if ( Array.isArray(genImgs)){
for (var gI = 0; gI < genImgs.length; gI++) {
var generalImg = lastForm.addImageItem();
generalImg.setTitle('General Section | Image ' + (gI + 1));
var genImg = UrlFetchApp.fetch(genImgs[gI]);
generalImg.setImage(genImg);
}
} else {
var generalImg = lastForm.addImageItem();
generalImg.setTitle('General Section | Image 1');
var genImg = UrlFetchApp.fetch(genImgs);
generalImg.setImage(genImg);
}
}
}
//make a paragraphTextItem for the CD to leave notes about this section if they would like
var generalNotes = lastForm.addParagraphTextItem()
.setTitle('Notes about the general section:')
.setHelpText('Leave notes here about any items you have not fixed and other things you would like the QAer to know.');
//make a new page for the parent content
var parentPage = lastForm.addPageBreakItem();
parentPage.setTitle(toolName + ' | Parent(s)');
//a variable that we can increment by 2 to account for there being 3 items in each parent
var incParent = 0;
//a loop that creates items for each parent including: new section, checkbox to approve content and image displays
for (var i = 0; i < parentNames.length; i++) {
var parYesNo = itemResponses[(i + incParent) + 5].getResponse();
var parComments = itemResponses[(i + incParent) + 5].getResponse();
var parImgs = itemResponses[(i + incParent) + 5].getResponse();
//create the new section for each parent
var parentSection = lastForm.addSectionHeaderItem();
//and name it
parentSection.setTitle(parentNames[i]);
//if statement to ensure we dont show any content if the QAer checked 'Yes' for looks good
//using incOne to ensure
if (parYesNo == 'Yes') {
parentSection.setHelpText('Looks Good!');
} else {
//create a checkbox list for all the comments the QAer listed if they clicked 'No' for looks good
if (parComments != '') {
var parentCheckbox = lastForm.addCheckboxItem();
parentCheckbox.setTitle(parentNames[i] + ' | QA Comments');
parentCheckbox.setHelpText('Please check the boxes that you have fixed. Feel free to leave a note about any in the following section.');
if (Array.isArray(parComments)) {
parentCheckbox.setChoiceValues(parComments);
} else {
parentCheckbox.createChoice(parComments)
}
}
}
//create the images the QAer listed if they clicked 'No' for looks good
if (parImgs != '') {
if (Array.isArray(parImgs)) {
for (var pI = 0; gI < parImgs.length; pI++) {
var parentImg = lastForm.addImageItem();
parentImg.setTitle(parentNames[i] + ' | Image ' + (pI + 1));
var parImg = UrlFetchApp.fetch(parImgs[pI]);
parentImg.setImage(parImg);
}
} else {
var parentImg = lastForm.addImageItem();
parentImg.setTitle(parentNames[i] + ' | Image ');
var parImg = UrlFetchApp.fetch(parImgs[pI]);
parentImg.setImage(parImg)
}
}
//increment to account for the other items in each parent
incParent += 2;
}
//end for loop
//make a new page for the children content
var childPage = lastForm.addPageBreakItem();
childPage.setTitle(toolName + ' | Children');
//determine how many parents there are and count three items for each
//also account for the items from the general section (4 items)
var parentItems = parentNames.length * 3;
var nonChildItems = parentItems + 4;
//a variable that we can increment by 4(the number of items in each child)
var incChild = 0;
//creates items for each parent including: checkbox to approve content and image displays
for (var j = 0; j < childNames.length; j++) {
var chiYesNo = itemResponses[nonChildItems + (j + incChild)].getResponse();
var chiComments = itemResponses[(j + incChild) + nonChildItems].getResponse();
var chiImgs = itemResponses[(j + incChild) + nonChildItems].getResponse();
//create sections for each child
var childSection = lastForm.addSectionHeaderItem();
childSection.setTitle(childNames[j] + ' | ' + itemResponses[nonChildItems + (j + incChild + 1)].getResponse());
if (chiYesNo == 'Yes') {
childSection.setHelpText('Looks Good!');
} else {
//create a checkbox list for all the comments the QAer listed if they clicked 'No' for looks good
if (chiComments != '') {
var childCheckbox = lastForm.addCheckboxItem();
childCheckbox.setTitle(childNames[j] + ' | QA Comments');
childCheckbox.setHelpText('Please check the boxes that you have fixed. Feel free to leave a note about any in the following section.');
if (Array.isArray(chiComments)) {
childCheckbox.setChoiceValues(chiComments);
} else {
childCheckbox.createChoice(chiComments);
}
}
}
//create the images the QAer listed if they clicked 'No' for looks good
if (chiImgs != '') {
if (Array.isArray(chiImgs)) {
for (var cI = 0; cI < chiImgs.length; cI++) {
var childImg = lastForm.addImageItem();
childImg.setTitle(childNames[j] + ' | Image ' + (cI + 1));
var chiImg = UrlFetchApp.fetch(chiImgs[cI]);
childImg.setImage(chiImg);
}
} else {
var childImg = lastForm.addImageItem();
childImg.setTitle(childNames[j] + ' | Image ');
var chiImg = UrlFetchApp.fetch(chiImgs[cI]);
childImg.setImage(chiImg);
}
}
//increment to account for the other items in each child
incChild += 3;
}
//end for loop
//grabs the form we just made's ID
var id = lastForm.getId();
//create the link that will be sent to the QAer to respond with content and images
var emailBody = 'https://docs.google.com/a/**************.com/forms/d/' + id + '/viewform';
//set the email of the QAer
var email = qaEmail;
//set the subject of the email to the name of the Tool
var emailSubject = toolName + ' | CD Response';
//send the email of the link to the new form to the CD
MailApp.sendEmail({
to: email,
subject: emailSubject,
htmlBody: emailBody});
}
Thanks in advance!
*edit for company privacy reasons.
I've been doing something very similar and have mostly been successful.
I was able to ensure code is moved over to newly created forms by creating a blank template form, with the necessary script attached.
When when a new form is needed with this script, I create a copy of the template document and then populate this with the necessary contents.
The only problem I have run into with this is being unable to easily set up triggers for code to run on form submission in these new forms. I have solved this by prompting the user to open the newly created form and click on a menu item I have added to 'initialise permissions'.
Unfortunately there is no way to programmatically attach a script to a form. In general, if you expect a script to be used on multiple forms, docs, etc, it's best to convert it to an add-on. This has the benefit of allowing you to make updates to the script over time, instead of each being a local copy.
Forms making forms making forms is also probably an anti-pattern. What you probably need is a more complex web app, which you can build in Apps Script but is quite a bit more involved.
Ok, in essence I want to create a short quiz that has a next and previous button. I want to loop through two arrays, questions and choices, and have a score at the end. I have read chapters on the DOM and Events and it is just not clicking apparently.
Really I need a little bit of code that shows a concrete example of how to manipulate the DOM. What I have so far are only the arrays, and a function declaring that x is in fact getting my element by id. haha.
Sorry I don't have more code to give. I tried to attach the id to a paragraph, and then get it by it's id and document.write the array, but that replaces the button. If you run the code below you'll see what I'm saying.
<!DOCTYPE html>
<html>
<head>
<title>Bom</title>
</head>
<body>
<input type="button" value="Iterate" id="myButton" onclick="iter_onclick()">
<p id="qArray">Some Text</p>
<script>
var qArray = ["Who is my dog?", "who is the prez?", "Who is my girlfriend?", "Who am I?"];
var cArray = [["Bill","Billy", "Arnold", "Tyler"],["Oz"," Buffon","Tupac","Amy"],["Tony Blair","Brack Osama","Barack Obama","Little Arlo"],["Emma Stone","Tony the Tiger","","The Smurf Girl"]];
function iter_onclick () {
var x = document.getElementById("qArray");
document.write("Hello World");
}
</script>
</body>
</html>`
Like I said, this is my first attempt at truly manipulating the DOM, and I know what I want to do. I just don't know how to do it. I am understanding all the syntax and events and objects and such. But, I'm not really sure how to apply it. Also, no Jquery. I want to know how to create applications with Javascript and then work my way into Jquery. Thanks people.
This will loop through your questions, hope this helps you to proceed.
var qArray = ["Who is my dog?",
"who is the prez?",
"Who is my girlfriend?",
"Who am I?"];
var cArray = [
["Bill", "Billy", "Arnold", "Tyler"],
["Oz", " Buffon", "Tupac", "Amy"],
["Tony Blair", "Brack Osama", "Barack Obama", "Little Arlo"],
["Emma Stone", "Tony the Tiger", "Amy Dahlquist", "The Smurf Girl"]
];
var index = 0;
function iter_onclick() {
//if this is the last question hide and displays quiz ends
if (index >= qArray.length) {
document.getElementById('qArray').innerHTML = '<div>Quiz End, Thank you</div>'
document.getElementById('myButton').style.visibility = 'hidden ';
return false;
}
var html = ' <div> ' + qArray[index] + ' </div> <div>';
for (var i = 0; i < cArray[index].length; i++) {
html += '<label><input type="radio" name="ans" value="'
+ cArray[index][i] + '"/ > ' + cArray[index][i] + ' </label>';
}
html += '</div > ';
document.getElementById('qArray').innerHTML = html;
index++;
}
Here's a very basic example you can work from. This modifies the existing DOM items. You cannot use document.write() on a document that is already loaded or it will clear everything you have and start over and it's not the most efficient way to put content into the DOM.
This example has a number of fields on the page, it loads a question and then checks the answer when you press the next button.
HTML:
<div id="question"></div>
<input id="answer" type="text"><br><br>
<button id="next">Next</button> <br><br><br>
Number Correct So Far: <span id="numCorrect">0</span>
Javascript (in script tag):
var qArray = ["Who is my dog?", "who is the prez?", "Who is my girlfriend?", "Who am I?"];
var cArray = [["Bill","Billy", "Arnold", "Tyler"],["Oz"," Buffon","Tupac","Amy"],["Tony Blair","Brack Osama","Barack Obama","Little Arlo"],["Emma Stone","Tony the Tiger","Amy Dahlquist","The Smurf Girl"]];
var questionNum = -1;
var numCorrect = 0;
function loadQuestion() {
++questionNum;
if (questionNum >= qArray.length) {
alert("all questions are done");
} else {
document.getElementById("question").innerHTML = qArray[questionNum];
document.getElementById("answer").value = "";
}
}
loadQuestion();
function checkAnswer() {
var answer = document.getElementById("answer").value.toLowerCase();
var allowedAnswers = cArray[questionNum];
for (var i = 0; i < allowedAnswers.length; i++) {
if (allowedAnswers[i].toLowerCase() == answer) {
return true;
}
}
return false;
}
document.getElementById("next").addEventListener("click", function(e) {
if (checkAnswer()) {
++numCorrect;
document.getElementById("numCorrect").innerHTML = numCorrect;
loadQuestion();
} else {
alert("Answer is not correct");
}
});
Working demo: http://jsfiddle.net/jfriend00/gX2Rm/
Following is the code where I display matched user input in the div but I want to hide the div when there is no match for user input. I can't seem to do it with the following code:
HTML code:
<input id="filter" type="text" placeholder="Enter your filter text here.." onkeyup = "test()" />
<div id="lc"> <p id='placeholder'> </p> </div>
JS code:
// JavaScript Document
s1= new String()
s2= new String()
var myArray = new Array();
myArray[0] = "Football";
myArray[1] = "Baseball";
myArray[2] = "Cricket";
myArray[3] = "Hockey";
myArray[4] = "Basketball";
myArray[5] = "Shooting";
function test()
{
s1 = document.getElementById('filter').value;
var myRegex = new RegExp((s1),"ig");
arraysearch(myRegex);
}
function arraysearch(myRegex)
{
document.getElementById('placeholder').innerHTML="";
for(i=0; i<myArray.length; i++)
{
if (myArray[i].match(myRegex))
{
document.getElementById('lc').style.visibility='visible';
document.getElementById('placeholder').innerHTML += myArray[i] + "<br/>";
}
else
{
document.getElementById('lc').style.visibility='hidden';
}
}
}
Regular expressions are a powerful tool but using them for so trivial a job is often troublesome.First you are using a direct input as regular expression which is never so good.
I copied your code and analyzed the logic you are making many many errors
for(i=0; i<myArray.length; i++)
{
if (myArray[i].match(myRegex))
{
document.getElementById('lc').style.visibility='visible';
document.getElementById('placeholder').innerHTML += myArray[i] + "<br/>";
}
else
{
document.getElementById('lc').style.visibility='hidden';
}
consider your code above, if I enter football, it matches with football, and football is shown. Next it checks for baseball which does not match and visibility changes to hidden!!
Better logic
1.Check what strings match, and add them to the division.
2.Check how many strings have matched, if none, change visibility to hidden.
You are using regular expressions when this actully can be achieved easily with indexOf();
these are pure logical errors
consider using jquery. (with a little http://underscorejs.org/ for utility)
var myArray = ["Football", "Baseball", "Cricket","Hockey", "Basketball", "Shooting"]
$("#filter").keyup(function() {
if(_.include(myArray, $(this).val()) {
$('#lc').show()
} else {
$('#lc').hide()
}
}