Is that possible to use canvas element in DOM jQuery? - html

I am new to jquery.
Is that possible to add canvas class in DOM jquery?
The canvas class include Skycons's icons that I want to use for my api.
$.ajax ({
url: "url",
type: "GET",
dataType: 'json',
success: function(e) {
let icon = e.weather[0].icon;
switch (icon) {
case "01d":
icon = "CLEAR_DAY";
break;
case "01n":
icon = "CLEAR_NIGHT";
break;
case "02d":
icon = "PARTLY_CLOUDY_DAY";
break;
case "02n":
icon = "PARTLY_CLOUDY_NIGHT";
break;
case "03d":
icon = "CLOUDY";
break;
case "03n":
icon = "CLOUDY";
break;
case "04d":
icon = "CLOUDY";
break;
case "04n":
icon = "CLOUDY";
break;
case "09d":
icon = "RAIN";
break;
case "09n":
icon = "RAIN";
break;
case "10d":
icon = "RAIN";
break;
case "10n":
icon = "RAIN";
break;
case "11d":
icon = "RAIN";
break;
case "11n":
icon = "RAIN";
break;
case "13d":
icon = "SNOW";
break;
case "13n":
icon = "SNOW";
break;
case "50d":
icon = "FOG";
break;
case "50n":
icon = "FOG";
break;
}
Then adding function
setIcons(icon, document.querySelector(".icon"));
function setIcons(icon, iconID) {
const skycons = new Skycons({ color: "white" });
const currentIcon = icon;
skycons.play();
return skycons.set(iconID, Skycons[currentIcon]);
}
let variable ='';
variable += '<div class="row h-100">';
variable += ' <canvas class="icon" width="128" height="128"></canvas>';
variable += '</div>';
$('#letWeather').html(variable);
}
});
Then add this id to Html..
<div id="letWeather"></div>
It doesn't displaying...
But if I am adding this to HTML, outside of DOM. It does works. Why?
<canvas class="icon" width="128" height="128"></canvas>

Look at the order you are doing things in.
First you search the DOM for an element with the class icon and you do stuff with whatever you find.
Next you create a string with some HTML in it that includes an element with that class.
Finally you use that HTML to add that element to the DOM.
You aren't going to find it if you search the DOM for it before you add it to the DOM.

Related

Copied Image from Google Document Paragraph inserted twice

I'm trying to combine several Google Document inside one, but images inside the originals documents are inserted twice. One is at the right location, the other one is at the end of the newly created doc.
From what I saw, these images are detected as Paragraph by the script.
As you might see in my code below, I've been inspired by similar topics found here.
One of them suggested searching for child Element inside the Paragraph Element, but debugging showed that there is none. The concerned part of the doc will always be inserted with appendParagraph method as the script is not able to properly detect the image.
This is why the other relevant topic I found cannot work here : it suggested inserting the image before the paragraph itself but it cannot detects it.
Logging with both default Logger and console.log from Stackdriver will display an object typed as Paragraph.
The execution step by step did not show displayed any loop calling the appendParagraph method twice.
/* chosenParts contains list of Google Documents name */
function concatChosenFiles(chosenParts) {
var folders = DriveApp.getFoldersByName(folderName);
var folder = folders.hasNext() ? folders.next() : false;
var parentFolders = folder.getParents();
var parentFolder = parentFolders.next();
var file = null;
var gdocFile = null;
var fileContent = null;
var offerTitle = "New offer";
var gdocOffer = DocumentApp.create(offerTitle);
var gfileOffer = DriveApp.getFileById(gdocOffer.getId()); // transform Doc into File in order to choose its path with DriveApp
var offerHeader = gdocOffer.addHeader();
var offerContent = gdocOffer.getBody();
var header = null;
var headerSubPart = null;
var partBody= null;
var style = {};
parentFolder.addFile(gfileOffer); // place current offer inside generator folder
DriveApp.getRootFolder().removeFile(gfileOffer); // remove from home folder to avoid copy
for (var i = 0; i < chosenParts.length; i++) {
// First retrieve Document to combine
file = folder.getFilesByName(chosenParts[i]);
file = file.hasNext() ? file.next() : null;
gdocFile = DocumentApp.openById(file.getId());
header = gdocFile.getHeader();
// set Header from first doc
if ((0 === i) && (null !== header)) {
for (var j = 0; j < header.getNumChildren(); j++) {
headerSubPart = header.getChild(j).copy();
offerHeader.appendParagraph(headerSubPart); // Assume header content is always a paragraph
}
}
fileContent = gdocFile.getBody();
// Analyse file content and insert each part inside the offer with the right method
for (var j = 0; j < fileContent.getNumChildren(); j++) {
// There is a limit somewhere between 50-100 unsaved changed where the script
// wont continue until a batch is commited.
if (j % 50 == 0) {
gdocOffer.saveAndClose();
gdocOffer = DocumentApp.openById(gdocOffer.getId());
offerContent = gdocOffer.getBody();
}
partBody = fileContent.getChild(j).copy();
switch (partBody.getType()) {
case DocumentApp.ElementType.HORIZONTAL_RULE:
offerContent.appendHorizontalRule();
break;
case DocumentApp.ElementType.INLINE_IMAGE:
offerContent.appendImage(partBody);
break;
case DocumentApp.ElementType.LIST_ITEM:
offerContent.appendListItem(partBody);
break;
case DocumentApp.ElementType.PAGE_BREAK:
offerContent.appendPageBreak(partBody);
break;
case DocumentApp.ElementType.PARAGRAPH:
// Search for image inside parapraph type
if (partBody.asParagraph().getNumChildren() != 0 && partBody.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE)
{
offerContent.appendImage(partBody.asParagraph().getChild(0).asInlineImage().getBlob());
} else {
offerContent.appendParagraph(partBody.asParagraph());
}
break;
case DocumentApp.ElementType.TABLE:
offerContent.appendTable(partBody);
break;
default:
style[DocumentApp.Attribute.BOLD] = true;
offerContent.appendParagraph("Element type '" + partBody.getType() + "' from '" + file.getName() + "' could not be merged.").setAttributes(style);
console.log("Element type '" + partBody.getType() + "' from '" + file.getName() + "' could not be merged.");
Logger.log("Element type '" + partBody.getType() + "' from '" + file.getName() + "' could not be merged.");
}
}
// page break at the end of each part.
offerContent.appendPageBreak();
}
}
The problem occurs no matter how much files are combined, using one is enough to reproduce.
If there's only one image in the file (no spaces nor line feed around) and if the "appendPageBreak" is not used afterward, it will not occur. When some text resides next to the image, then the image is duplicated.
One last thing : Someone suggested that it is "due to natural inheritance of formatting", but I did not find how to prevent that.
Many thanks to everyone who'll be able to take a look at this :)
Edit : I adapted the paragraph section after #ziganotschka suggestions
It is very similar to this subject except its solution does not work here.
Here is the new piece of code :
case DocumentApp.ElementType.PARAGRAPH:
// Search for image inside parapraph type
if(partBody.asParagraph().getPositionedImages().length) {
// Assume only one image per paragraph (#TODO : to improve)
tmpImage = partBody.asParagraph().getPositionedImages()[0].getBlob().copyBlob();
// remove image from paragraph in order to add only the paragraph
partBody.asParagraph().removePositionedImage(partBody.asParagraph().getPositionedImages()[0].getId());
tmpParagraph = offerContent.appendParagraph(partBody.asParagraph());
// Then add the image afterward, without text
tmpParagraph.addPositionedImage(tmpImage);
} else if (partBody.asParagraph().getNumChildren() != 0 && partBody.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
offerContent.appendImage(partBody.asParagraph().getChild(0).asInlineImage().getBlob());
} else {
offerContent.appendParagraph(partBody.asParagraph());
}
break;
Unfortunately, it stills duplicate the image. And if I comment the line inserting the image (tmpParagraph.addPositionedImage(tmpImage);) then no image is inserted at all.
Edit 2 : it is a known bug in Google App Script
https://issuetracker.google.com/issues/36763970
See comments for some workaround.
Your image is embedded as a 'Wrap text', rather than an Inline image
This is why you cannot retrieve it with getBody().getImages();
Instead, you can retrieve it with getBody().getParagraphs();[index].getPositionedImages()
I am not sure why exactly your image is copied twice, but as a workaround you can make a copy of the image and insert it as an inline image with
getBody().insertImage(childIndex, getBody().getParagraphs()[index].getPositionedImages()[index].copy());
And subsequently
getBody().getParagraphs()[index].getPositionedImages()[index].removeFromParent();
Obviously, you will need to loop through all the paragraphs and check for each one either it has embedded positioned images in order to retrieve them with the right index and proceed.
Add your PositionedImages at the end of your script after you add all your other elements. From my experience if other elements get added to the document after the the image positioning paragraph, extra images will be added.
You can accomplish this my storing a reference to the paragraph element that will be used as the image holder, and any information (height, width, etc) along with the blob from the image. And then at the end of your script just iterate over the stored references and add the images.
var imageParagraphs = [];
...
case DocumentApp.ElementType.PARAGRAPH:
var positionedImages = element.getPositionedImages();
if (positionedImages.length > 0){
var imageData = [];
for each(var image in positionedImages){
imageData.push({
height: image.getHeight(),
width: image.getWidth(),
leftOffset: image.getLeftOffset(),
topOffset: image.getTopOffset(),
layout: image.getLayout(),
blob: image.getBlob()
});
element.removePositionedImage(image.getId());
}
var p = merged_doc_body.appendParagraph(element.asParagraph());
imageParagraphs.push({element: p, imageData: imageData});
}
else
merged_doc_body.appendParagraph(element);
break;
...
for each(var p in imageParagraphs){
var imageData = p.imageData
var imageParagraph = p.element
for each(var image in imageData){
imageParagraph.addPositionedImage(image.blob)
.setHeight(image.height)
.setWidth(image.width)
.setLeftOffset(image.leftOffset)
.setTopOffset(image.topOffset)
.setLayout(image.layout);
}
}

Line 49, 52,55,58,61,64- 1119:Access of possibly undefined property text through a reference with static type String

Not sure what I am doing wrong, I removed any text from the text box fields so why am I still getting this error ?
Code below :
switch (day) {
case "Sun":
day.text = "Monday";
break;
case "Mom":
day.text = "Tuesday";
break;
case "Tue":
day.text = "Wednesday";
break;
case "Wed":
day.text = "Thursday";
break;
case "Thu":
day.text = "Friday";
break;
case "Fri":
day.text = "Saturday";
break;
case "Sat":
day.text = "Sunday";
break;
}
switch (codeToday) {
case "0":
case "3200":
var weather00:weather00 = new weather00();
_weatherToday.addChild(weather00);
_weatherToday.scaleX = 10.85;
_weatherToday.scaleY = 158.75;
break;
case "1":
case "3200":
var weather01:weather01 = new weather01();
_weatherToday.addChild(weather01);
_weatherToday.scaleX = 10.85;
_weatherToday.scaleY = 158.75;
break;
}
i suppose that 'day' is a String variable and have not a text property - look here -> String
Some components have a text property like: TextField and TextArea

html append to textarea

I have been working on this piece of code to get geolocation on a timer of 10 seconds, result will be displayed in text area. The problem is how do I append new result in without replacing the old ones, and perhaps auto expand textarea if necessary.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML that display geolocation</title>
</head>
<body>
<textarea rows="50" cols="100" id="demo"></textarea>
<script>
var x = document.getElementById("demo");
var timer = setInterval(function () { getLocation() }, 10000);
function getLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(success, error)
}
else
{
x.innerHTML = "Geoloaction is not supported."
}
}
function success(pos)
{
var y = pos.coords;
var z = new Date().toLocaleTimeString();
x.innerHTML = z + " Latitude: " + y.latitude + " Longitude" + y.longitude;
}
function error(err)
{
switch (error.code)
{
case error.PERMISSION_DENIED:
x.innerHTML = "User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML = "Location information is unavailable."
break;
case error.TIMEOUT:
x.innerHTML = "The request to get user location timed out."
break;
case error.UNKNOWN_ERROR:
x.innerHTML = "An unknown error occurred."
break;
}
}
</script>
</body>
</html>
jsfiddle DEMO
You use value for a textarea not innerHTML. Then you can use += to append text to it.
var mTextArea = document.getElementById("demo");
mTextArea.value = "Some text.";
mTextArea.value += " Some other text.";
Now if you get the value of the textarea it will be
console.log(mTextArea.value);
Some text. Some other text.
EDIT:
To make textarea to expand automatically you need to set its height to its scrollHeight.
function resizeTextArea(elm) {
elm.style.height = elm.scrollHeight + 'px';
}
So if the text is being added to the textarea programmatically then just call the function afterwards like resizeTextArea(mTextArea);
If you want it to resize as you type then:
var mTextArea = document.getElementById('demo');
mTextArea.addEventListener('keyup', function() {
this.style.height = this.scrollHeight + 'px';
});
EDIT 2:
To start a new line you use "\n".
"This is the first line.\nThis is the second line."
Use += instead of = to append content to the textarea where you set x.innerHTML:
function success(pos){
var y = pos.coords;
var z = new Date().toLocaleTimeString();
x.innerHTML += z + " Latitude: " + y.latitude + " Longitude" + y.longitude;
}
I can see that you are not using jQuery in there so .append is not an option for you.
For your solution, you can just follow these steps:
Get the content of the textarea and put it in a variable.
Concatenate what you are trying to append to that variable (txt_area_content+new_to_append)
Clear the contents of that textarea and then put what you have concatenated.

html5 canvas doodle change colour

I'm trying really hard to understand javascript and I was inspired by this code by Jay Weekes: view-source:http://jayweeks.com/sketchy-structures-html5-canvas/#/ <|:{
I am trying to find out how to let the user choose the strokeStyle colour.
I don't quite know how to go about this. I tried it and the opacity stopped working and the colour just went black...
I used a button with an id and a function. Not working. I decided to come for help.
I don't know if I'm expressing myself very well. Please let me know if I'm not.
Many thanks in advance! :)
I have a rough start for one possible solution to this question. The result is here at this jsFiddle.
My idea was to first add a simple UI element for selecting color. The simplest thing I could think of was a list of links.
<div id="sketch-color">
<ul class="colorList">
<li>Black</li>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul>
</div>
You'll notice I started looking at using HTML5 data, but didn't follow through as I should have. I edited the CSS file to make the links a bit more obvious:
#sketch-color li:first-of-type a { color:black; }
...
Then, to follow the logic of the original, I added a line to the basic UI readout:
<li>pen color: <span id="current-color"></span></li>
From that point on, it was just javascript. I added another variable into the list of "current" elements and set its default to "Black":
var currOpacity = document.getElementById( 'current-opacity' ),
currDensity = document.getElementById( 'current-density' ),
currCache = document.getElementById( 'current-cache' ),
currColor = document.getElementById( 'current-color' );
currCache.innerHTML = '0';
currColor.innerHTML = "Black";
I then needed to grab all the new links, turn off their default click event handler, and add my own. I'm used to jQuery, so I probably didn't do this in the most efficient way.
// Color Events
var colorListItems = document.getElementById( 'sketch-color' ).getElementsByTagName('ul')[0].children;
var colorLinks = [];
for(var i = 0; i < colorListItems.length; i++)
{
colorLinks.push(colorListItems[i].children[0]);
}
for(var i = 0; i < colorLinks.length; i++)
{
colorLinks[i].removeEventListener("click");
colorLinks[i].addEventListener("click", onClickColorChange, false);
}
Then I defined the event handler:
//event handlers
function onClickColorChange( e ) {
e.preventDefault();
currColor.innerHTML = e.target.innerHTML;
return false;
}
Ok, so, that's great. I can change the text in a span. Not very interesting. I need to hack into Jay's drawing code to make this do something. I noticed that the decision to set a color doesn't happen until the Point.connect() function is called, so I changed the pivotal line in that function to call a new function to set the line style:
if( totDist < maxDist*5 && drawDist < maxDist ){
ctx.strokeStyle = currentStrokeStyle();
ctx.line( this.x, this.y, p.x, p.y );
} else { break; }
And then defined this new function:
function currentStrokeStyle() {
var curr_color = currColor.innerHTML;
var red = 0, green = 0, blue = 0;
switch(curr_color) {
case "Red": red = 255; break;
case "Green": green = 255; break;
case "Blue": blue = 255; break;
};
return 'rgba( ' + red + ',' + green + ',' + blue + ','+ uiOpacity.opacity +' )';
}
And then the magic happened.
I realize there's a lot of room for improvement here. There should be an rgb slider or something to that effect, and I should use the HTML5 data attribute instead of keying off innerHTML. That said, I'm submitting the first version I got to work. I invite you to fork the jsfiddle and make it better.
Update
I apologize for not making it clear how to add new colors with this arrangement. Basically, we need to add new links to the list of colors in the UI, then add new cases to the switch statement in the currentStrokeStyle() function. So, to add an orange option:
<div id="sketch-color">
<ul class="colorList">
<li>Black</li>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
<li>Orange</li>
</ul>
</div>
And:
function currentStrokeStyle() {
var curr_color = currColor.innerHTML;
var red = 0, green = 0, blue = 0;
switch(curr_color) {
case "Red": red = 255; break;
case "Green": green = 255; break;
case "Blue": blue = 255; break;
case "Orange": red = 255; green = 128; break;
};
return 'rgba( ' + red + ',' + green + ',' + blue + ','+ uiOpacity.opacity +' )';
}
If you want the link to appear orange, too, you would need to change the CSS again:
#sketch-color li:nth-child(4) a { color:blue; }
#sketch-color li:nth-child(5) a { color:orange; }
And that should work for now. Again, this would be easier to change if I'd used the HTML5 data attribute to pass rgb values directly to the currentStrokeStyle(), but I was lazy and it was getting late.
And the new color has been added to the jsFiddle.

TabGroup within a NavGroup - Both navbars show and NavGroup title missing

I have an app that contains a messaging system. It consists of a TableView that splits off into two TabGroups, using a NavGroup (I'm using Ti 1.7.5).
The problem I'm seeing is two fold;
Both title bars of the NavGroup and the Tab are being displayed, and
The TabGroup's title is not being displayed in the NavGroup title bar.
The following screenshot illustrates both problems:
Code (please note this is heavily summarised):
csu.module.messages.createMainWindow = function() {
csu.module.messages.mainWindow = Ti.UI.createWindow($$.moduleMainWindow);
csu.module.messages.navGroupContainer = Ti.UI.createWindow($$.modalContainer);
var mainTableView = Ti.UI.createTableView($$.tableView);
csu.module.messages.navGroup = Ti.UI.iPhone.createNavigationGroup({
window: csu.module.messages.mainWindow
});
...
mainTableView.addEventListener('click', function(e){
// Event info
var index = e.index, section = e.section, row = e.row, rowData = e.rowData;
switch(index) {
case 0:
// inbox;
csu.module.messages.inboxView = csu.module.messages.createInboxView(); // returns the tabgroup
csu.module.messages.navGroup.open(csu.module.messages.inboxView);
break;
case 1:
// archive;
csu.module.messages.archiveView = csu.module.messages.createArchiveView(); // Returns another tabgroup
csu.module.messages.navGroup.open(csu.module.messages.archiveView);
break;
}
});
...
csu.module.messages.mainWindow.add(mainTableView);
csu.module.messages.navGroupContainer.add(csu.module.messages.navGroup);
}
csu.module.messages.createInboxView = function() {
var tabGroup = Ti.UI.createTabGroup({
title: 'Inbox',
navBarHidden: false,
backgroundColor: '#000000',
barColor: csu.ui.theme.headerColor // black
});
var criticalInbox = csu.module.messages.createListWindow(m_Config.MESSAGE_TYPE_CRITICAL, true);
csu.module.messages.criticalInboxTab = Ti.UI.createTab({
title: 'Critical',
icon: 'images/tab-critical.png',
window: criticalInbox
});
...
// two other tabs are created
tabGroup.addTab(csu.module.messages.criticalInboxTab);
tabGroup.addTab(csu.module.messages.importantInboxTab);
tabGroup.addTab(csu.module.messages.generalInboxTab);
return tabGroup;
};
csu.module.messages.createListWindow = function(listType, isInbox) {
var tabWindow, title, tableView;
switch(listType) {
case m_Config.MESSAGE_TYPE_CRITICAL:
title = 'Critical';
break;
case m_Config.MESSAGE_TYPE_IMPORTANT:
title = 'Important';
break;
case m_Config.MESSAGE_TYPE_GENERAL:
title = 'General';
break;
};
tableView = Ti.UI.createTableView();
var tableData = new Array();
tableView.setData(tableData);
tabWindow = Ti.UI.createWindow({
title: title,
navBarHidden: false
});
tabWindow.add(tableView);
return tabWindow;
}
Does anyone know of a work around or something to get the title in the Navigation bar from the TabGroup? Is this a bug?
Your assistance is appreciated.
Titanium discourage the use of tab groups within navigation groups as they are both window managers, displaying a titlebar at the top.
See: http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.Window
While it doesn't look the same, a tabbed bar should be used instead.