Preserve Formatting When Setting New Cell Value (Google Spreadsheet) - javascript

I have the following script which sets a new value for a selected spreadsheet cell. It works as expected but after every entry it clears all the previous formatting from the cell. How can I modify the code to make sure it preserves all the partial formatting, such as font weight/color? Thank you for your help.
function enterName1(options1, activity1, number1) {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var value = cell.getValue();
var formattedDate = Utilities.formatDate(new Date(), "GMT+3", "dd.MM.yy' at 'HH:mm");
Logger.log(formattedDate);
if (value === '') {
value = value + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
sheet.getActiveRange().setNumberFormat('#STRING#');
cell.setValue(value);
} else {
value = value + "\n\n" + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
sheet.getActiveRange().setNumberFormat('#STRING#');
cell.setValue(value);
}
}

I believe your goal as follows.
Question 1: You want to preserve the existing text styles of the text in the cell when the value is added to the cell including the values.
Question 2: You want to preserve the existing text styles of the text in the cell when the value is added to the cell including the values. And also, you want to set the text style for formattedDate of the adding text.- Question 3: You want to preserve the existing text styles of the text in the cell when the value is added to the cell including the values. And also, you want to set the text style for formattedDate of the adding text. And also, even when the cell is empty, you want to set the text style for formattedDate of the adding text.
Answer for question 1:
Modification points:
In this case, it is required to retrieve the text styles of the existing values and set the text styles after the value was added. "RichTextValue" is used for this.
When your script is modified, it becomes as follows.
Modified script:
From:
} else {
value = value + "\n\n" + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
sheet.getActiveRange().setNumberFormat('#STRING#');
cell.setValue(value);
}
To:
} else {
value = value + "\n\n" + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
var richTextValue = cell.getRichTextValue();
var existingStyles = richTextValue.getRuns().map(e => ({start: e.getStartIndex(), end: e.getEndIndex(), style: e.getTextStyle()}));
var richTexts = SpreadsheetApp.newRichTextValue().setText(value);
existingStyles.forEach(e => richTexts.setTextStyle(e.start, e.end, e.style));
cell.setRichTextValue(richTexts.build());
cell.setNumberFormat('#STRING#');
}
In this modified script, the text styles of the existing value are set. So the added text has no text style. Please be careful this.
Answer for question 2:
Modification points:
In this case, it is required to retrieve the text styles of the existing values and also set the text style for formattedDate, and then, set the text styles after the value was added. "RichTextValue" is also used for this.
When your script is modified, it becomes as follows.
Modified script:
From:
} else {
value = value + "\n\n" + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
sheet.getActiveRange().setNumberFormat('#STRING#');
cell.setValue(value);
}
To:
} else {
var textStyle = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor("#FF0000").build(); // Please set this for the additional text.
var richTextValue = cell.getRichTextValue();
var existingStyles = richTextValue.getRuns().map(e => ({start: e.getStartIndex(), end: e.getEndIndex(), style: e.getTextStyle()}));
var startOffset = (value + "\n\n" + "📞 ").length;
existingStyles.push({start: startOffset, end: startOffset + formattedDate.length, style: textStyle});
var richTexts = SpreadsheetApp.newRichTextValue().setText(value + "\n\n" + "到 " + formattedDate + " call " + options1 + number1 + ": " + activity1);
existingStyles.forEach(e => richTexts.setTextStyle(e.start, e.end, e.style));
cell.setRichTextValue(richTexts.build());
cell.setNumberFormat('#STRING#');
}
In this modified script, the text styles of the existing value and formattedDate of the adding text are set.
As above sample, formattedDate has the bold and red font color.
Answer for question 3:
Modification points:
In this case, it is required to retrieve the text styles of the existing values and also set the text style for formattedDate, and then, set the text styles after the value was added. "RichTextValue" is also used for this. And also, when the cell is empty, it is required to set the text style for formattedDate of the adding text.
When your script is modified, it becomes as follows.
Modified script:
From:
if (value === '') {
value = value + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
sheet.getActiveRange().setNumberFormat('#STRING#');
cell.setValue(value);
} else {
value = value + "\n\n" + "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
sheet.getActiveRange().setNumberFormat('#STRING#');
cell.setValue(value);
}
To:
var textStyle = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor("#FF0000").build(); // Please set this for the additional text.
if (value === '') {
value = "📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1;
var richTexts = SpreadsheetApp
.newRichTextValue()
.setText("📞 " + formattedDate + " call " + options1 + number1 + ": " + activity1)
.setTextStyle(("📞 ").length, ("📞 " + formattedDate).length, textStyle);
cell.setRichTextValue(richTexts.build());
cell.setNumberFormat('#STRING#');
} else {
var richTextValue = cell.getRichTextValue();
var existingStyles = richTextValue.getRuns().map(e => ({start: e.getStartIndex(), end: e.getEndIndex(), style: e.getTextStyle()}));
var startOffset = (value + "\n\n" + "📞 ").length;
existingStyles.push({start: startOffset, end: startOffset + formattedDate.length, style: textStyle});
var richTexts = SpreadsheetApp.newRichTextValue().setText(value + "\n\n" + "到 " + formattedDate + " call " + options1 + number1 + ": " + activity1);
existingStyles.forEach(e => richTexts.setTextStyle(e.start, e.end, e.style));
cell.setRichTextValue(richTexts.build());
cell.setNumberFormat('#STRING#');
}
Reference:
Class RichTextValue

Related

Attempting to output to a text box with Javascript

I'm creating a communications generator that will standardise SMS communications regarding critical IT incidents for my company. I've got an IF/ELSE statement that identifies whether an issue is new, updated, or resolved to pull the necessary information together and format it accordingly. As far as I can tell, everything here is fine, however I'm having an issue writing to a text box ('smsToSend') which should allow the user to review before they copy the text across to our sms sender app, as nothing is being output into this box.
function generateSMS(){
var issueTitle = document.getElementById("incidentTitle");
var advisorImpact = document.getElementById("advisorImpact";
var incidentUpdate = document.getElementById("incidentUpdate");
var incidentStatus = document.getElementById("incidentState");
var startTime = document.getElementById("startTime");
var endTime = document.getElementById("endTime");
var incidentPriority = document.getElementById("incidentPriority");
var incidentBrand = "TechTeam";
var systemImpacted = document.getElementById("systemImpacted");
var incidentReference = document.getElementById("incidentReference");
var smsToSend = document.getElementById("smsToSend");
if (incidentStatus != "Closed"){
smsToSend = "P" + incidentPriority + " " + incidentBrand + "IT RESOLVED: " + systemImpacted + ": " + incidentUpdate + ": Start: " + startTime + " End: " + endTime + " Reference: " + incidentReference;
}
else{
if (incidentUpdate == "We are investigating this issue"){
smsToSend = "P" + incidentPriority + " " + incidentBrand + "IT ISSUE: " + systemImpacted + ": " + issueTitle + ". " + advisorImpact + ": " + incidentReference;
}
else {
smsToSend = "P" + incidentPriority + " " + incidentBrand + "IT UPDATE: " + systemImpacted + ": " + incidentUpdate + ": " + incidentReference;
}
}
}
generateSMS();
alert.getElementById(smsToSend);
Try replacing all assignments to smsToSend like this:
smsToSend = yourValue;
With this:
smsToSend.value = yourValue;
Your problem happens because smsToSend is an instance of an element, rather than a variable linked to the displayed text. To update the element's value, you have to change the value property of the element.
The Right way of setting the value to a text box is
var smsToSend = document.getElementById("smsToSend");
smsToSend.value = "Your value";

Get values from checkbox to calender

I'm new to this. And have a code. HTML form that has 4 Checkboxes
The result goes into a G-spreadsheet. From the Sheet I want the checked boxes values to polulate a Calendar event. Now it works but I get all the Checkboxes values in the calendar. Not only the ones that are checked.
function appendData(data){
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Records");
Logger.log(data)
// Lägg till rad i spreadsheet
ws.appendRow([data.name, data.email, data.cuser, data.lastday, data.telenor, data.comment, data.company, data.costacc, data.laptop, data.ipad, data.printer, data.router]);
// Create data for event
var title = data.name + " börjar sin anställning på Roche"
var date = new Date(data.lastday)
var description = "<b>Mobil + Abonnemang:</b>\n" + data.telenor + "\n\n" +
"<b>Bolag:</b>\n" + data.company + "\n\n" +
"<b>Övrig utrustning:</b>\n" + data.laptop + ", " + data.ipad + ", " + data.printer + ", " + data.router
"<b>Kopiera rättigheter från:</b>\n" + data.cuser + "\n\n" +
"<b>Övriga kommentarer:</b>\n" +
data.comment

Text input value is returning undefined without any error

I want to make alert message show the data of the form I input.But the text element's data doesn't work correctly.
<script type="text/javascript">
function showUserData(){
category = document.getElementById("category").value;
regicon = "";
var obj=document.getElementsByName("register");
for(idx in obj){
if(obj[idx].checked){
regicon += obj[idx].value;
}
}
title = document.getElementById("title").value;//here is the problem
author = document.getElementById("author").value;
email = document.getElementById("email").value;
content = document.getElementById("content").value;
password = document.getElementById("password").value;
coverdate = document.getElementById("coverdate").value;
contentimage = document.getElementById("contentimage").value;//
time_result = new Date();//기사등록일은 date()
window.alert("카테고리: "+category + "\n"
+ "등록상태: " + regicon + "\n"
+ "제목: " + title + "\n"
+ "이메일: " + email + "\n"
+ "기자: " + author + "\n"
+ "내용: " + content + "\n"
+ "취재일: " + coverdate + "\n"
+ "기사등록일: " + time_result + "\n");
}
</script>
When I run the code, the alert show 'undefined' at the title value.
I thought that the title value doesn't initialized so I tried
title = "";
It was not the solution.How can I make the function run correctly
Have you created a titlevariable? It seems to me you forgot to put "var" or "const" before the title variable.

How to pass Jquery value to code behind in asp.net

$("#getButtonValue").click(function () {
var msg = '';
for (i = 1; i < counter; i++) {
msg += "\n Width #" + i + " : " + $('#txtWidth' + i).val();
msg += "\n Height #" + i + " : " + $('#txtHeight' + i).val();
msg += "\n Length #" + i + " : " + $('#txtLength' + i).val();
msg += "\n Weight #" + i + " : " + $('#txtWeight' + i).val();
}
alert(msg);
});
This code return height,width,length and weight multiple time (With respect to conter).
I want to pass All this value to code behind file .And pass all value to this packeges.
qurystr += "&packages[1][width]=" ";
qurystr += "&packages[1][height]="";
qurystr += "&packages[1][length]="";
qurystr += "&packages[1][weight]="";
Please help.Thanks
You can Use Hidden Fields to Save your List as Comma Separated Values
<asp:HiddenField runat="server" id="hdf" />
In JS
$('<%#hdf.CliendID%>').value="1,2,3,4,5,6,7,8,9";
width,height,length,width,height,length....

How can create toggleable divs using javascript's innerhtml function?

I am trying to import information from an XML file, and create a name which, when clicked, will show more information. This information will be inside a div with no display until the header has been clicked.
This is the idea. Doesn't work.
$(document).ready(function () {
$.ajax({
type: "Get",
dataType: "xml",
url: 'service.xml',
success: function (xml) {
$(xml).find('Service[Name="j1979"]').find("Define").each(function () {
var PID = $(this).attr("PID");
var name = $(this).find("Name").text();
var source = $(this).find("source").text();
var doffset = $(this).find("DOffset").text();
var type = $(this).find("Type").text();
var length = $(this).find("Lenght").text();
var scale = $(this).find("Scale").text();
var noffset = $(this).find("NOffset").text();
var units = $(this).find("Units").text();
var moreinfo = "<div id='moreinfo'>source += '\r\n' += doffset += '\r\n' += type += '\r\n' += length += '\r\n' += scale += '\r\n' += noffset += '\r\n' += units</div>";
document.getElementById("j1979").innerHTML += PID += " ";
document.getElementById("j1979").innerHTML += < p onclick = "document.getElementById('moreinfo').style.display = 'inline-block'" > += "\r\n";
document.getElementById("j1979").innerHTML += moreinfo;
});
}
});
});
Sorry for any obvious mistakes and/or ugly code.
I assume that this is what you want to achieve: DEMO
just assume that the script in the demo is inside the success function
first, you have some error in here
document.getElementById("j1979").innerHTML += < p onclick = "document.getElementById('moreinfo').style.display = 'inline-block'" > += "\r\n";
this will not add the p element to the element with id j1979 because you write it like that, where you should be writing it like this
document.getElementById("j1979").innerHTML += "<p onclick=\"document.getElementById('moreinfo').style.display = 'inline-block';\" ></p>";
note the quotes at start and end, and the closing tag
second, there's no word or anything inside the p element that indicates that you could click it to show more information, so put the PID inside the p like this
document.getElementById("j1979").innerHTML += "<p onclick=\"document.getElementById('moreinfo').style.display = 'inline-block';\">" + PID + "</p>";
here's the full code with some CSS style to hide it before the user click on the PID
$(document).ready(function () {
var PID = "testPID";
var name = "Random Name";
var source = "Google";
var doffset = "1000";
var type = "A-9001";
var length = "50CM";
var scale = "100";
var noffset = "0";
var units = "Some Units";
var moreinfo = "<div id='moreinfo'>source: " + source + "</br>" + "doffset: " + doffset + "</br>" + "type: " + type + "</br>" + "length: " + length + "</br>" + "scale: " + scale + "</br>" + "noffset: " + noffset + "</br>" + "units: " + units + "</div>";
document.getElementById("j1979").innerHTML += "<p onclick=\"document.getElementById('moreinfo').style.display = 'inline-block';\">" + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
});
#moreinfo {
display: none;
}
#j1979 {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div id="j1979"></div>
From the code you have, you can use '+' operator to concatenate strings.
When you need to use single quote inside string defined with single quote, you can use backslash (\) as escape character before it.
Also, you need to hide the div with class "moreinfo" initially.
As for new line, if you want each attribute in new line in moreinfo class, it can be achieved by using HTML "pre" tag or "br" tag or some other way.
So code would be:
var moreinfo = "<pre id='moreinfo' style='display:none'> source = " + source + "\r\n doffset = " + doffset + "\r\n type = " + type + "\r\n length = " + length + "\r\n scale = " + scale + "\r\n noffset = " + noffset + "\r\n units = " + units +"</pre>";
document.getElementById("j1979").innerHTML += '<p onclick="document.getElementById(\'moreinfo\').style.display = \'inline-block\'">\r\n' + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
or
var moreinfo = "<div id='moreinfo' style='display:none'> source = " + source + "<br> doffset = " + doffset + "<br> type = " + type + "<br> length = " + length + "<br> scale = " + scale + "<br> noffset = " + noffset + "<br> units = " + units +"</div>";
document.getElementById("j1979").innerHTML += '<p onclick="document.getElementById(\'moreinfo\').style.display = \'inline-block\'">\r\n' + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
If you want to toggle display on click, you can use ternary operator to give condition in onclick function:
var moreinfo = "<div id='moreinfo' style='display:none'> source = " + source + "<br> doffset = " + doffset + "<br> type = " + type + "<br> length = " + length + "<br> scale = " + scale + "<br> noffset = " + noffset + "<br> units = " + units +"</div>";
document.getElementById("j1979").innerHTML += '<p onclick="document.getElementById(\'moreinfo\').style.display == \'inline-block\' ? document.getElementById(\'moreinfo\').style.display = \'none\' : document.getElementById(\'moreinfo\').style.display = \'inline-block\'">\r\n' + PID + "</p>";
document.getElementById("j1979").innerHTML += moreinfo;
I wrote a program where I needed to toggle a div with javascript. I found a solution with this code.
function toggle( selector ) {
var nodes = document.querySelectorAll( selector ),
node,
styleProperty = function(a, b) {
return window.getComputedStyle ? window.getComputedStyle(a).getPropertyValue(b) : a.currentStyle[b];
};
[].forEach.call(nodes, function( a, b ) {
node = a;
node.style.display = styleProperty(node, 'display') === 'block' ? 'none' : 'block';
});
You can then call the function with:
toggle('.idOrClass');
make sure you use single quotes around the class or id name
Hope this helps! :)

Categories

Resources