Following is an example of a sample webform I made in Google Apps Script, where I'm trying to dynamically add three select dropdowns and an input element whenever the add
button is clicked. The elements should render in following order -
dropdown
dropdown
input
dropdown
.
I'm using materialize framework for this.
After a lot of trying and going through the materializecss
documentation, I was able to render the text input field as expected. But, the dropdowns still won't render. Clearly, I'm making some mistake, cannot figure out what and where.
I'm including the code files-
Code.gs
function doGet(e) {
Logger.log(e);
return HtmlService.createTemplateFromFile('form_materialize').evaluate();
}
function include(fileName){
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
form_materialize.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<!-- google font pack link -->
<link href="https://fonts.googleapis.com/icon?family=Material Icons" rel="stylesheet">
<!-- Mini materialize.css cdn link -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<?!= include('css_scripts'); ?>
</head>
<body>
<div >
<div class = "row">
<h1>A Sample Form</h1>
</div>
<div id="productsection">
<!-- product details like "Product Type"(dropdown), "Products"(dropdown), "Product Qty"(text input field), "Unit"(dropdown) to be added here dynamically -->
</div>
<div class = "row">
<a id="addproduct"><i >add</i></a>
</div>
</div>
<!-- Mini materialize.js cdn link -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<?!= include('js_scripts_materialize'); ?>
</body>
</html>
js_scripts_materialize.html
<script>
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems, options);
});
let counter = 0;
const orderTypeList = ["PH", "ECOM"];
const optionList = ["Test Product 1", "Test Product 2", "Test Product 3", "Test Product 4", "Test Product 5"];
const unitOptionList = ["KGS", "PCS", "BAGS"];
document.getElementById("addproduct").addEventListener("click", addInputField);
function addInputField(){
counter ;
// everytime when "add product" button is clicked, the following elements must be added to the "<div id="produc></div>" tag.
// <div >
// <div id="divone">
// <select id="productX">
// <option>option-i</option>
// <option>option-1</option>
// <option>option-2</option>
// ...
// ...
// <option>option-n</option>
// <select>
// </select>
// <div id="divtwo">
// <input id="productqtyX" type="text">
// <label for="productqtyX">Quantity</label>
// </div>
// <div id="divthree">
// <select id="productUnitX">
// <option>option-1</option>
// <option>option-2</option>
// ...
// ...
// <option>option-n</option>
// </select>
// </div>
// </div>
// creates a new div of class row
const newDivElem = createElementTemplate('div', null, ['row']);
// creates a new select tag for order type dropdown
const newOrderTypeSelectElem = createElementTemplate('select', "ordertype" counter.toString());
// generates the content of the dropdown for products and is inserted to the above "productX" select tag
createOptionsElem(newOrderTypeSelectElem, orderTypeList);
// creates a new select tag for product dropdown
const newProductSelectElem = createElementTemplate('select', "product" counter.toString());
// generates the content of the dropdown for products and is inserted to the above "productX" select tag
createOptionsElem(newProductSelectElem, optionList);
// creates a input element for quantity input
const newQtyInputElem = createElementTemplate('input', 'productqty' counter.toString(), ['validate']);
newQtyInputElem.type = 'text';
// creates a label for the quantity input element
const newQtyLabelElem = createElementTemplate('label');
newQtyLabelElem.textContent = "Quantity";
//Creates a new select element for product quantity unit(dropdown)
const newUnitSelectElem = createElementTemplate('select', 'productqtyunit' counter.toString());
// generates the content of the dropdown for units and is inserted to the above "productqtyunitX" select tag
createOptionsElem(newUnitSelectElem, unitOptionList);
//create inner "div" tags with class "input-field col s4" as described in materializecss documentation
const innerDivElems = [];
for(let i = 0; i < 4; i ){
innerDivElems.push(createElementTemplate('div', `div${(Number(i) 1)}`, ['input-field', 'col', 's3']));
}
innerDivElems[0].appendChild(newOrderTypeSelectElem);
innerDivElems[1].appendChild(newProductSelectElem);
innerDivElems[2].appendChild(newQtyInputElem);
innerDivElems[2].appendChild(newQtyLabelElem);
innerDivElems[3].appendChild(newUnitSelectElem);
//Inserts select, quantityInput, quanityLabel, newUnitSelectTag tags in div child
for(let i in innerDivElems){
newDivElem.appendChild(innerDivElems[i]);
}
// Finally, appends the newly created div tag to the productSection tag.
document.getElementById('productsection').appendChild(newDivElem);
}
function createOptionsElem(selectElem, optionsArr){
const newDefaultOptionElem = document.createElement('option');
newDefaultOptionElem.disabled = true;
newDefaultOptionElem.setAttribute('selected', true);
newDefaultOptionElem.textContent="Choose your option";
selectElem.appendChild(newDefaultOptionElem);
for(let i in optionsArr){
const newOptionElem = document.createElement('option');
newOptionElem.textContent = optionsArr[i];
newOptionElem.value = optionsArr[i];
// Inserts the option tag in select tag
selectElem.appendChild(newOptionElem);
}
}
// function to create a new element
function createElementTemplate(tagType, idVal, classNameList){
const newElement = document.createElement(tagType);
if(idVal !== undefined)
newElement.id = idVal;
if(classNameList !== undefined){
for(let i in classNameList){
newElement.classList.add(classNameList[i]);
}
}
return newElement;
}
</script>
CodePudding user response:
Although I'm not sure whether I could correctly understand your expected result, how about the following modification?
In this modification, your js_scripts_materialize.html
is modified.
Modified script:
I think that in this case, this part might not be required to be used.
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems, options);
});
And also, please modify addInputField()
as follows.
From:
document.getElementById('productsection').appendChild(newDivElem);
To:
document.getElementById('productsection').appendChild(newDivElem);
var elems = document.querySelectorAll('select'); // Added
M.FormSelect.init(elems); // Added
- By this modification, I thought that when you click a red button, you can see the dropdown lists.