refresh drop down list after button click in web app - javascript

I have a web app with one drop down list and 2 buttons. The drop down list get values from a sheet. The buttons write back in the sheet. The script I have works fine with that:
<script>
$(function() {
$('#txt1').val('');
google.script.run
.withSuccessHandler(updateSelect)
.getSelectOptions();
});
function updateSelect(opt)
{
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<opt.length;i++)
{
select.options[i] = new Option(opt[i],opt[i]);
}
}
function listS() {
const selectElem = document.getElementById('sel1')
const index = selectElem.selectedIndex;
if (index > -1) {
const e = document.getElementById("sel1");
const value = e.options[index].value;
const body = { index: index, value: value };
google.script.run.withSuccessHandler(yourCallBack).yourServerSideFunc(body);
}
}
document.getElementById("but1").addEventListener("click",listS);
function yourCallBack(response) {
}
</script>
In Java script:
function getSelectOptions()
{
var ss=SpreadsheetApp.openById('1onuWoUKh1XmvEAmKktwJekD782BFIru-MDA0omqzHjw');
var sh=ss.getSheetByName('Database');
var rg=sh.getRange(2,1,sh.getLastRow()-1,8);
var vA=rg.getValues();
var useremail = Session.getActiveUser().getEmail();
var opt=[];
for(var i=0;i<vA.length;i++)
{
if(vA[i][1] == "Pending Approval"){
if(vA[i][7]+"#xxx.com" == useremail || vA[i][7]+"#xxx.com" == useremail) {
opt.push(vA[i][3]+" REQ ID: "+vA[i][0]);
}
}
};
if (opt.length == 0) {opt.push("You do not have pending requests")};
return opt;
}
function doGet() {
var output = HtmlService.createHtmlOutputFromFile('list');
return output;
}
function yourServerSideFunc(body) {
var value = body["value"];
var ss = SpreadsheetApp.openById('1onuWoUKh1XmvEAmKktwJekD782BFIru-MDA0omqzHjw');
var sh = ss.getSheetByName('Database');
var rg=sh.getRange(1,1,sh.getLastRow()-1,4);
var vA=rg.getValues();
var str = "Approved";
for(var i=0;i<vA.length;i++)
{
if(vA[i][3]+" REQ ID: "+vA[i][0] == value) {
sh.getRange(i+1, 2).setValue(str);
}
};
return ContentService.createTextOutput(JSON.stringify({message: "ok"})).setMimeType(ContentService.MimeType.JSON);
Now I am trying to regenerate the drop down list values after the button is clicked. I tried to add
var output = HtmlService.createHtmlOutputFromFile('list');
return output;
in yourServerSideFunc(body) function to regenerate the HTML but does not work. I have tried to force a HTML refresh, but also did not work.
How can I easily re-trigger the generation of the drop down list items? Worst case scenario it is ok to refresh the whole page, but it should be simple to regenerate the drop down list since I have already the code for it.

I ended up with this work around.
function listS() {
const selectElem = document.getElementById('sel1')
const index = selectElem.selectedIndex;
if (index > -1) {
const e = document.getElementById("sel1");
const value = e.options[index].value;
const body = { index: index, value: value };
google.script.run.withSuccessHandler(yourCallBack).yourServerSideFunc(body);
//ADDED:
var select = document.getElementById("sel1");
select.options[index] = new Option("Approved! Please refresh","Approved! Please refresh");
selectElem.selectedIndex = index;
}
}
It does not really meet the original goal to refresh the list from the sheet. It would be great if someone else posted a solution to call the server function. I tried to add google.script.run.doGet() and similar, but it seems that it does not call the server side functions properly.

Related

Firebase .orderByChild().on runs more and more times every time it is called

I'm creating a guest list program that stores the guest list in Firebase RTDB and when I check people in and out my function runs several times more than it is supposed to. I've sent alerts to the console so I know how many times it has run. I have separate functions for both check in and check out operations so it may be that I am calling my db too many times?
//-------------------- Check In and Check In Helper Functions -------------------------
//Helper Function to Grab current List index
function printArray() {
var ref = database.ref('guestList')
ref.on('value', readData, errData);
}
function readData(data){
guestList=[];
var scores = data.val();
var keys = Object.keys(scores)
for (var i=0; i < keys.length; i++){
var k = keys[i]
var name = scores[k].name;
var inside = scores[k].Inside;
var timeIn = scores[k].TimeIn;
var timeOut = scores[k].TimeOut;
guestList[i] = {
name: name,
Inside: inside,
TimeIn: timeIn,
TimeOut: timeOut,
}
}
checkIn(guestList);
}
function errData(err){
console.log('Error!');
console.log(err);
}
//Helper Function to set text box to selected name
function checkInn(name){
console.log(name)
document.getElementById('checkIn').value = name;
}
//Check in
function checkIn(list) {
//Grabs current guest to be added or deleted from form text box
var name = document.getElementById('checkIn').value;
//Checks to see if user is in list of guests and isn't in the list of guest in the party
var guestsRef = firebase.database().ref("guestList/");
guestsRef.orderByChild("name").on("child_added", function(data) {
if (name == data.val().name) {
objIndex = list.findIndex((obj => obj.name == name));
guestsRef = firebase.database().ref("guestList/" + objIndex)
guestsRef.update({
Inside: "Yes",
TimeIn: getTime(),
})
guestsRef.off();
document.getElementById('checkIn').value = "";
alerts(name, true)
}
})
}
//------------------------- Check Out ------------------------------------------------------------
//Helper Function to Grab current List index
function printArrayy() {
var ref = database.ref('guestList')
ref.on('value', readOutData, errData);
}
function readOutData(data){
guestList=[];
var scores = data.val();
var keys = Object.keys(scores)
for (var i=0; i < keys.length; i++){
var k = keys[i]
var name = scores[k].name;
var inside = scores[k].Inside;
var timeIn = scores[k].TimeIn;
var timeOut = scores[k].TimeOut;
guestList[i] = {
name: name,
Inside: inside,
TimeIn: timeIn,
TimeOut: timeOut,
}
}
checkOut(guestList);
}
//Helper Function to set text box to selected name
function checkOutt(name){
console.log(name);
document.getElementById('checkOut').value = name;
}
//Check Out
function checkOut(list) {
//Grabs current guest to be added or deleted from form text box
var name = document.getElementById('checkOut').value;
//Checks to see if user is in list of guests and isn't in the list of guest in the party
var guestsRef = firebase.database().ref("guestList/");
guestsRef.orderByChild("name").on("child_added", function(data) {
if (name == data.val().name) {
objIndex = list.findIndex((obj => obj.name == name));
guestsRef = firebase.database().ref("guestList/" + objIndex)
guestsRef.update({
Inside: "No",
TimeOut: getTime(),
})
document.getElementById('checkOut').value = "";
guestsRef.off();
alerts(name, false)
}
})
}
//Placeholder to alert user when a succesful check in or check out function runs
function alerts(name, Boolean){
if(Boolean){
console.log(name + " has been checked in!")
}
else{
console.log(name + " has been checked out!")
}
}
Here is the screenshot of my output. Thanks in advance!
Edit: Forgot to mention and apologize for my excessive use of helper functions! My HTML form calls printArrayy() and printArray first for each function!
have you tried once instep on, i mean:
ref.once('value', readOutData, errData); }

How to customize autocomplete function of the CodeMirror

I want to customize an autocomplete function to Codemirror.
So I have build this code:
CodeMirror.commands.autocomplete = function (cm) {
var arrayTabNONDefault = new Array();
var stringaCampi = null;
var arrayTabellaCampo = null;
var textVal = cm.getValue();
textVal = textVal.toUpperCase();
var res = textVal.match("SELECT(.*)FROM");
if (res != null) {
stringaCampi = res[1];
arrayTabellaCampo = stringaCampi.split(",");
var nomeTab = null;
for (var i = 0; i < arrayTabellaCampo.length; i++) {
nomeTab = (arrayTabellaCampo[i].split(".")[0]).trim();
if (hintTables[nomeTab] == null)
hintTables[nomeTab] = new Array();
} //FINE FOR
} //FINE IF
CodeMirror.showHint(cm, CodeMirror.hint.sql, {
tables: hintTables
});
cm.on("beforeChange", function (cm, change) {
var before = cm.getRange({ line: 0, ch: 0 }, change.from);
var text = cm.getRange(change.from, change.to);
var after = cm.getRange(change.to, { line: cm.lineCount() + 1, ch: 0 });
if (before.indexOf("FROM") !== -1)
// alert("Ho scritto FROM");
console.log("before change", before, text, after);
});
cm.on("change", function (cm, change) {
var from = change.from;
var text = change.text.join("\n");
var removed = change.removed.join("\n");
var to = cm.posFromIndex(cm.indexFromPos(from) + text.length);
var before = cm.getRange({ line: 0, ch: 0 }, from);
var after = cm.getRange(to, { line: cm.lineCount() + 1, ch: 0 });
if (before.indexOf("FROM") !== -1)
console.log("after change", before, removed, text, after);
});
} //FINE ESTENSIONE
This is the content of hintTables
var hintTables = { "#T_TF_FilesList": ["FilesListHeaderID", "NumRecord", "FileTypeID", "FileID", "FilesListHeaderID", "NumRecord"],
"#T_TF_SelectedItems": ["EventHeaderID", "ItemType", "ItemID1", "ItemID2", "EventHeaderID", "ItemType", "ItemID1", "ItemID2"],
"#T_TFT_CacheSearchCriteriaHeaders": ["ID", "SyncDate", "FileTypeID", "CriteriaExpressionString", "CriteriaExpressionHash", "PageRecordsNumber", "PageNumber", "NumFiles"]
};
So I want that the system should propose a list of this table after I write FROM, or the system should to propose a list of stored procedures after I write EXECUTE.
It is possible to do this?
Are you trying to customize the SQL hint addon? If so, you should make changes inside sql-hint.js (under codemirror/addon/hint).
Basically what you should do is:
1.In your app.js (whatever js file for your main logic) call editor.showHint({hint: CodeMirror.hint.sql) on "change" event;
2.Inside sql-hint.js, return {list: hintTables, from: somePos, to: somePos} when the user types FROM or EXECUTE which can be detected by regular expression or inspecting the tokens at the line. I made up some code for your reference:
var cursor = editor.getCursor();
var tokenAtCursor = editor.getTokenAt(cursor);
if (tokenAtCursor.type == "FROM-and-EXECUTE")
return {list: hintTables,
from: CodeMirror.Pos(cur.line, tokenAtCursor.start),
to: CodeMirror.Pos(cur.line, tokenAtCursor.end)};
If I misunderstand your question and this answer is not helpful, please tell me and I will delete it.

localStorage Not Clearing in Any Browser Outside of Chrome

I'm having an issue when it comes to the localStorage clearing in any browser environment outside of Chrome. I have a captcha using shapes that the user must draw to submit a form. There is a span the user can click to generate a new shape. In order to keep the information inputted into the previous fields, I store the data in localStorage every time a new shape is requested. However, if the page is refreshed, I'd like the localStorage to be completely wiped out.
Here is the code for the span that the user clicks on:
<span style="color:#0000EE;cursor:pointer;" id="new-shape" onclick="window.location.reload()" title="Click for a new shape">new shape</span>
And here is the JS for the localStorage:
$('#new-shape').on('click', function () {
var stickies = $('.sticky');
var dropdowns = $('select');
window.onbeforeunload = function () {
localStorage.setItem("branch", $('#00NL0000003INTJ').val());
localStorage.setItem("department", $('#00NL0000003I0Ux').val());
localStorage.setItem("contact", $('#00NL0000003INUC').val());
localStorage.setItem("company", stickies[0].value);
localStorage.setItem("firstName", stickies[1].value);
localStorage.setItem("lastName", stickies[2].value);
localStorage.setItem("phone", stickies[3].value);
localStorage.setItem("ext", stickies[4].value);
localStorage.setItem("email", stickies[5].value);
localStorage.setItem("help", stickies[6].value);
}
});
window.onload = function () {
var stickies = $('.sticky');
var dropdowns = $('select');
var selects = [localStorage.getItem("branch"), localStorage.getItem("department"), localStorage.getItem("contact")];
var company = localStorage.getItem("company");
var first = localStorage.getItem("firstName");
var last = localStorage.getItem("lastName");
var phone = localStorage.getItem("phone");
var ext = localStorage.getItem("ext");
var email = localStorage.getItem("email");
var help = localStorage.getItem("help");
var stickiesArr = [company, first, last, phone, ext, email, help];
for (var i = 0; i < stickiesArr.length; i++) {
if (stickiesArr[i] != null) {
stickies[i].value = stickiesArr[i];
}
}
for (var i = 0; i < selects.length; i++) {
if (selects[i] != null) {
dropdowns[i].value = selects[i];
}
}
//this allows the wipe out of all data on a page refresh,
//but clicking on "new shape" will maintain the data
localStorage.clear();
}
This code works flawlessly in Chrome, but the page refresh in IE and Firefox fails to clear the localStorage. Am I doing something wrong for the localStorage to clear across multiple browsers?
Edit
I have tried using window.location.clear(), and for good measure, localSession.clear().
I managed to finally get it to work. Part of the problem was the call of:
window.onbeforeunload = function () { (...) }
FireFox and IE11 both were having trouble with this anonymous function call. I had to change my on.click event to:
$('#new-shape').on('click', function () {
var stickies = $('.sticky');
localStorage.setItem("branch", $('#00NL0000003INTJ').val());
localStorage.setItem("department", $('#00NL0000003I0Ux').val());
localStorage.setItem("contact", $('#00NL0000003INUC').val());
localStorage.setItem("company", stickies[0].value);
localStorage.setItem("firstName", stickies[1].value);
localStorage.setItem("lastName", stickies[2].value);
localStorage.setItem("phone", stickies[3].value);
localStorage.setItem("ext", stickies[4].value);
localStorage.setItem("email", stickies[5].value);
localStorage.setItem("help", stickies[6].value);
});
And my window.onload anonymous function call had to be slightly reconfigured to:
window.onload = function () {
var stickies = $('.sticky');
var dropdowns = $('select');
var selects = [localStorage.getItem("branch"), localStorage.getItem("department"), localStorage.getItem("contact")];
var company = localStorage.getItem("company");
var first = localStorage.getItem("firstName");
var last = localStorage.getItem("lastName");
var phone = localStorage.getItem("phone");
var ext = localStorage.getItem("ext");
var email = localStorage.getItem("email");
var help = localStorage.getItem("help");
var localStorageArr = [company, first, last, phone, ext, email, help];
//input fields sticky
for (var i = 0; i < localStorageArr.length; i++) {
stickies[i].value = localStorageArr[i];
}
//dropdown fields sticky
for (var i = 0; i < selects.length; i++) {
if (selects[i] != null) {
dropdowns[i].value = selects[i];
} else {
dropdowns[i].selectedIndex = 0;
}
}
//fixing textarea
if (help === null) {
stickies[6].value = "";
}
localStorage.clear();
}
Some hacky workarounds, but the results are now working as desired.

Google script - parse HTML from Website Forum - and Write Data to Sheet

I'm getting HTML from a forum url, and parsing the post count of the user from their profile page. I don't know how to write the parsed number into the Google spreadsheet.
It should go account by account in column B till last row and update the column A with count.
The script doesn't give me any errors, but it doesn't set the retrieved value into the spreadsheet.
function msg(message){
Browser.msgBox(message);
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu("Update")
.addItem('Update Table', 'updatePosts')
.addToUi();
}
function getPostCount(profileUrl){
var html = UrlFetchApp.fetch(profileUrl).getContentText();
var sliced = html.slice(0,html.search('Posts Per Day'));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
return postCount;
}
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var accountSheet = spreadSheet.getSheetByName("account-stats");
var statsLastCol = statsSheet.getLastColumn();
var accountCount = accountSheet.getLastRow();
var newValue = 0;
var oldValue = 0;
var totalNewPosts = 0;
for (var i=2; i<=accountCount; i++){
newValue = parseInt(getPostCount(accountSheet.getRange(i, 9).getValue()));
oldValue = parseInt(accountSheet.getRange(i, 7).getValue());
totalNewPosts = totalNewPosts + newValue - oldValue;
accountSheet.getRange(i, 7).setValue(newValue);
statsSheet.getRange(i,statsLastCol).setValue(newValue-todaysValue);
}
if(showAlert==false){
return 0;
}
msg(totalNewPosts+" new post found!");
}
function valinar(needle, haystack){
haystack = haystack[0];
for (var i in haystack){
if(haystack[i]==needle){
return true;
}
}
return false;
}
The is the first time I'm doing something like this and working from an example from other site.
I have one more question. In function getPostCount I send the function profileurl. Where do I declare that ?
Here is how you get the URL out of the spreadsheet:
function getPostCount(profileUrl){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var thisSheet = ss.getSheetByName("List1");
var getNumberOfRows = thisSheet.getLastRow();
var urlProfile = "";
var sliced = "";
var A_Column = "";
var arrayIndex = 0;
var rngA2Bx = thisSheet.getRange(2, 2, getNumberOfRows, 1).getValues();
for (var i = 2; i < getNumberOfRows + 1; i++) { //Start getting urls from row 2
//Logger.log('count i: ' + i);
arrayIndex = i-2;
urlProfile = rngA2Bx[arrayIndex][0];
//Logger.log('urlProfile: ' + urlProfile);
var html = UrlFetchApp.fetch(urlProfile).getContentText();
sliced = html.slice(0,html.search('Posts Per Day'));
var postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
sliced = sliced.slice(sliced.search('<dt>Total Posts</dt>'),sliced.length);
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
Logger.log('postCount: ' + postCount);
A_Column = thisSheet.getRange(i, 1);
A_Column.setValue(postCount);
};
}
You're missing var in front of one of your variables:
postCount = sliced.slice(sliced.search("<dd> ")+"<dd> ".length,sliced.search("</dd>"));
That won't work. Need to put var in front. var postCount = ....
In this function:
function updatePosts(){
if(arguments[0]===false){
showAlert = false;
} else {
showAlert=true;
}
There is no array named arguments anywhere in your code. Where is arguments defined and how is it getting any values put into it?

Filter a child picklist in CRM 2011

I'm trying to convert javascript code from CRM 4.0 to CRM 2011.
I'm having problems with a picklist filter.
My function is on the onchange of the parent picklist. It works the first time but the second it erase everything from my child picklist.
This is the part where I suppose to reset the picklist
if(!oSubPicklist.originalPicklistValues)
{
oSubPicklist.originalPicklistValues = oSubPicklist.getOptions();
}
else
{
oSubPicklist.getOptions = oSubPicklist.originalPicklistValues;
oSubPicklist.setOptions = oSubPicklist.originalPicklistValues;
}
And this is the part where i remove all the option not related:
oTempArray is an array with the options that i want to keep. If a check the "oSubPicklist.getOptions.length" the value is the same that my original picklist.
for (var i=oSubPicklist.getOptions.length; i >= 0;i--)
{
if(oTempArray[i] != true)
{
Xrm.Page.getControl("new_product").removeOption(i);
}
}
Ideas?
Edit: I solved declaring a global var with the originalPickList in the onLoad event and:
oSubPicklist.clearOptions();
for (var i=0; i< oSubPicklist.originalPicklistValues.length; i++)
{
for (var j=0; j< oDesiredOptions.length; j++)
{
if (i == oDesiredOptions[j])
{oSubPicklist.addOption(oSubPicklist.originalPicklistValues[i]);}
}
}
Your code is not very clear to me: May be you could paste all your function code for better understanding but:
This is how you get the options from PickList in CRM 2011
var myOptionSet = Xrm.Page.ui.controls.get("new_product") //get Control
var optionsSet = myOptionSet .getAttribute().getOptions(); //get Options
preferredTimeOptionSet.clearOptions(); //Clear all options
//Create a new Option
var opt1 = new Option();
opt1.text = "one";
opt1.value = 1;
//Add Option
myOptionSet.addOption(opt1);
//Remove Option
myOptionSet.removeOption(1);
Good Example here
Here is another way to do Parent/Child picklists:
function dynamicDropdown(parent, child) {
filterPicklist(parent, child);
}
function parentListFilter(parent, id) {
var filter = "";
if (getParentCode(parent) != "") {
filter = getParentCode(parent);
} else {
// No [ ] match
}
return filter;
}
function filterPicklist(parent, child) {
var parentList = Xrm.Page.getAttribute(parent).getValue();
var childListControlAttrib = Xrm.Page.getAttribute(child);
var childListOptions = childListControlAttrib.getOptions();
var childListControl = Xrm.Page.getControl(child);
var codeToFilterListOn = parentListFilter(parent, parentList);
if (codeToFilterListOn != "") {
childListControl.clearOptions();
for (var optionIndex in childListOptions) {
var option = childListOptions[optionIndex];
// Ignore xx and check for Match
if (option.text.substring(0, 2) != "xx" && option.text.indexOf(codeToFilterListOn) > -1) {
childListControl.addOption(option);
}
}
} else {
// Didn't match, show all?
}
}
function getParentCode(parent) {
//Get Parent Code Dynamically from inside [ ]
var filter = "";
var parentValue = Xrm.Page.getAttribute(parent).getText();
if (parentValue && parentValue.indexOf("]") > -1) {
var parentCode = parentValue.substring(parentValue.indexOf("[") + 1, parentValue.indexOf("]"));
if (parentCode) {
filter = parentCode + " | ";
} else {}
}
return filter;
}
See more here: Parent/Child

Categories