How to get week numbers in month in Javascript? - javascript

I need to generate year calendar with week numbers which should look like this image:
However it is not trivial to get week numbers in each month so they wouldn't overlap or be missing. I am using weekCount() function from this SO question. And for displaying calendar I have written this code:
var year = parseInt($(this).text());
var months = {1:'leden',2:'únor',3:'březen',4:'duben',5:'květen',6:'červen',7:'červenec',8:'srpen',9:'září',10:'říjen',11:'listopad',12:'prosinec'};
var calendar = $('<div id="summary_search_form_menu"></div>');
calendar.offset({top:$(this).offset().top + $(this).height() + 10}).css({right: '0px'});
var cur_week = 0;
for (var i=1;i<=12;i++) {
var row = $('<div class="row"></div>');
row.append('<div class="month button dark-blue">'+months[i]+'</div>');
var week_count = weekCount(year, i);
for (var week=1;week<week_count;week++) {
cur_week++;
row.append('<div class="week button blue">'+cur_week+'</div>');
}
calendar.append(row);
}
$('body').append(calendar);
Any way how to display week numbers correctly ?

OK, I have finally solved this on my own. In case somebody would find it helpful, I post my final code which works as I needed.
function weekCount(year, month_number) {
var firstOfMonth = new Date(year, month_number-1, 1);
var lastOfMonth = new Date(year, month_number, 0);
var used = firstOfMonth.getDay() + lastOfMonth.getDate();
return Math.ceil( used / 7);
}
Date.prototype.getWeekNumber = function(){
var d = new Date(+this);
d.setHours(0,0,0);
d.setDate(d.getDate()+4-(d.getDay()||7));
return Math.ceil((((d-new Date(d.getFullYear(),0,1))/8.64e7)+1)/7);
};
var year = parseInt($(this).text());
var months = {1:'leden',2:'únor',3:'březen',4:'duben',5:'květen',6:'červen',7:'červenec',8:'srpen',9:'září',10:'říjen',11:'listopad',12:'prosinec'};
var calendar = $('<div id="summary_search_form_menu"></div>');
calendar.offset({top:$(this).offset().top + $(this).height() + 10}).css({right: '15px'});
var cur_week = 0;
var col1 = $('<div id="summary_search_form_menu_col1"></div>');
var col2 = $('<div id="summary_search_form_menu_col2"></div>');
calendar.append(col1);
calendar.append(col2);
var col2_table = $('<div id="summary_search_form_menu_col2_table"></div>');
col2.append(col2_table);
for (var i=1;i<=12;i++) {
var row = $('<div class="row"></div>');
col1.append('<div class="month button dark-blue">'+months[i]+'</div>');
var week_count = weekCount(year, i);
var d = new Date(year, i-1, 1, 0,0,0);
var first_week_in_month = d.getWeekNumber();
for (var week=(cur_week == first_week_in_month ? 2 : 1);week<=week_count;week++) {
cur_week++;
row.append('<div class="week button blue">'+cur_week+'</div>');
}
col2_table.append(row);
}
$('body').append(calendar);

Related

How to set Day, Month and Year in a DatePicker Field in custom HTML forms - Apps Script

I don't know how to populate a Datepicker. I have a function "Edit data", when the user clicks on this button, a custom HTML form is opened and all the data of a spreadsheet is showing there. The part of the TextField was easy, was just TextField.value = data[1], but for type Date, I don't know how to do this, my code is that:
function pesquisarContrato(){
var dashboard = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Dashboard');
var planContrato = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Contratos');
var contrato = dashboard.getRange("G3").getValue();
if(contrato == ""){return false;}
var dados = planContrato.getRange(3,1, planContrato.getLastRow(), 27).getValues();
for(var linha = 0; linha<dados.length; linha++) {
if(dados[linha][0] == contrato) {
var dados_completos = {}
dados_completos.id_contrato = dados[linha][0];
dados_completos.licitacao = dados[linha][1];
dados_completos.nsipac = dados[linha][2];
dados_completos.objetivo = dados[linha][3];
dados_completos.empresa = dados[linha][4];
dados_completos.cnpj = dados[linha][5];
//here, I get the day of data with custom function ToDate()
dados_completos.inicioVigencia = toDate(linha,6)[0];
return ([dados_completos.id_contrato, dados_completos.licitacao,
dados_completos.nsipac, dados_completos.objetivo,
dados_completos.empresa, dados_completos.cnpj,
dados_completos.inicioVigencia])
}
function toDate(linha, coluna){
var planContrato = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Contratos');
var dados = planContrato.getRange(3,1, planContrato.getLastRow(), 27).getValues();
var d = Utilities.formatDate(new Date(dados[linha][coluna]), Session.getScriptTimeZone, "dd/MM/yyyy");
var split = d.split('/');
// Month is zero-indexed so subtract one from the month inside the constructor
var date = new Date(split[2], split[1]-1,split[0]); //Y M D
var day = date.getDate();;
var month = date.getMonth()+1;
var year = date.getFullYear();
var date_completa = {};
date_completa.day = day;
date_completa.month = month;
date_completa.year = year;
return ([date_completa.day, date_completa.month, date_completa.year])
}
HTML part:
<div class="row">
<div class="input-field col s3">
<input id="iniciogarantia" type="date" class="validate">
<label for="iniciogarantia">Início da garantia</label>
</div>
</div>
<script>
google.script.run.withSuccessHandler(pesquisar).pesquisarContrato();
var campoContrato = document.getElementById("contrato");
var campoLicitacao = document.getElementById("licitacao");
var campoSipac = document.getElementById("sipac");
var campoObjetivo = document.getElementById("objetivo");
var campoEmpresa = document.getElementById("empresa");
var campoCnpj = document.getElementById("cnpj");
var campoIniciovigencia = document.getElementById("iniciovigencia");
function pesquisar(atualizar){
campoContrato.value = atualizar[0];
campoLicitacao.value = atualizar[1];
campoSipac.value = atualizar[2];
campoObjetivo.value = atualizar[3];
campoEmpresa.value = atualizar[4];
campoCnpj.value = atualizar[5];
// this part have an issue, .value don't works for datepicker,
// so how can I populate this field?
//campoIniciovigencia.? = atualizar[6];
M.updateTextFields();
}
</script>
Replace ALL lines after
var d = Utilities.formatDate(new Date(dados[linha][coluna]), Session.getScriptTimeZone, "dd/MM/yyyy");
by:
return Utilities.formatDate(new Date(dados[linha][coluna]), Session.getScriptTimeZone, "yyyy-MM-dd");
Also:
dados_completos.inicioVigencia = toDate(linha,6)[0];

Google App script takes 10 mins for one function but exceeds time limit when replicated

first time poster so I apologise if if im not following the correct etiquette.
So I have code that, in essence, creates 70 forecast docs in specified folders. This works fine.
I have used the same code, repointed the all the folder references, but now times out.
Code is as follows, any suggestions on how I can make this run faster?
function createFiles(weeknr, masterIDs, masterfolders, mastercodes, archivefolders) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var date = new Date()
var textdate = Utilities.formatDate(date, "Europe/London", "dd/MM/YYYY HH:mm")
var fileslog = ss.getSheetByName("FileList")
var year = date.getYear()
var mainfolder = DriveApp.getFolderById("1HdG3eJZrIMF-CRpx17Reqdyd7JM5v5ZW")
var weekfolder = mainfolder.createFolder('Week ' + weeknr + ' ' + year)
var tempArray = []
for (var i = 0; i < masterIDs.length; i++) {
// for (var i=0;i<masterIDs.length;i++){
var folderID = masterfolders[i]
var masterID = masterIDs[i]
var code = mastercodes[i]
var archivefolder = archivefolders[i]
var newfile = DriveApp.getFileById(masterID).makeCopy(code + ' DCS WK' + weeknr,
DriveApp.getFolderById(folderID))
var newID = newfile.getId()
tempArray.push([newfile.getName(), newID, newfile.getUrl(),
newfile.getDateCreated(), "Created", folderID, archivefolder, weeknr])
SpreadsheetApp.openById(newID).getSheetByName("Main").getRange(3, 3).setValue(weeknr)
weekfolder.addFile(newfile)
//NEW UPDATE 14/02 to set the owner to network finance
newfile.setOwner('network.finance#dpdgroup.co.uk')
//End of UPDATE
fileslog.getRange(fileslog.getLastRow() + 1, 1, 1, 8).setValues([tempArray[i]])
}
// Logger.log(tempArray )
// if(tempArray.length>0){
// fileslog.getRange(fileslog.getLastRow()+1, 1, tempArray.length,
8).setValues(tempArray)
// }
}
function archiveFiles(weeknr, fileIDs, masterfolders, mastercodes, archivefolders) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var date = new Date()
var textdate = Utilities.formatDate(date, "Europe/London", "dd/MM/YYYY HH:mm")
var fileslog = ss.getSheetByName("FileList")
//var year = date.getYear()
//var mainfolder = DriveApp.getFolderById("1HdG3eJZrIMF-CRpx17Reqdyd7JM5v5ZW")
//var weekfolder = mainfolder.createFolder('Week '+weeknr+' '+year)
var tempArray = []
for (var i = 0; i < fileIDs.length; i++) {
// for (var i=0;i<masterIDs.length;i++){
var folderID = masterfolders[i]
var fileID = DriveApp.getFileById(fileIDs[i])
var code = mastercodes[i]
var archivefolder = archivefolders[i]
DriveApp.getFolderById(archivefolder).addFile(fileID)
DriveApp.getFolderById(folderID).removeFile(fileID)
//var newfile = DriveApp.getFileById(masterID).makeCopy(code + ' DCS WK'+weeknr,
DriveApp.getFolderById(folderID))
//var newID = newfile.getId()
tempArray.push([fileID.getName(), fileIDs[i], fileID.getUrl(),
fileID.getLastUpdated(), "Archived", masterfolders[i], archivefolders[i], weeknr])
//weekfolder.addFile(newfile)
}
Logger.log(tempArray)
if (tempArray.length > 0) {
fileslog.getRange(fileslog.getLastRow() + 1, 1, tempArray.length, 8).setValues(tempArray)
}
}
Posted the answer for documentation purpose.
As discussed in the comments the problem was the file size, splitting the copied files in batches did the trick:
So turns out, the file was simply too large to create 70 files in the allotted time. So I split it down to batches of 30 and its worked perfectly. thanks for your help

Highlighting selected fields in dynamically added rows makes them disappear

NOTE: Please no Jquery answers, need to get my head around Javascript first.
So I have added some rows to my table through insertRow(-1).
When I try to look up that table via getElementById and change the background color of a field, it works fine for the first added row:
"dates[4].style.backgroundColor = '#FF0000';"
But not for the second added row or thereafter, they just disappear:
"dates[7].style.backgroundColor = '#FF0000';
I am trying to highlight the current day (will replace the numbers 4/7 with a variable) I'm not sure whats happening, could anyone shed some light please?
Javascript
<script type="text/javascript">
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var hour = currentTime.getHours()
var min = currentTime.getMinutes()
//document.write(month + "/" + day + "/" + year)
var test = currentTime.getDay();
var day = currentTime.getDate()+1;
var month = currentTime.getMonth();
var full_year = currentTime.getFullYear();
var total_days = (daysInMonth(month,full_year));
var d=1;
function daysInMonth(month,year) {
return new Date(year, month, 0).getDate();
}
var temp = test+1;
for(i=0; i<5; i++){
var table = document.getElementById("calendar");
var row = table.insertRow(-1);
row.setAttribute("id", "rowClassName", 0);
for(c=1;c<8; c++){
if(d<test){
var newCell = row.insertCell(-1);
newCell.innerHTML = '0';
d++;
} else if ((temp-test)<=total_days){
var newCell = row.insertCell(-1);
newCell.innerHTML = (temp-test);
temp = temp+1;
if(temp==day){
var table1 = document.getElementById("rowClassName");
var dates = table1.getElementsByTagName('td');
dates[7].style.backgroundColor = '#FF0000';
}
}
}
}
HTML
<table id="calendar">
<tr>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
</table>
Change:
var table1 = document.getElementById("rowClassName");
To:
var table1 = document.getElementById("calendar");
Explanation:
You are only getting the cells for the current row using "rowClassName". Each row only consists of 7 elements (Mon-Sun). [7] means you are selecting the 8th cell in that row, which doesn't exist (JavaScript arrays are 0-based - the first element starts from 0).
So now what you want to do is count the number of table cells from the start of the table, inclusive of those in the first row.
Also, if you do it this way, the table cell you are trying to reference may not been created by the loop yet. You should set the red color outside of the two loops, or set a class to the cell, and use CSS to style the background color.
Snippet:
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var hour = currentTime.getHours()
var min = currentTime.getMinutes()
//document.write(month + "/" + day + "/" + year)
var test = currentTime.getDay();
var day = currentTime.getDate() + 1;
var month = currentTime.getMonth();
var full_year = currentTime.getFullYear();
var total_days = (daysInMonth(month, full_year));
var d = 1;
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
var temp = test + 1;
for (i = 0; i < 5; i++) {
var table = document.getElementById("calendar");
var row = table.insertRow(-1);
row.setAttribute("id", "rowClassName"+1, 0);
for (c = 1; c < 8; c++) {
if (d < test) {
var newCell = row.insertCell(-1);
newCell.innerHTML = '0';
d++;
} else if ((temp - test) <= total_days) {
var newCell = row.insertCell(-1);
newCell.innerHTML = (temp - test);
temp = temp + 1;
if (temp == day) {
newCell.className = "current";
}
}
}
}
.current {
background-color: red;
}
<table id="calendar">
<tr>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
</table>

Google Apps Script validation issue in Google UiApp

I have been trying to figure out Google Apps Script validation in Google Sites and have yet to make the validation part work correctly.
I need to validate 2 things:
That there is at least 5 characters in the "location" textbox (up to 100)
That a date has been selected from the dropdown
If both conditions are not met, then it should make visible 2 things:
warnException
warnExceptionMes
That's it.
The rest of my logic is working great. I am just starting out.
The full logic is listed below. I have replaced our domain info with xxxxxxxxx.
So far, it either never shows the messages and does nothing or just getting one of the items right allows it to move forward. They should both meet the requirements or the warnExceptions should be thrown. This would also be the same if a user loaded the page and did not fill either/or area out and just pushed the button.
How can I validate the Location textbox and the dateBox?
var templateIDToCopy = 'xxxxxxxxxx';
var folderIDtoCopyTo = 'xxxxxxxxxx';
var councilMembers = ['Unknown','Name 1','Name 2'];
function doGet(e) {
var text= new Array();
var app = UiApp.createApplication();
var hpanel = app.createGrid(4, 6).setId('pannel');
var hpanelException = app.createGrid(2,3).setId('hpanelException');
var location = app.createTextBox().setName('location').setId("location").setWidth('200');
var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
for (var i = 0 ; i < councilMembers.length; i++) {
minuteTaker.addItem(councilMembers.valueOf()[i]);
}
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
var hour = app.createListBox(false).setId('hour').setName('hour')
// var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=1;h<13;++h){hour.addItem(h)}
var min = app.createListBox(false).setId('minute').setName('minute')
.addItem('00').addItem('15').addItem('30').addItem('45');
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(196, 25);
var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
// Setup error message
var warnException =app.createImage('https://sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/Opps.png').setId('warnException').setVisible(false);
var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').setVisible(false);
// handlers
var handler1 = app.createClientHandler()
.validateLength(location, 0, 50).validateMatches(dateBox, '2', 'g')
.forTargets(warnException).setVisible(true)
.forTargets(warnExceptionMes).setVisible(true);
var handler2 = app.createServerHandler('handlerFunction')
.validateLength(location, 1, 100).validateNotMatches(dateBox, '2', 'g')
.addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
submit.addClickHandler(handler1).addClickHandler(handler2);
hpanel.setWidget(0,0,app.createLabel('Select Date'))
.setWidget(0,1,app.createLabel('Hour'))
.setWidget(0,2,app.createLabel('Minutes'))
.setWidget(0,3,app.createLabel('AM/PM'))
.setWidget(0,4,app.createLabel('Location'))
.setWidget(0,5,app.createLabel('Minute Taker'))
hpanel.setWidget(1,0,dateBox)
.setWidget(1,1,hour)
.setWidget(1,2,min)
.setWidget(1,3,amPm)
.setWidget(1,4,location)
.setWidget(1,5,minuteTaker)
hpanel.setWidget(2,5,submit)
app.add(hpanel);//.add(warnException).add(warnExceptionMes);
hpanelException.setWidget(1,1,warnException).setStyleAttribute("text-align", "right")
.setWidget(1,2,warnExceptionMes)
// .setWidget(1,2,nextSteps)
app.add(hpanelException);
return app;
}
function handlerFunction(e) {
var app = UiApp.getActiveApplication();
app.getElementById('submit').setText('Building, please wait...').setEnabled(false);
var location = e.parameter.location;
var determineName = e.parameter.minuteTaker;
var date = e.parameter.dateBox;
var timeZone = date.toString().substr(25,6)+":00";
var dateMilli = date.getTime();
var hour = parseInt(e.parameter.hour);
var amPm = e.parameter.amPm;
if (amPm == 'PM' && hour != 12) hour = hour + 12;
if (hour == 12 && amPm == 'AM') hour = 0;
var hourMilli = hour * 3600000;
var minMilli = parseInt(e.parameter.minute) * 60000;
var milliTotal = dateMilli + hourMilli + minMilli;
// create custom format
var newDate = Utilities.formatDate(new Date(milliTotal), timeZone, 'MM/dd/yy hh:mm aaa');
app.getElementById('dateTimeLabel').setText(newDate);
// make a copy of the minutes template to use
var duplicateID = DriveApp.getFileById(templateIDToCopy)
.makeCopy('Simply Minutes v1.0 - Stage 1: Building new minutes...')
.getId();
// get the id of the annual folder where minutes will be stored
var getFolderID = DriveApp.getFolderById(folderIDtoCopyTo);
// copy new minutes sheet to the annual folder where minutes are stored
var moveIT = DriveApp.getFileById(duplicateID).makeCopy('Simply Minutes v1.0 - Stage 2: Building new minutes...', getFolderID).getId();
// get the new minutes doc that was created
var template = DocumentApp.openById(moveIT);
var templateHeader = template.getHeader();
var templateBody = template.getActiveSection();
// fill in the values
templateHeader.replaceText("<date>", newDate);
templateBody.replaceText("<date>", newDate);
templateHeader.replaceText("<location>", location);
templateBody.replaceText("<location>", 'N/A');
var email = Session.getEffectiveUser().getEmail();
var eUser = Session.getEffectiveUser().getUsername();
var createdBy = '';
if(ContactsApp.getContact(email)){
var fullName = ContactsApp.getContact(email).getFullName();
createdBy = fullName;
}
else {
createdBy = 'N/A';
};
var determineName = e.parameter.minuteTaker;
templateHeader.replaceText("<minutetaker>", determineName);
templateHeader.replaceText("<createdby>", createdBy)
templateBody.replaceText("<minutetaker>", determineName);
templateBody.replaceText("<createdby>", createdBy);
template.setName(newDate + ' TAC Minutes Recorded By ' + determineName);
// close out the doc
template.saveAndClose();
// remove the copy that was left in the root directory
// DriveApp.getFileById(duplicateID).isTrashed();
DriveApp.getFileById(duplicateID).setTrashed(true);
app = UiApp.getActiveApplication();
app.getElementById('submit').setText('Completed!').setEnabled(false);
app.getElementById('nextSteps').setVisible(true);
return app;
}
Try like this (see below) I changed a bit the validations and separated in 2 handlers + added a "clear" handler to be able to click-to-delete the warnings... test code here
You have also to add something to clear the warnings in the server handler and, why not combine the image and text warning in a single widget ? (easier to clean)
code below :
function doGet(e) {
var text= new Array();
var app = UiApp.createApplication();
var hpanel = app.createGrid(4, 6).setId('pannel');
var clearHandler = app.createClientHandler().forEventSource().setVisible(false)
var hpanelException = app.createGrid(2,3).setId('hpanelException');
var location = app.createTextBox().setName('location').setId("location").setWidth('200');
var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
for (var i = 0 ; i < councilMembers.length; i++) {
minuteTaker.addItem(councilMembers.valueOf()[i]);
}
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
var hour = app.createListBox(false).setId('hour').setName('hour')
// var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=1;h<13;++h){hour.addItem(h)}
var min = app.createListBox(false).setId('minute').setName('minute')
.addItem('00').addItem('15').addItem('30').addItem('45');
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(196, 25);
var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
// Setup error message
var warnException =app.createImage('https://sites.google.com/xxxxxxxxxx/minutes/create-new-minutes/Opps.png').setId('warnException').setVisible(false).addClickHandler(clearHandler);
var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').setVisible(false).addClickHandler(clearHandler);
// handlers
var handler0 = app.createClientHandler()
.validateLength(location, 0, 5)
.forTargets(warnException).setVisible(true)
.forTargets(warnExceptionMes).setVisible(true);
var handler1 = app.createClientHandler()
.validateNotMatches(dateBox, '2', 'g')
.forTargets(warnException).setVisible(true)
.forTargets(warnExceptionMes).setVisible(true);
var handler2 = app.createServerHandler('handlerFunction')
.validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
.addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
submit.addClickHandler(handler0).addClickHandler(handler1).addClickHandler(handler2);
hpanel.setWidget(0,0,app.createLabel('Select Date'))
.setWidget(0,1,app.createLabel('Hour'))
.setWidget(0,2,app.createLabel('Minutes'))
.setWidget(0,3,app.createLabel('AM/PM'))
.setWidget(0,4,app.createLabel('Location'))
.setWidget(0,5,app.createLabel('Minute Taker'))
hpanel.setWidget(1,0,dateBox)
.setWidget(1,1,hour)
.setWidget(1,2,min)
.setWidget(1,3,amPm)
.setWidget(1,4,location)
.setWidget(1,5,minuteTaker)
hpanel.setWidget(2,5,submit)
app.add(hpanel);//.add(warnException).add(warnExceptionMes);
hpanelException.setWidget(1,1,warnException).setStyleAttribute("text-align", "right")
.setWidget(1,2,warnExceptionMes)
// .setWidget(1,2,nextSteps)
app.add(hpanelException);
return app;
}
EDIT second version following your comment.
I simulated a server function that takes some time so you see all the steps. + I combined the warning as suggested. (demo code updated with version 2)
var templateIDToCopy = 'xxxxxxxxxx';
var folderIDtoCopyTo = 'xxxxxxxxxx';
var councilMembers = ['Unknown','Name 1','Name 2'];
function doGet(e) {
var text= new Array();
var app = UiApp.createApplication();
var hpanel = app.createGrid(4, 6).setId('pannel');
var hpanelException = app.createGrid(2,3).setId('hpanelException');
var location = app.createTextBox().setName('location').setId("location").setWidth('200');
var minuteTaker = app.createListBox().setName('minuteTaker').setId("minuteTaker").setWidth('200')
for (var i = 0 ; i < councilMembers.length; i++) {
minuteTaker.addItem(councilMembers.valueOf()[i]);
}
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox').setFireEventsForInvalid(false);
var hour = app.createListBox(false).setId('hour').setName('hour')
// var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=1;h<13;++h){hour.addItem(h)}
var min = app.createListBox(false).setId('minute').setName('minute')
.addItem('00').addItem('15').addItem('30').addItem('45');
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Create Minutes').setId('submit').setPixelSize(195, 65);
var nextSteps = app.createAnchor('Please click here to see the minutes archive.', 'https://drive.google.com/xxxxxxxxxx/folderview?xxxxxxxxxx').setId('nextSteps').setVisible(false);
var clearHandler = app.createClientHandler();
// Setup error message
var warnException =app.createImage('https://dl.dropboxusercontent.com/u/211279/clock_e0.gif').addClickHandler(clearHandler);
var warnExceptionMes = app.createLabel('The date and Location are required. Please try again.').setStyleAttribute('font-weight', 'normal').setStyleAttribute('font-size','14px').addClickHandler(clearHandler);
var warnPanel = app.createHorizontalPanel().add(warnException).add(warnExceptionMes).setId('warning').setVisible(false);
clearHandler.forTargets(warnPanel).setVisible(false);
// handlers
var handler0 = app.createClientHandler()
.validateLength(location, 0, 5)
.forTargets(warnPanel).setVisible(true)
var handler1 = app.createClientHandler()
.validateNotMatches(dateBox, '2', 'g')
.forTargets(warnPanel).setVisible(true)
var handler2 = app.createClientHandler()
.validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
.forEventSource().setText('Server Handler is running...').setEnabled(false)
.forTargets(warnPanel).setVisible(false);
var handlerS = app.createServerHandler('handlerFunction')
.validateLength(location, 6, 100).validateMatches(dateBox, '2', 'g')
.addCallbackElement(location).addCallbackElement(dateBox).addCallbackElement(hpanel);
submit.addClickHandler(handler0).addClickHandler(handler1).addClickHandler(handler2).addClickHandler(handlerS);
hpanel.setWidget(0,0,app.createLabel('Select Date'))
.setWidget(0,1,app.createLabel('Hour'))
.setWidget(0,2,app.createLabel('Minutes'))
.setWidget(0,3,app.createLabel('AM/PM'))
.setWidget(0,4,app.createLabel('Location'))
.setWidget(0,5,app.createLabel('Minute Taker'))
hpanel.setWidget(1,0,dateBox)
.setWidget(1,1,hour)
.setWidget(1,2,min)
.setWidget(1,3,amPm)
.setWidget(1,4,location)
.setWidget(1,5,minuteTaker)
hpanel.setWidget(2,5,submit)
app.add(hpanel);
hpanelException.setWidget(1,1,warnPanel).setStyleAttribute("text-align", "right")
app.add(hpanelException);
return app;
}
function handlerFunction(e) {
var app = UiApp.getActiveApplication();
Utilities.sleep(1000);
app.getElementById('submit').setText('SERVER HANDLER is DONE');
// app.getElementById('warning').setVisible(false);// not necassary anymore, see clientHandler2
return app;
}

Setting a JSF list box directly from javascript

I'd like to directly set the listbox elements defined in a jsf block via setting them in a javascript code, but the document.getElementById() returns null ?
JSF Code:
<h:panelGroup id="dtEffectiveDate">
<h:outputText value="EffectiveDates:" style="margin-left: 250px;width:76px;"/>
<h:selectManyListbox id="effectiveDateListbox" style="margin-left: 15px; width:76px;" size="2">
<c:selectItems id="effectiveDateSelectItems" value="#{manualDataEntryRegText.effectiveDates}"/>
</h:selectManyListbox>
</h:panelGroup>
JavaScript code:
CalendarPopup.handleSelectForMultipleDates = function(type, args, obj, inputEl)
{
alert("MultiSelect");
var arrDates = CalendarPopup.effectiveDateCalendar.getSelectedDates();
var length = arrDates.length;
var i=0;
var tokenizedDates = "";
var txtDate = document.getElementById("pageForm:effectiveDateListbox");
alert(txtDate); // returns null
for (i = 0; i!= length; i++)
{
var date = arrDates[i];
var displayMonth = date.getMonth() + 1;
var displayYear = date.getFullYear();
var displayDate = date.getDate();
tokenizedDates = displayMonth.toString(10) + "/" + displayDate.toString(10) + "/" + displayYear.toString(10);
effectiveDateListbox.options[i].value = tokenizedDates;
i++;
}
}
EDIT: I am able to get the listbox but cannot set it:
How do I set the listbox ?
var listBox = document.getElementById('pageForm:effectiveDateListbox');
for (i = 0; i!= length; i++)
{
var date = arrDates[i];
var displayMonth = date.getMonth() + 1;
var displayYear = date.getFullYear();
var displayDate = date.getDate();
tokenizedDates = displayMonth.toString(10) + "/" + displayDate.toString(10) + "/" + displayYear.toString(10);
listBox.options[i].value = tokenizedDates;
i++;
}
This should not return null:
<select id="pageForm:effectiveDateListbox" name="pageForm:effectiveDateListbox" multiple="multiple" size="0"></select>
document.getElementById('pageForm:effectiveDateListbox');
If it is, it might be that the select element does not exist at the time your javascript is running. To protect against that you could try:
window.onload = function(){
// do stuff here
};

Categories

Resources