I have a script that shows a dialog window with a slider bar, next to a static text.
The text shows the percentage of the slider bar (0 to 100).
The problem is that the percentage is shown in decimals, while I would need it to show them in integers, as the next part of the code takes the number from the text and I don't need decimals.
The code is :
var Dial = new Window ("dialog");
Dial.alignChildren = ["right","center"];
var Group1 = Dial.add ("group");
var Slide = Group1.add ("slider");
Slide.minvalue = 0;
Slide.maxvalue = 100;
Slide.value = 50;
Slide.preferredSize.width = 300;
Slide.onChanging = function () {
Label.text = Slide.value;
}
var Label = Group1.add ("statictext");
Label.preferredSize.width = 30;
Label.text = Slide.value;
var Button1 = Dial.add ("button");
Button1.text = "OK";
Button1.onClick = function () {
Dial.close()
}
Dial.show()
Someone has any idea how to do it?
I've tried with Math.round() on Label.text and on Slide.value, but I don't know if I can't use it correctly or if it's not the right code for this case.
I'm sure the line like this is the absolute correct way to get the round numbers in this case:
Label.text = Math.round(Slide.value);
If somewhere down-river you will need a string you can get the string via var myString = Label.text.toString(); or even var myString = '' + Label.text;. But usually JavaScript/Extendscript doesn't care either the value is a number or a string. It deals with them indiscriminately.
Related
Is there a way to get the length of visible part of an overflown text (or the size of the overflown part, to calculate the rest, for the case) with CSS or JavaScript?
And if so, could it be calculated dynamically (i.e. on window resize?)
The idea is to make a read more button which span button always sticks at the end of the last visible line, it doesn't matter the screen size.
Something like this involves a lot of factors, for instance, your "text" could be a mixture of text and other elements (<b>, <i>, <img>). Assuming it's just straight text, the following works by splitting the string at various halves, with successively smaller halves, to eventually arrive at the text that gives the same height as your source element with hidden overflow.
function getVisibleText(source)
{
let yardstick = document.createElement(source.nodeName);
let sourceRectangle = source.getBoundingClientRect();
let text = source.textContent;
yardstick.style.width = sourceRectangle.width + "px";
yardstick.style.position = "absolute";
yardstick.style.top = "-999px";
yardstick.style.left = "-999px";
yardstick.textContent = text;
source.parentNode.appendChild(yardstick);
let size = text.length;
let difference = size;
let yardstickRectangle = yardstick.getBoundingClientRect();
let result = text;
while((difference > 1 || yardstickRectangle.height > sourceRectangle.height) && size > 0)
{
difference = Math.round(difference / 2);
if(yardstickRectangle.height > sourceRectangle.height)
size -= difference;
else
size += difference;
result = text.substring(0, size);
yardstick.textContent = result;
yardstickRectangle = yardstick.getBoundingClientRect();
}
yardstick.parentNode.removeChild(yardstick);
// Trim to the last whole word
let match = (new RegExp("\\s+\\S*?$", "g")).exec(result)[0];
if(match)
result = result.substring(0, result.length - match.length);
return(result);
}
I am trying to design some code in Apps Script that can be put on any Google Slides presentation and split every text box by paragraphs so every paragraph has its own text box.
I started out using var shape = slide.insertShape(SlidesApp.ShapeType.TEXT_BOX, 50, 50, 300, 300); to make the new text boxes like google describes to use in most of its tutorials but it 'couldn't identify the TEXT_BOX type' so I found .insertTextBox and that seems to work better but I've found other problems.
I can use .getParagraphs to find the number of paragraphs in a text box but I can't tell if it doesn't include the contents of each paragraph or if I'm just not using the correct command to get the text from the paragraph. I have also tried to find an alternative to find the beginning of each paragraph and divide the text from there but I can't find a command for that either. Maybe would I have to use .indexOf to find each /n or /r, or is there a simpler way?
I'm also having a problem where my equations to divide up the text box size are giving me undefined answers and I've tried declaring the variables as numbers but it just makes things worse.
function myFunction() { // get slides in the presentation and establish 'for' variables
var slide = SlidesApp.getActivePresentation().getSlides();
var i;
var j;
var k;
for (i = 0; i < slide.length; i++) { // get the text boxes on each slide
var text = slide[i].getShapes();
for (j = 0; j < text.length; j++) { // get the location of and the paragraphs in each textbox (locations don't work)
var top = text[j].getTop;
var left = text[j].getLeft;
var width = text[j].getWidth;
var height = text[j].getHeight;
var paragraph = text[j].getText().getParagraphs();
for (k = 0; k < paragraph.length; k++){ // make a textbox for each paragraph distributed vertically over the original textbox
var content = text[j].getRange(paragraph[k]); //I was hoping this would fill with the contents of current paragraph
var shapeheight = height / paragraph.length; //NaN and I don't know why
var shapetop = height * k + top; //also doesn't work these should all be numbers
slide[i].insertTextBox(content, left, shapetop, width, shapeheight);
}
text[j].remove(); //delete original textbox on slide
}
}
}
Here are pictures of what I'm trying to do:
Slide before intended changes
Approximate slide after intended changes
I believe your goal as follows.
You want to split each paragraph in a text box as each text box on Google Slides.
You want to achieve this using Google Apps Script.
Modification points:
In your script,
getTop, getLeft, getWidth and getHeight are the method. So please add ().
About var content = text[j].getRange(paragraph[k]), getRange has no arguments.
About var shapeheight = height / paragraph.length, in this case, this can be put outof the for loop.
About var shapetop = height * k + top, in this case, that might be var shapetop = shapeheight * k + top.
When above points are reflected to your script, it becomes as follows.
Modified script:
function myFunction() {
var slide = SlidesApp.getActivePresentation().getSlides();
var i;
var j;
var k;
for (i = 0; i < slide.length; i++) {
var text = slide[i].getShapes();
for (j = 0; j < text.length; j++) {
var top = text[j].getTop(); // Modified
var left = text[j].getLeft(); // Modified
var width = text[j].getWidth(); // Modified
var height = text[j].getHeight(); // Modified
var paragraph = text[j].getText().getParagraphs();
var shapeheight = height / paragraph.length; // Modified
for (k = 0; k < paragraph.length; k++) {
var content = paragraph[k].getRange().asString(); // Modified
var shapetop = shapeheight * k + top; // Modified
slide[i].insertTextBox(content, left, shapetop, width, shapeheight);
}
text[j].remove();
}
}
}
Note:
In the current stage, it seems that AutoFit cannot be set. By this, when slide[i].insertTextBox(content, left, shapetop, width, shapeheight) is used, the text deviates a little from the box. So in this case, how about not using shapeheight? In this case, please modify slide[i].insertTextBox(content, left, shapetop, width, shapeheight); as follows.
var t = slide[i].insertTextBox(content);
t.setLeft(left);
t.setTop(shapetop);
t.setWidth(width);
References:
getTop()
getLeft()
getWidth()
getHeight()
getRange()
insertTextBox(text)
I can't get the array values (alphabet) linked to the slider. It gives a number instead of a letter.
Javascript only is the goal here btw.
I tried giving it a createSlider.value = allTheLetters among some other things but it is not working.
// Creating the Alphabet Array
var allTheLetters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
// Creating button
var button = document.createElement("button");
button.style.display = "block";
button.id = "sliderButton";
var sliderButtonId = document.getElementById("sliderButton");
button.innerHTML = "Add new letter";
// End creating Button
// Creating slider and displaying it to the DOM
var sliderParent = document.getElementById("target");
var createSlider = document.createElement("input");
createSlider.type = "range";
createSlider.min = 0;
createSlider.max = allTheLetters.length;
sliderParent.appendChild(createSlider);
sliderParent.appendChild(button);
// End slidercreation
the value of createSlider now is 50, i'd like it to start with the letter A and go max to the letter Z.
Turns out you can't get a non numeric value inside a slider, so you have to get the value of the slider position and make it link to the array you created like below:
// Creating slider and displaying it to the DOM
var sliderParent = document.getElementById("target");
var createSlider = document.createElement("input");
createSlider.type = "range";
createSlider.min = 0;
createSlider.max = allTheLetters.length-1;
sliderParent.appendChild(createSlider);
sliderParent.appendChild(button);
// get Value of slider location
var sliderResult = createSlider.value;
var theLetterIWant = allTheLetters[sliderResult];
console.log(theLetterIWant);
// End slidercreation
Im working on a simple conversation form, where I need to input dimensions ex. 12x24x36 inches to 304.8 x 609.6 x 914.4 mm.
My problem is I don't know how to compute convert those numbers separately.
I manage to remove the x but all the numbers merge.
Thanks, I hope you understand me.
here is my sample code
HTML
<h4>Dimensions</h4>
<label>inches <input id="number1"></label>
<label>mm <input id="number2"></label>
<button type="button" onclick="myFunction()">convert</button>
JS
function myFunction() {
var inches = document.getElementById("number1").value;
var removex = inches.replace(/x/g,"");
var input = parseInt(removex);
document.getElementById("number2").value = input
}
CODEPEN
https://codepen.io/anon/pen/yPpmej
If you have a string like:
var str = '304.8 x 609.6 x 914.4 mm'
You can use split() and parseFloat() to get an array of numbers with:
var str = '304.8 x 609.6 x 914.4 mm'
var numbers = str.split('x').map(parseFloat)
console.log(numbers)
You just need to know your input format so you can adjust for other variations.
parseFloat() will ignore any non-numeric characters after the numbers so it works well for stripping units.
If your receiving "12x24x36" as input(string) then for complete desired result update your function as below:-
function myFunction() {
var inches = document.getElementById("number1").value;
var inchesArr = inches.split("x");
var mmArr = inchesArr.map(function(i) {
return parseFloat(i) * 25.4;
});
var mmString = mmArr.join("x");
document.getElementById("number2").value = mmString;
}
EXPLANATION
You can convert your input example 12x24x36 into an array via str.split('x'), then do the math conversion from inch to millimeters (x inches * 25.4) and push those back into a new array of millimeters values. Then you can rejoin those values with an x via str.join('x') and put them back into your document. Here's what it looks like.
SCRIPT
function myFunction() {
var inches = document.getElementById("number1").value.split('x');
var millimeters = [];
for (var i = 0; i < inches.length; i++) millimeters.push(parseInt(inches[i]*25.4));
document.getElementById("number2").value = millimeters.join('x');
}
CODEPEN
https://codepen.io/anon/pen/KyZOYb
I'm developing a Classic ASP page that pulls some content from a database and creates a Read more link after the first 100 characters as follows;
<div class="contentdetail"><%=StripHTML(rspropertyresults.Fields.Item("ContentDetails").Value)%></div>
<script type="text/javascript">
$(function() {
var cutoff = 200;
var text = $('div.contentdetail').text();
var rest = $('div.contentdetail').text().substring(cutoff);
if (text.length > 200) {
var period = rest.indexOf('.');
var space = rest.indexOf(' ');
cutoff += Math.max(Math.min(period, space), 0);
}
var visibleText = $('div.contentdetail').text().substring(0, cutoff);
$('div.contentdetail')
.html(visibleText + ('<span>' + rest + '</span>'))
.append('<a title="Read More" style="font-weight:bold;display: block; cursor: pointer;">Read Moreā¦</a>')
.click(function() {
$(this).find('span').toggle();
$(this).find('a:last').hide();
});
$('div.contentdetail span').hide();
});
</script>
However, the script obviously just cuts the text off after 100 characters. Preferably I would like it to keep on writing text until the first period or space, for example. Is this possible to do?
Thank you.
var cutoff = 100;
var text = $('div.contentdetail').text();
var rest = text.substring(cutoff);
if (text.length > cutoff) {
var period = rest.indexOf('.');
var space = rest.indexOf(' ');
cutoff += Math.max(Math.min(period, space), 0);
}
// Assign the rest again, because we recalculated the cutoff
rest = text.substring(cutoff);
var visibleText = $('div.contentdetail').text().substring(0, cutoff);
EDIT: shortened it a bit.
EDIT: Fixed a bug
EDIT: QoL improvement
How about:
var text= $('div.contentdetail').text();
var match= text.match( /^(.{100}([^ .]{0,20}[ .])?)(.{20,})$/ );
if (match!==null) {
var visibleText = match[1];
var textToHide = match[3];
...do replacement...
}
The {0,20} will look forward for a space or period for up to 20 characters before giving up and breaking at exactly 100 characters. This stops an extremely long word from breaking out of the length limitation. The {20,} at the end stops a match being made when it would only hide a pointlessly small amount of content.
As for the replacement code, don't do this:
.html(visibleText + ('<span>' + textToHide + '</span>'))
This is inserting plain-text into an HTML context without any escaping. If visibleText or textToHide contains any < or & characters you will be mangling them, perhaps causing a XSS security problem in the process.
Instead create the set the text() of the div and the span separately, since that's the way you read the text in the first place.
Here is a fairly simple approach to getting endings at the word level, and shooting for about your given limit in characters.
var limit = 100,
text = $('div.contentdetail').text().split(/\s+/),
word,
letter_count = 0,
trunc = '',
i = 0;
while (i < text.length && letter_count < limit) {
word = text[i++];
trunc += word+' ';
letter_count = trunc.length-1;
}
trunc = $.trim(trunc)+'...';
console.log(trunc);