I am wondering how to add a duplicate panel underneath the previous existing panel ("productOtherPanel") using the "Add Product" button. I would like the new panel to be inserted below the existing "productOtherPanel" and above the "Add Product" button. I would also like this new panel to contain the same drop down list and text box as the original "productOtherPanel". I need this panel to duplicate an infinite number of times. Is this possible?
function doGet(e) {
var app = UiApp.createApplication();
var productOtherPanel = app.createHorizontalPanel().setId('productOtherPanel');
var productPanel = app.createVerticalPanel().setId('productPanel');
var productList = app.createListBox().setName("productList").setId('productList');
productList.addItem("8:1 Compressed Blocks");
productList.addItem("8:1 Compressed Briquettes");
var pricePerTonPanel = app.createVerticalPanel().setId('pricePerTonPanel');
var pricePerTonTextBox = app.createTextBox().setId("pricePerTonTextBox").setName("pricePerTonTextBox")
.setText("$0.00");
var buttonPanel = app.createVerticalPanel().setId('buttonPanel');
var button = app.createButton("Add Product");
app.add(productOtherPanel);
productOtherPanel.add(productPanel);
productPanel.add(productList);
productOtherPanel.add(pricePerTonPanel);
pricePerTonPanel.add(pricePerTonTextBox);
app.add(buttonPanel);
buttonPanel.add(button);
return app;
}
Try to see if this code is what you are looking for:
function doGet(e) {
var app = UiApp.createApplication();
var productOtherPanel = app.createVerticalPanel().setId('productOtherPanel');
var productPanel = app.createHorizontalPanel().setId('productPanel');
// Product list dropdown
var productList = app.createListBox().setName("productList").setId('productList');
productList.addItem("8:1 Compressed Blocks");
productList.addItem("8:1 Compressed Briquettes");
// Product Price Textbox
var pricePerTonTextBox = app.createTextBox().setId("pricePerTonTextBox").setName("pricePerTonTextBox").setText("$0.00");
productPanel.add(productList);
productPanel.add(pricePerTonTextBox);
var buttonPanel = app.createVerticalPanel().setId('buttonPanel');
var button = app.createButton("Add Product");
button.addClickHandler(app.createServerHandler("addProductHandler").addCallbackElement(productOtherPanel));
app.add(productOtherPanel);
productOtherPanel.add(productPanel);
app.add(buttonPanel);
buttonPanel.add(button);
return app;
}
function addProductHandler(e) {
var app = UiApp.getActiveApplication();
var productPanel = app.createHorizontalPanel().setId('productPanel');
// Product list dropdown
var productList = app.createListBox().setName("productList").setId('productList');
productList.addItem("8:1 Compressed Blocks");
productList.addItem("8:1 Compressed Briquettes");
// Product Price Textbox
var pricePerTonTextBox = app.createTextBox().setId("pricePerTonTextBox").setName("pricePerTonTextBox").setText("$0.00");
productPanel.add(productList);
productPanel.add(pricePerTonTextBox);
var panel = app.getElementById("productOtherPanel");
panel.add(productPanel);
return app;
}
Related
I have this script at the document level (simplified) on a PDF:
function SetFieldValues(){
var Model = this.getField("Model");
var Armor = this.getField("Armor");
var Winch = this.getField("Winch");
var Test1 = this.getField("Test1");
var Test2 = this.getField("Test2");
if(event.willCommit) {
switch(event.value) {
case "015305676":
Model.value = "AMK23";
Armor.value = "YES";
Winch.value = "NO";
Test1.setItems[("Not Applicable")];
Test2.setItems[("-", "Serviceable", "Unserviceable")];
break;
}}}
This event is kicked off by the Custom Keystroke on the form's initiating dropdown list:
if( event.willCommit )
{
if(event.value == "-")
this.resetForm(["Model","Armor","Winch"]);
else
SetFieldValues(event.value)
}
All the fields update appropriately (Model, Armor, and Winch) however, the "Test" combo boxes do not populate as expected.
I then tried it a different way with this (which I thought would be genius using an array ...pfft... I was wrong):
function SetFieldValues(){
var Model = this.getField("Model");
var Armor = this.getField("Armor");
var Winch = this.getField("Winch");
const ArmorArray = [field='Test1', field='Test2'];
var ArmorArray;
var CheckOptionsY = {
Yes: [["-"],["Serviceable"],["Unserviceable"]],
};
var CheckOptionsN = {
No: [["Not Applicable"]],
};
if(event.willCommit)
{
switch(event.value) {
case "015305676":
Model.value = "AMK23";
Armor.value = "YES";
Winch.value = "NO";
ArmorArray.setItems[(CheckOptionsY)];
break;
}}}
Again, the fields update no problem (Model, Armor, and Winch) but the "Test" fields do not update with the combo box list options. What did I do wrong? How can I get these "Test" combo boxes to load with the appropriate 'Yes' / 'No' options?
WARNING: I'm not a programmer by trade.
Ok. Got the disclaimer out of the way. So this might not be the best way to do this but here is the scenario. I have a dropdown that gets populated via a Google Sheet. The user chooses a selection from the list but this dropdown does not have all of the possible values it could have. There will likely be a time when the user needs a new value added. While I could manually update the spreadsheet as new values are requested that introduces an element of human availability to get this done and I'm not always available.
What I would prefer is a self-serve model. I want to supply the user with a text field where they can enter the new value and submit it to the Google Sheet. Then I would like the dropdown to be updated with the new value for the user to choose.
Now, I realize that I could just submit the value in the new field to the Google Sheet but that will require building a condition to see whether it is the dropdown or text field that has a value in it. I'd also need some type of error handling in case both the dropdown and text field have values. That seems like a bigger headache to program then my ask.
I'm not sure what code you would need to see to help make this work but here is what I think might help.
doGet function
function doGet(e){
var ss = SpreadsheetApp.openById(ssId)
var ws = ss.getSheetByName("External");
var range = ws.getRange("A2:D2");
var valuesArray = [];
for (var i = 1; i <= range.getLastColumn(); i++){
var lastRowInColumn = range.getCell(1, i).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
var list = ws.getRange(2,i,lastRowInColumn-1,1).getValues();
valuesArray.push(list);
}
var userEmail = Session.getActiveUser().getEmail();
var sourceListArray = valuesArray[2].map(function(r){ return '<option>' + r[0] + '</option>'; }).join('');
var productListArray = valuesArray[3].map(function(r){ return '<option>' + r[0] + '</option>'; }).join('');
var tmp = HtmlService.createTemplateFromFile("config");
tmp.productList = productListArray;
return tmp.evaluate();
}
Add to Google Sheet
function userClicked(tagInfo){
var ss = SpreadsheetApp.openById(ssId)
var ws = ss.getSheetByName("Data");
ws.appendRow([tagInfo.email, tagInfo.source, tagInfo.product, new Date()]);
}
Add record
function addRecord(){
var tagInfo = {};
tagInfo.product = document.getElementById("product").value;
google.script.run.userClicked(tagInfo);
var myApp = document.getElementById("source");
myApp.selectedIndex = 0;
M.FormSelect.init(myApp);
var myApp = document.getElementById("brand");
myApp.selectedIndex = 0;
M.FormSelect.init(myApp);
var myApp = document.getElementById("product");
myApp.selectedIndex = 0;
M.FormSelect.init(myApp);
}
How dropdowns are populated in the HTML.
<div class="input-field col s3">
<select id="product" onchange="buildURL()">
<option disabled selected value="">Choose a product</option>
<?!= productList; ?>
</select>
<label>Product</label>
</div>
Need to see anything else? I think it might be relatively easy to add the new value to the column but the tricky part seems to be the update of only that one dropdown and not the entire app. To me it seems like I want to trigger the doGet() function again but only for that specific dropdown. Thoughts?
UPDATE: current code to add new value to dropdown
function addProduct() {
let newProd = document.getElementById("newProduct").value;
google.script.run.withSuccessHandler(updateProductDropdown).addNewProduct(newProd);
document.getElementById("newProduct").value = "";
}
function updateProductDropdown(newProd){
var newOption = document.createElement('option');
newOption.value = newProd;
newOption.text = newProd;
document.getElementById('product').add(newOption);
}
UPDATE2: App Scripts function to add new value to column in spreadsheet
function addNewProduct(newProd){
var columnLetterToGet, columnNumberToGet, direction, lastRow, lastRowInThisColWithData, rng, rowToSet, startOfSearch, valuesToSet;
var ss = SpreadsheetApp.openById(ssId);
var ws = ss.getSheetByName("List Source - External");
lastRow = ws.getLastRow();
//Logger.log('lastRow: ' + lastRow)
columnNumberToGet = 9;//Edit this and enter the column number
columnLetterToGet = "I";//Edit this and enter the column letter to get
startOfSearch = columnLetterToGet + (lastRow).toString();//Edit and replace with column letter to get
//Logger.log('startOfSearch: ' + startOfSearch)
rng = ws.getRange(startOfSearch);
direction = rng.getNextDataCell(SpreadsheetApp.Direction.UP);//This starts
//the search at the bottom of the sheet and goes up until it finds the
//first cell with a value in it
//Logger.log('Last Cell: ' + direction.getA1Notation())
lastRowInThisColWithData = direction.getRow();
//Logger.log('lastRowInThisColWithData: ' + lastRowInThisColWithData)
rowToSet = lastRowInThisColWithData + 1;
valuesToSet = [newProd];
ws.getRange(rowToSet, 9).setValues([valuesToSet]);
return newProd;
}
SOLUTION to Update Materialize Dropdown
function updateProductDropdown(newProd){
newProdOption = document.getElementById('product');
newProdOption.innerHTML += '<option>' + newProd + '</option>';
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
}
You can specify a client side callback function if you use google.script.run withSuccessHandler(callback) where your callback could update the list only and not the whole site.
Example:
google.script.run.withSuccessHandler(updateDropdownWidget).updateDropdownList(text_from_input)
Where updateDrownList(text_from_input) is a function in your Apps Script that adds text to the sheet using SpreadsheetApp for example, and returns the "text" to the callback function: updateDropdownWidget(text) which adds a new list item to the HTML drop-down list in your front end.
index.html:
<form>
<label for="newOption">New option for the dropdown:</label>
<input type="text" id="nopt" name="newOption">
<input type="button" value="Submit"
onclick="google.script.run.withSuccessHandler(updateDropdownWidget)
.updateDropdownList(document.getElementById('nopt').value)">
</form>
<label for="cars">Choose a car:</label>
<select name="cars" id="cars">
<?!= values; ?>
</select>
<script>
function updateDropdownWidget(text){
var option = document.createElement('option');
option.value = text;
option.text = text;
document.getElementById('cars').add(option);
}
</script>
Code.gs:
function doGet(e){
var ss = SpreadsheetApp.getActiveSheet();
var lastRow = ss.getDataRange().getLastRow();
var values = ss.getRange(1,1,lastRow,1).getValues();
var valuesArray = [];
for (var i = 0; i < values.length; i++){
valuesArray.push('<option value="'+values[i]+'">' +values[i]+ '</option>');
}
var tmp = HtmlService.createTemplateFromFile("index");
tmp.values = valuesArray;
return tmp.evaluate();
}
function updateDropdownList(text_from_input){
// Log the user input to the console
console.log(text_from_input);
// Write it to the sheet below the rest of the options
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getDataRange().getLastRow();
sheet.getRange(lastRow+1,1).setValue(text_from_input);
// Return the value to the callback
return text_from_input;
}
Here's an example:
In my Stack Over Flow spreadsheet I four buttons which can be used to run any function in 3 script files and every time I load the sidebar it reads the functions in those script files and returns them to each of the select boxes next to each button so that I test functions that I write for SO with a single click and I can select any function for any button. Here's the Javascript:
$(function(){//JQuery readystate function
google.script.run
.withSuccessHandler(function(vA){
let idA=["func1","func2","func3","func4"];
idA.forEach(function(id){
updateSelect(vA,id);
});
})
.getProjectFunctionNames();
})
Here is GS:
function getProjectFunctionNames() {
const vfilesA=["ag1","ag2","ag3"];
const scriptId="script id";
const url = "https://script.googleapis.com/v1/projects/" + scriptId + "/content?fields=files(functionSet%2Cname)";
const options = {"method":"get","headers": {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}};
const res = UrlFetchApp.fetch(url, options);
let html=res.getContentText();
//SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(html), "Project Functions");
let data=JSON.parse(res.getContentText());
let funcList=[];
let files=data.files;
files.forEach(function(Obj){
if(vfilesA.indexOf(Obj.name)!=-1) {
if(Obj.functionSet.values) {
Obj.functionSet.values.forEach(function(fObj){
funcList.push(fObj.name);
});
}
}
});
//SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(funcList.join(', ')), "Project Functions");
return funcList;//returns to withSuccessHandler
}
Image:
Animation:
I have a gridview using devexpress tools that is populated on page load. When I select a row I have button that will allow me to edit the information in that row by popping up an edit box that allows me to change the information. The issue I am having is when they click that button the data that was behind the gridivew could have changed so I want to be able to query the database again (using some parameters from the selected row) when that edit button is clicked.
Here is the query that is ran when the 'edit' button is clicked.
function ShowPopupEditInventory() {
$.when(getFocusedInventory()).then(function (x) {
popupControlEditInventory.Show();
});
function getFocusedInventory(s, e) {
grid.GetRowValues(grid.GetFocusedRowIndex(), 'StorageLocation;LP;Sku_Alpha;LotCode;ExpirationDate;FIFOReferenceDate;ManufactureDate;InventoryStatus;SellableUnitQuantity;ReceiveDate;InventoryDetailID;Area', getFocusedInventoryValues);
}
function getFocusedInventoryValues(values) {
var fStorageLocation = values[0];
var fLP = values[1];
var fSku_Alpha = values[2];
var fLotCode = values[3];
var fExpirationDate = values[4];
var fFIFOReferenceDate = values[5];
var fManufactureDate = values[6];
var fInventoryStatus = values[7];
var fSellableUnitQuantity = values[8];
var fReceiveDate = values[9];
var fInventoryDetailID = values[10];
var fArea = values[11];
editInventoryStorageLocation.SetText(fStorageLocation);
editInventoryLP.SetText(fLP);
editInventoryItem.SetText(fSku_Alpha);
editInventoryQty_OldValue.SetText(fSellableUnitQuantity);
editInventorySts_OldValue.SetText(fInventoryStatus);
editInventoryLot_OldValue.SetText(fLotCode);
txtEditInventoryLot.SetText(fLotCode);
$(".editInventoryLot").val(fLotCode);
editInventoryStatus.SetValue(fInventoryStatus)
editInventoryUnitQuantity.SetText(fSellableUnitQuantity);
editInventoryDTL_No.SetText(fInventoryDetailID);
editInventoryNotes.SetText('');
$(".editInventoryAdjustmentCode").prop("selectedIndex", 0);
editInventoryArea.SetText(fArea);
editInventoryLot.Focus();
btnOKEditInventory.SetEnabled(true);
}
}
I want a Sharepoint 2013 app to create programmatically an Enterprise Custom Field when it runs for the first time.
I fiddled around with the following code snippet, but it's not working
var projContext = PS.ProjectContext.get_current();
function AddCustomField() {
$('#message').text('Adding Custom Field...');
var object_to_add = new PS.CustomFieldCreationInformation();
object_to_add.FieldType = CustomFieldType.Text;
object_to_add.Name = "New_one";
object_to_add.Description = "test description";
projContext.CustomFieldCollection.add(object_to_add);
}
Any help would be appreciated!
var projContext = PS.ProjectContext.get_current();
var fieldType = PS.CustomFieldType.TEXT;
var customfields = projContext.get_customFields();
var entityTypes = projContext.get_entityTypes();
var projEntity = entityTypes.get_projectEntity();
var resourceEntity = entityTypes.get_resourceEntity();
var taskEntity = entityTypes.get_taskEntity();
projContext.load(customfields);
projContext.load(entityTypes);
projContext.load(projEntity);
projContext.load(resourceEntity);
projContext.load(taskEntity);
projContext.executeQueryAsync(QuerySucceeded, QueryFailed);
CreateField("Test", "Test", fieldType, projEntity);
function CreateField(name, description, fieldtype, entitytype) {
var customfieldInfo = new PS.CustomFieldCreationInformation();
customfieldInfo.set_description(description);
customfieldInfo.set_name(name);
customfieldInfo.set_fieldType(fieldtype);
customfieldInfo.set_entityType(entitytype);
customfields.add(customfieldInfo);
customfields.update();
projContext.load(customfields);
projContext.executeQueryAsync(QuerySucceeded, QueryFailed);
}
I am using Google Scripts UiApp in order to gather availability information. I want to send this information to a spreadsheet. I have used the example here: http://www.googleappsscript.org/advanced-examples/insert-data-in-sheet-using-ui-forms
to get me started in the right direction.
The Web App looks good and when clicking submit, the appropriate message displays. However, the values that are transferred to the spreadsheet say "undefined" for all of the entries.
How can I convince it to link the textbox entered data to the variables so that I can transfer to the spreadsheet?
Thanks!!
Here is some code:
var submissioSSKey = // Key removed
function doGet() {
var rows = 15
var columns = 15
var mygrid = UiApp.createApplication().setTitle("MLC Walk Ins Scheduling")
var panel = mygrid.createSimplePanel();
// Define the grid layout
var grid = mygrid.createGrid(rows, columns).setCellPadding(2).setCellSpacing(8)
// Create the text at the top
var Title = mygrid.createLabel("Walk-In Scheduling")
grid.setWidget(1, 1, Title)
(snip) - creating various checkboxes and textboxes
var text1 = mygrid.createTextBox().setName('name1')
grid.setWidget(3,9,text1)
var text6 = mygrid.createTextBox().setName('message1')
grid.setWidget(4,9,text6)
// Create the "submit" button
var submit_button = mygrid.createButton("Submit")
grid.setWidget(12,9,submit_button)
var infoLabel = mygrid.createLabel('Availability inserted successfully.').setVisible(false).setId('info');
grid.setWidget(13,9,infoLabel)
var handler = mygrid.createServerClickHandler('insertInSS');
handler.addCallbackElement(panel);
submit_button.addClickHandler(handler);
panel.add(grid);
mygrid.add(panel);
mygrid.add(grid);
return mygrid
}
Then the function call for the button:
//Function to insert data in the sheet on clicking the submit button
function insertInSS(e){
var mygrid = UiApp.getActiveApplication()
var name1 = e.parameter.name1
var message1 = e.parameter.message1
mygrid.getElementById('info').setVisible(true).setStyleAttribute('color','blue')
var sheet = SpreadsheetApp.openById(submissioSSKey).getActiveSheet()
var lastRow = sheet.getLastRow()
var targetRange = sheet.getRange(lastRow+1, 1, 1, 2).setValues([[name1,message1]])
return mygrid
}
Ahh! A simple fix for a big headache.
I had an extra line:
mygrid.add(grid);
that was breaking it.