I was given a task to make small change in schedule appointment calendar, the goal of this task is to display number of appointments per day(number of events can be displayed above of under day, see screenshot below). This app uses Full Calendar v1.5.4. I was looking at full calendar documentation but I didn't find anything useful there, this app already utilizes allDayText so it can not be applied there.
Do you know how can I create a new row below or above a day header and add there information about number of events that are happening that day?
Edit:
I've came up with the this code, added it in buildSkeleton method. Added 7 to i so column has unique value.
"<tr>" +
"<th class='fc-agenda-axis " + headerClass + "'> </th>";
for (i = 0; i < colCnt; i++) {
s += "<th class='fc- fc-col" + i+7 + ' ' + headerClass + "'/>";
}
s += "<th class='fc-agenda-gutter " + headerClass + "'> </th>" +
"</tr>" +
Which gives me a row that I need but for some reason it changes size of the first and last column.
Once styling will be fixed I'll have to find a place where I can insert a number of events.
Function below gives desired behavior, it updates number of events whenever view is changed.
Although I'm not able to adjust size of the first and last columns in header to the previous state, as you can see at the second screenshot they are way wider. I checked css file attached to the fullCalendar but didn't find anything there, it seems to be updated in fullCalendar.js file.
function SetCount(events) {
var startDate = calendar.getView().start;
var endDate = calendar.getView().end;
var e = events.filter(e => e.isBlockAppointment === false && startDate <= e.start && e.start <= endDate);
var hist = {};
dates = [];
e.map(function(a) { dates.push(a.start.getDay()) });
dates.map(function (a) { if (a in hist) hist[a]++; else hist[a] = 1; });
var colCnt = getColCnt();
if (colCnt === 1) {
$('.Index0').text(Object.keys(hist).length === 0 ? 0 : hist[Object.keys(hist)[0]]);
} else {
for (var i = 0; i < colCnt; i++) {
$('.Index' + i).text(i in hist ? hist[i]: 0);
}
}
}
Before:
After:
I tried add rowspan="2" to these rows and removed them from the second row but it doesn't work. How can I change a size of these 2 columns?
"<th class='fc-agenda-axis " + headerClass + "'> </th>";
"<th class='fc-agenda-gutter " + headerClass + "'> </th>"
Related
I have a function to append table rows whenever a user selects values from checkbox popup window. If the user selects same or different check box values , the old values should be deleted. My code is not deleting/replacing the old row and somehow it deletes the name of the old row and creates extra table data values.
https://imgur.com/JjQjTaW
In this case, the second circled table row should have replaced the first circled row.
function AppendSampleTable(specimenNumberTextBoxId, specimenArray, _combinatedIdForSampleTbl) {
// var specimenNumberTextBoxId = "MOLECULAR DIAGNOSTICSSpec1";
var sampleTable = document.getElementById('ctl00_ContentPlaceHolder1_tblSample');
// var sampleTable = document.getElementById('ctl00_ContentPlaceHolder1_sampleNum6');
var specimenType = document.getElementById(specimenNumberTextBoxId).getAttribute("specimentype");
var poolSpecimenCode = document.getElementById(specimenNumberTextBoxId).getAttribute("poolspecimen");
var specimenNumber = "test";
var tableRows = $(sampleTable).find('tr');
var rowIndex = tableRows.length;
var i = 0;
var newRow;
var specimenArrayLength = specimenArray.length - 1; // Because specimenArray contains empty string for first element.
// Erase tr that has same name as requested.
var $oldRow = $(sampleTable).find('tr[name="' + _combinatedIdForSampleTbl + '"]'); //WHY IS THIS NOT WORKING OR IS IT? SHOUDL IT REMOVE OLD ROWS?// 3/28/2019
alert("old row=" + $oldRow);
$oldRow.remove();
// Append tr that contains desired values.
for (i; i < specimenArrayLength; i++) {
// If none of specimen has choosen for a pool, array will contain 'undefined', so we need to ignore that not to be appended into table.
if (specimenArray[i + 1] != undefined) {
specimenNumber = specimenArray[i + 1];
newRow = "<tr name='" + _combinatedIdForSampleTbl + "'><td class='col-xs-2'><span id='ctl00_ContentPlaceHolder1_sampleName" + (rowIndex + i + 1) + "' specimenCode='" + poolSpecimenCode + "'>POOL - " + specimenType + "</span></td><td class='col-xs-2'><span id='ctl00_ContentPlaceHolder1_sampleNum" + (rowIndex + i + 1) + "'>" + specimenNumber + "</span></td></tr>";
$(sampleTable).append(newRow);
}
}
}
I expect my code to replace the old row and not have extra empty table data values.
I am seeking help trying to add a new table in my third function called ingredients. I am not very familiar with javascript so I tried to duplicate code from newDosage which is similar to what I need to do. Unfortunately, right now all I see is 0, 1, or 2 and not the actual text from the ingredient table. If anyone can help me correctly call the table, it would be greatly appreciated. Thank you.
Below is my code. The first function pulls the database, the second function uses the results and the third function is where I have tried to add the ingredient table.
function listTreatmentDb(tx) {
var category = getUrlVars().category;
var mainsymptom = getUrlVars().mainsymptom;
var addsymptom = getUrlVars().addsymptom;
tx.executeSql('SELECT * FROM `Main Database` WHERE Category="' + category +
'" AND Main_Symptom="' + mainsymptom + '" AND Add_Symptom="' + addsymptom + '"',[],txSuccessListTreatment);
}
function txSuccessListTreatment(tx,results) {
var tubeDest = "#products";
var len = results.rows.length;
var treat;
for (var i=0; i < len; i = i + 1) {
treat = results.rows.item(i);
$("#warning").append("<li class='treatment'>" + treat.Tips + "</li>");
$("#warning-text").text(treat.Tips);
$('#warning').listview('refresh');
//console.log("Specialty Product #1: " + treat.Specialty1);
if(treat.Specialty1){
$("#products").append(formatProductDisplay('specialty1', treat.Specialty1, treat.PurposeSpecialty1, treat.DosageSpecialty1, '1'));
}
if(treat.Specialty2){
$("#products").append(formatProductDisplay('specialty2', treat.Specialty2, treat.PurposeSpecialty2, treat.DosageSpecialty2, '0'));
}
}
}
function formatProductDisplay(type, productName, productPurpose, productDosage, Ingredients, aster){
var newDosage = productDosage.replace(/"\n"/g, "");
if(aster=='1'){ productHTML += "*" }
productHTML+= "</div>" +
"</div>" +
"<div class='productdose'><div class='label'>dosage:</div>" + newDosage + "</div>" +
"<div class='productdose'><div class='label'>ingredients:</div>" + Ingredients +
"</div></li>"
return productHTML;
}
You are missing an argument when you call formatProductDisplay(). You forgot to pass in treat.Ingredient.
Change:
$("#products").append(formatProductDisplay('specialty1', treat.Specialty1, treat.PurposeSpecialty1, treat.DosageSpecialty1, '1'));
To:
$("#products").append(formatProductDisplay('specialty1', treat.Specialty1, treat.PurposeSpecialty1, treat.DosageSpecialty1, treat.Ingredients, '1'));
Also do the same thing to the similar 'Specialty2' line right below it.
I have a method called refreshHistory() that basically reads locally stored list of json (using https://github.com/marcuswestin/store.js/) and populates a list in the order they were stored at.
Everytime a user action happens, this method is called. But as the list gets bigger and bigger, it slows down the browser to a crawl.
function refreshHistory() {
var records = typeof store.get('history') == "undefined" ? 0 : store.get('history').history;
;
if (records == 0) {
$('#content #historyView').html('<i>history show up here in order.</i>');
} else {
var xhistory = '<div id="history">';
for (var i = 0; i < records.length; i++) {
var xaction = records[i]
xhistory += '<div id="action">' + (i + 1) + '. ' + '<b>' + xaction.action + "</b> " + xaction.caption + '<span class="delaction" id=' + i + ' data-stamp="' + xaction.msg + '" style="color:red;cursor:pointer;">' + '[remove]' + '</span></div>'
}
xhistory += "</div>"
$('#qtip-0-content #historyView').html(xhistory);
}
}
Rendering everything on every event is a simple strategy, which is good, but it does run into the performance problems you are describing. It's hard to give specific advice, but you could either:
Implement a more detailed rendering logic, where only new items are rendered and added to the DOM.
Use ReactJs or Virtual DOM libraries, which allow your code to use the render everything pattern, but make the actual updates to the DOM faster by doing the minimum needed.
The only way to really make this efficient is to implement it in a different way.
I've been using knockout.js personally and am very happy with it. Basically you write a template and the library handles the DOM node changes, only updating the parts needed. You will need to learn how to think slightly differently, but there are some great tutorials available.
That said, one simple trick you can try is move the selectors outside the function so they are only ran once instead of each time you call the function.
For sanity I would also keep records variable the same type whether or not the .get('history') returns undefined.
var contentHistoryView = $('#content #historyView');
var qtipHistoryView = $('#qtip-0-content #historyView');
function refreshHistory() {
var records = typeof store.get('history') == "undefined" ? [] : store.get('history').history;
if (records.length) {
contentHistoryView.html('<i>history show up here in order.</i>');
} else {
var xhistory = '<div id="history">';
for (var i = 0; i < records.length; i++) {
var xaction = records[i]
xhistory += '<div id="action">' + (i + 1) + '. ' + '<b>' + xaction.action + "</b> " + xaction.caption + '<span class="delaction" id=' + i + ' data-stamp="' + xaction.msg + '" style="color:red;cursor:pointer;">' + '[remove]' + '</span></div>'
}
xhistory += "</div>"
qtipHistoryView.html(xhistory);
}
}
I doubt this will have a huge impact though, as I suspect most of the execution time is spent in the loop.
I'm using Slickgrid to display data on a html site. The user can choose a table and the columns.
The code works well, but one table contains around 30 columns and around 500000 rows. Now the script takes too long and I get a firefox javascript timeout.
I know, that i can use setTimeout(), but i don't know how to use in this function.
What can i do, to avoid the javascript timeout?
function addRow(){
for (var i=0;i<arrayRow.length;i++){
var row ='{"id": "' + i + '", ';
for (var j=0;j>arrayColumn.length;j++){
row = row + '"' + arrayColumn[j] + '" : "' + array[j]+[i] + '",'
}
row = row.substr(0,row.length-1);
row = row + '}';
data[i]=JSON.parse(row);
}
if (i==arrayRow.length){
dataView.setItems(data);
}
}
Edit1: I've updated my code, but now I get the error "too much recursion".
i=0;
function addRow(){
if (i<arrayRow.length){
var row ='{"id": "' + i + '", ';
for (var j=0;j>arrayColumn.length;j++){
row = row + '"' + arrayColumn[j] + '" : "' + array[j]+[i] + '",'
}
row = row.substr(0,row.length-1);
row = row + '}';
data[i]=JSON.parse(row);
i++;
if(i%100000==0){
setTimeout(addRow,0);
} else {
addRow();
}
}
if (i==arrayRow.length){
dataView.setItems(data);
}
}
The timeout for script execution measure the time that took the execution of one method.
You need to separete "for" loop into several loops. For example you can make a method that add 100000 rows and call it with settimeout 5 times
Maybe it should be something like that:
var iFirstRow = 0;
funtion AddRows( _iFirstRow, _nRowsToAdd )
{
..implementation of adding nRows
iFirstRow = iFirstRow + nRowsToAdd;
if ( There is rows to add )
{
Call AddRows via timeout
}
else
{
..its ready
}
}
Basically this is supposed to find the values in specific columns of the row and add them together to get a total and place that total in the cell specified. It is not working for some reason.
function rating(Irange,Q,Y,AG,AO,AW,BE,BM) {
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
var range = sheet.getRange(Irange);
var row = Irange.getRow();
var total = Number(values[row][8]) +
Number(values[row][9]) +
Number(values[row][10]) +
Number(values[row][11]) +
Number(values[row][16]) +
Number(values[row][17]) +
Number(values[row][18]) +
Number(values[row][19]) +
Number(values[row][24]) +
Number(values[row][25]) +
Number(values[row][26]) +
Number(values[row][27]) +
Number(values[row][32]) +
Number(values[row][33]) +
Number(values[row][34]) +
Number(values[row][35]) +
Number(values[row][40]) +
Number(values[row][41]) +
Number(values[row][42]) +
Number(values[row][43]) +
Number(values[row][48]) +
Number(values[row][49]) +
Number(values[row][50]) +
Number(values[row][51]) +
Number(values[row][56]) +
Number(values[row][57]) +
Number(values[row][58]) +
Number(values[row][59]) +
Number(values[row][64]) +
Number(values[row][65]) +
Number(values[row][66]) +
Number(values[row][67]);
return total;
}
It looks odd that you're doing
var range = sheet.getRange(Irange);
...and then not using that range for anything. Instead, on the next line, you have:
var row = Irange.getRow();
I haven't done virtually anything with Google Docs Spreadsheets, but perhaps that should be range.getRow() (no I), since Range objects have a getRow method. (Naturally I have no idea what your Irange argument is, but it looks like you're using it as a string when calling getRange(a1Notation)).