asp/ javascript Pasting an image to a textbox - javascript

So I was able to find this greate jscript: http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/
The java is pretty simple (all credit to the author)
// We start by checking if the browser supports the
// Clipboard object. If not, we need to create a
// contenteditable element that catches all pasted data
if (!window.Clipboard) {
var pasteCatcher = document.createElement("div");
// Firefox allows images to be pasted into contenteditable elements
pasteCatcher.setAttribute("contenteditable", "");
// We can hide the element and append it to the body,
pasteCatcher.style.opacity = 0;
document.body.appendChild(pasteCatcher);
// as long as we make sure it is always in focus
pasteCatcher.focus();
document.addEventListener("click", function() { pasteCatcher.focus(); });
}
// Add the paste event listener
window.addEventListener("paste", pasteHandler);
/* Handle paste events */
function pasteHandler(e) {
// We need to check if event.clipboardData is supported (Chrome)
if (e.clipboardData) {
// Get the items from the clipboard
var items = e.clipboardData.items;
if (items) {
// Loop through all items, looking for any kind of image
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
// We need to represent the image as a file,
var blob = items[i].getAsFile();
// and use a URL or webkitURL (whichever is available to the browser)
// to create a temporary URL to the object
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
// The URL can then be used as the source of an image
createImage(source);
}
}
}
// If we can't handle clipboard data directly (Firefox),
// we need to read what was pasted from the contenteditable element
} else {
// This is a cheap trick to make sure we read the data
// AFTER it has been inserted.
setTimeout(checkInput, 1);
}
}
/* Parse the input in the paste catcher element */
function checkInput() {
// Store the pasted content in a variable
var child = pasteCatcher.childNodes[0];
// Clear the inner html to make sure we're always
// getting the latest inserted content
pasteCatcher.innerHTML = "";
if (child) {
// If the user pastes an image, the src attribute
// will represent the image as a base64 encoded string.
if (child.tagName === "IMG") {
createImage(child.src);
}
}
}
/* Creates a new image from a given source */
function createImage(source) {
var pastedImage = new Image();
pastedImage.onload = function() {
// You now have the image!
}
pastedImage.src = source;
}
I get data:image/png;base64,iVBORw0KG
My question for everybody is how to I paste that back into an textbox multiline or into a text area? Or into anything a user can see?
Thanks!

That example already works, it should show an image but the opacity is set to 0, just change that to 1 and it will show an image.
You can always predefine an image in a location that you want and just set the source of that.
Your user should be able to see that.

Related

How to loop through object and if span innerText matches the key, then setAttribute value of that key?

I'm trying to create a chrome extension, that will loop through a certain span innerText and if that value matches it will change that text to hyperlinked text with a URL connected to that specific word.
On the web page there are these tags (chat,flamingo,sample ticket, test, etc.) there is a <span> element within a span element with a class "badge-tag"
What I plan is to have an object with numerous entries, key will represent the text of tag(<span>) and the value will be the URL I want to convert this to.
The html will look something like this so I have to grab the value of document.getElementsByClassName("badge-tag").innerText.
Sample html
<span class="badge-tag"><span>facebook</span></span>
<span class="badge-tag"><span>youtube</span></span>
<span class="badge-tag"><span>twitter</span></span>
<span class="badge-tag"><span>bing</span></span>
I created this JS:
if(typeof listitems === 'undefined'){
const init = function(){
const listitems = document.getElementsByClassName("badge-tag");
const tagMap = {
"facebook":"https://google.com",
"youtube":"https://youtube.com",
"test/obj":"https://docs.gorgias.com",
"instagram/dm":"https://instagram.com"
};
// console.log(tagMap['facebook'])
if(text in tagMap){
console.log("ok")
}
Object.values(listitems).forEach(item => {
const text = item.firstChild;
const link = document.createElement('a');
link.setAttribute("href", tagMap); //test link.setAttribute("href", "https://google.com");
link.setAttribute("target", "_blank");
item.appendChild(link);
link.appendChild(text);
// document.querySelectorAll('.badge-tag a')
// .forEach(function(elem){
// elem.setAttribute('target','_blank');
// })
}
)
}
init();
}
What this code does is converts all the <span> with class "badge-tag" to hyperlinked, I need a way to connect the object tagMap with it so that only the if text is equal to object key, it will add it's respective value.
I understand that I'm missing a good chunk here, as I need For Loop, and probably something else to validate but I'm kinda stuck, any help would be appreciated even if it's just a link to an article.
This is the JsFiddle I was messing with https://jsfiddle.net/94yd2h3g/31/
Thanks!
I made only a few minor modifications to your code:
/* if(text in tagMap){
console.log("ok")
console.log(tagMap[text])
} */
if(typeof listitems === 'undefined'){
const init = function(){
const listitems = document.getElementsByClassName("badge-tag");
const tagMap = {
"facebook":"https://google.com",
"youtube":"https://youtube.com",
"test/obj":"https://docs.gorgias.com",
"instagram/dm":"https://instagram.com"
};
// console.log(tagMap['facebook'])
text = "facebook"
if(text in tagMap){
console.log("ok")
}
Object.values(listitems).forEach(item => {
const text = item.textContent;
if(text in tagMap) {
const link = document.createElement('a');
link.setAttribute("href", tagMap[text]);
link.setAttribute("target", "_blank");
while(item.firstChild)
link.appendChild(item.firstChild);
item.appendChild(link);
}
// document.querySelectorAll('.badge-tag a')
// .forEach(function(elem){
// elem.setAttribute('target','_blank');
// })
}
)
}
init();
}
The text you're looking for is best achieved with Node.textContent. I also added a loop to run through all children and add those, which should make the implementation a bit more flexible. Briefly, you can have a situation where an element's text can be made up of more than one text node and looping through .firstChild accounts for that.
Of course, there are multiple ways to skin a cat. You could create a new normalised text node and destroy the old one, use innerHTML, etc., but this is what seemed simplest to me and required the fewest changes.

I am having trouble capturing the vale of a text area, and saving it into local storage

Hi I just wondering if i can get some pointers with my code, I am trying to capture and save the input value of a textarea. I am fairly new to JavaScript and I have been wrecking my brain trying to figure it out. My issue is regarding the saveEntry() function, which isn't complete I have only posted how my code is right now, and isn't causing errors/unwanted effects. Any tips or hints would be fantastic, as I keep getting errors
function addTextEntry(key, text, isNewEntry) {
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById('textarea').value;
// ...make a text item using the value
// ...store the item in local storage using the given key
localstroage.setItem(key, item);
}
// Connect the saveEntry event listener to the textarea element 'change' event
textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
I was told to utilise something similar to this code below, but not exactly the same as I need to capture the data value of the user input text, not pre-created data.
function createDemoItems() {
console.log("Adding demonstration items to local storage");
var item, data, key;
// Make a demo text item
data =
"Friday: We arrived to this wonderful guesthouse after a pleasant journey " +
"and were made most welcome by the proprietor, Mike. Looking forward to " +
"exploring the area tomorrow.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000001";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Saturday: After a super breakfast, we took advantage of one of the many " +
"signed walks nearby. For some of the journey this followed the path of a " +
"stream to a charming village.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000002";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo image item
data = window.DUMMY_DATA_URL;
item = makeItem("image", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000003";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Sunday: Following a tip from Mike we drove to a gastropub at the head of " +
"the valley - a great meal and fabulous views all round.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000004";
// Store the item in local storage
localStorage.setItem(key, item);
}
You are very close, you just have to make some adjustments here and there!
Just as a disclaimer, I had to re-create your addSection() function, in order to have it properly working. If you already had one, you could discard mine
When we create a new entry, in order to make it distinguishable, I have assigned it the id of the key. Before, you were trying to call getElemenyById("textarea"), but no element had id textarea, which is in fact the tag name of the textarea element that you created. Read more about getElementByTagName if you want.
I have changed the way the event listener is set to:
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
The difference between change and input are that change will fire only when you are done with the changes and click outside of the textarea, whilst input will fire everytime that you input something. Now you know, so of course, feel free to change it to what you would like it to behave.
Lastly, I have made the just-created item to be retrieved immediately and logged to console. This will be useful just for testing, you can comment out those lines when you are happy.
Beware that the snippet below is playable, but it won't actually save data to LocalStorage because of SO limitations, so you won't be able to fully test it on this page.
function addSection(key, element) {
element.id = key;
var test = document.querySelector("#test");
test.appendChild(element);
}
function addTextEntry(key, text, isNewEntry) {
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById(key).value;
// ...store the item in local storage using the given key
localStorage.setItem(key, currentValue);
//Testing if we can retrieve the item, comment out when you're happy
var item = localStorage.getItem(key);
console.log(item);
}
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
// Connect the saveEntry event listener to the textarea element 'change' event
//textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
}
window.onload = () => addEntryClick();
<html>
<head>
</head>
<body>
<div id="test"></div>
</body>
</html>
There are a number of things wrong with the way you're doing things, but you know that: that's why you're here!
You have a typo: localstroage should be localStorage
You create a text area but don't give it an ID. In your saveData function you attempt to find it, but you're searching for it by tag name. There's no need to search: your event handler will already have this set to the element.
In your event handler you refer to your function as saveData(). This will invoke the function immediately and assign its return value as an event handler. Just pass the function name.
Here's a demonstration of concept for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Explore local storage</title>
</head>
<body>
<textarea id="txt" placeholder="Enter text and press TAB"></textarea>
<script>
"use strict";
let txtKey = "someKey"
// Save the data. No need to search for the text area:
// the special value 'this' is already set to it.
function saveEntry() {
localStorage.setItem(txtKey, this.value);
}
// Look fr the previous text and if it exists, put it in the textarea
let storedText = localStorage.getItem(txtKey);
if (storedText) {
document.getElementById('txt').value = storedText;
}
// Now add the event listener.
tArea.addEventListener('change', saveEntry); // Pass just the function name
</script>
</body>
</html>
This code uses a hard-coded value for txtKey. Your code might need to generate and track some value for the key, otherwise you risk overwriting earlier data with later data.

Cannot retrieve the HTML Dom object

I am using IE11 for this since that is my companys standard browser.
I am working on a solution to catch the paste event when pasting a screen dump into the web application. So far so good but after I have pasted the image I would like to change the size. Preferable before actually so I don't get a jumping application.
I have create a jsfiddle where you can see the entire test application: http://jsfiddle.net/e5f5gLan/3/
Do like this when running the jsfiddle:
Make a screen shot
Put the marker in the red square
Press Ctrl + v
Now the intention is that the pasted image should become 100px x 100px in size. It doesn't.
The problem is that I am not getting hold of the DOM object so I can set the style/size of the image.
The significant part is at the end of the javascript (I guess...):
var image_container = document.getElementById('pastearea');
var image = image_container.getElementsByTagName("img");
image[0].setAttribute("style", "width: 100px; height: 100px");
First of all, I imagined that the img element would become part of an array and that I should access the only img-element using image[0]. But then I get the error "Not possible to get setAttribute for a reference that is undefined or null. " (freely translated from Swedish...)
Ok, perhaps it understands it is only one element and just returns an object that isn't an array. So I changed the last row above to:
image.setAttribute("style", "width: 100px; height: 100px");
Then I get that setAttribute is not supported by the object.
If I create an HTML page with similar structure (img inside div) and just tries to change the size, then it works. Check out this one (click the button to shrink the image): http://jsfiddle.net/m4kzd7jp/3/
How can I change change the size of the image before or after I have pasted it?
Yeah I added the style and it worked to keep it 100px height/width.
#pastearea img { width: 100px; height: 100px; }
I tested your code and the filelist was always 0. If you want to handle this through code, here's what I was using in our project. basically you should be looping items not files and checking if it is a file.
function (e) {
var clip = e.clipboardData || window.clipboardData;
if (clip) {
var preInsert = getData(); // this pulled the input box text or div html
for (var i = 0; i < clip.items.length; i++) {
var item = clip.items[i];
if (item.kind == "file" &&
item.type.indexOf('image/') !== -1) {
var fr = new FileReader();
fr.onloadend = function () {
if (preInsert == getData()) // if nothing changed, we'll handle it otherwise it was already handled
setData(fr.result);
};
var data = item.getAsFile();
fr.readAsDataURL(data);
}
}
}
}
This area shows what I was doing in angular to get/set
var getSelection = function() {
if (window.getSelection && window.getSelection().rangeCount > 0) //FF,Chrome,Opera,Safari,IE9+
{
return window.getSelection().getRangeAt(0).cloneRange();
}
else if (document.selection)//IE 8 and lower
{
return document.selection.createRange();
}
return null;
}
var isInputTextarea = false; // I was being more generic in my angular directive
var getData = function () {
if (isInputTextarea)
return $element.val();
return $element.html();
};
var setData = function (src) {
if (isInputTextarea) {
$element.val(function (index, value) {
return value + " " + "<img src='" + src + "'>";
});
}
else {
var selection = getSelection(); // I presume we have focus at this point, since it is a paste event
if (selection) {
var img = document.createElement("img");
img.src = src;
selection.insertNode(img);
}
}
};

JavaScript, using a function to change the text displayed in a HTML <p> tag

I have a HTML5 canvas, which is displaying a number of images and a paragraph of text on the page underneath the canvas. I want the text in the paragraph to be updated to display a different element from a JS array depending on which image the user clicks on.
Currently, I have a 'mousedown' function that looks like this:
_mousedown: function(evt) {
this._setUserPosition(evt);
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
isClickOnImage(evt);
var id = shape.id;
selectTip(id);
}
//init stage drag and drop
if(Kinetic.DD && this.attrs.draggable) {
this._initDrag();
}
}
I tried using the line var id = shape.id to update the ID that's being passed to the function, so that it will get the correct element from my 'tips' array, but for some reason, when I view the page in the browser, and click on an image, the text beneath the canvas is not updated. It seems that this function is not updating the 'id' variable to the ID of whichever image has been clicked.
After looking into this, it seems to me that I will want to use a loop inside the 'mousedown' function, that will take the 'id' of the image on which the click has been detected, and loop through my 'sources' array (which is where all of the images have been loaded from the HTML into the JS), checking at each position whether the image stored at that location has the same ID as that of the image that has been clicked on. If it does, the loop should set the text to the text stored at that position of the array, and if not, it should continue looking through the array until it find it. Would this make sense? I tried adding the following code to the 'mousedown' function, but it doesn't change the text as I expected:
var imageCheckArray = 0;
while(imageCheckArray < sources.length){
if(shape.id == sources[imageCheckArray]){
selectTip(imageCheckArray);
} else {
imageCheckArray++;
}
}
Is there something I'm missing from the loop?
The code for the whole function currently looks like this:
_mousedown: function(evt) {
this._setUserPosition(evt);
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
isClickOnImage(evt);
/*This line needs to get the element of the sources array that has been selected,
and then select the element at the same position from the tips array.*/
//var id = null;
var imageCheckArray = 0;
while(imageCheckArray < sources.length){
if(shape.id == sources[imageCheckArray]){
selectTip(imageCheckArray);
} else {
imageCheckArray++;
}
}
//var id =
//selectTip(id);
}
//init stage drag and drop
if(Kinetic.DD && this.attrs.draggable) {
this._initDrag();
}
}
Edit 11/01/2013 # 16:10
The code for selectTip is:
function selectTip(id){
$("#tipsParagraph").text(tips[id]);
}
and I've put a jsFiddle up here: http://jsfiddle.net/cd8G7/ although the 'result' panel is not showing what I actually see when I view the page in my browser- I get the canvas with all of the images displayed, and the paragraph underneath the canvas shows the text from the first element of my 'tips' array.
Edit 23/01/2013 # 13:50
Here's my isClickOnImage function:
function isClickOnImage(event){
var clickX = event.clientX;
var clickY = event.clientY;
//var imageCheckIteration = 0;
while(imageCheckIteration < sources.length){
if((clickX > sources[imageCheckIteration].x && clickX < sources[imageCheckIteration].x + imageWidth) &&
(clickY > sources[imageCheckIteration].y && clickY < sources[imageCheckIteration].y + imageHeight)){
/*This is where I need to print the variable that holds the text I want to display, but I need to display its contents
outside the canvas, in the <p></p> tags below. */
console.log("Click on image detected");
document.getElementById("tipsParagraph").innerHTML = sources[imageCheckIteration].data-tip /*tips[imageCheckIteration]*/;
} else {
document.getElementById("tipsParagraph").innerHTML = "";
}
}
}
What I intended that this function do is, capture the X & Y coordinates of any click on the canvas, and store them in the variables "clickX" and "clickY". Then, I have a variable called "imageCheckIteration" that has been initialised to 0, and while this variable is less than the length of my "sources" array (which is the array where all of the images have been stored), the function should check whether the click was on an area of the canvas that is covered by one of the images in the array.
If it was, then a console log should display the message "click on image detected", and the line
document.getElementById("tipsParagraph").innerHTML = sources[imageCheckIteration].data-tip;
should set the value of the "tipsParagraph" to be the value of the 'data-tip' attribute of whichever image is at the 'imageCheckIteration' position of the 'sources' array. If the click was detected on an area of the canvas that does not have an image displayed, then the value of the "tipsParagraph" should be set to hold nothing.
However, for some reason, when I view the page in the browser, the 'tipsParagraph' displays the text "This is where the text will be displayed", which is its default value, so that's fine. But, when I click on an image, or click anywhere else on the canvas, the text displayed in the 'tipsParagraph' is not updated.
I can't figure out why this is- can someone point me in the right direction? Does it mean that my isClickOnImage(event) function is never being called?
I simplified the way you are getting a reference to an image through the canvas. The trick here is to swap the z-index of the canvas and the image container and grab the reference to the image on the mouse up event. I don't know of a clean way to get elements behind a canvas, hence the workaround.
$('canvas').bind('mousedown', function(e) {
$('section').css('z-index', 4);
});
$('img').bind('mouseup', function(e) {
$('#tipsParagraph').text($(this).attr('id') + ":" + $(this).attr('alt'));
$('section').css('z-index', 2);
});
The second portion here is grabbing some attributes from the image itself and updating the text inside your div.
You can see more of the solution here.

How to get the element background image in html using javascript

I want to get all the html page elements' background images that are set using css or the element background property.
how can I do this using javascript?
The getStyle() function below was taken from http://www.quirksmode.org/dom/getstyles.html#link7 (and slightly modified).
Of course you need to make sure the DOM is ready. An easy way to do that is to place the script toward the bottom of the page, just inside the closing </body> tag.
<script type="text/javascript">
function getStyle(x, styleProp) {
if (x.currentStyle) var y = x.currentStyle[styleProp];
else if (window.getComputedStyle) var y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
return y;
}
// Get all elements on the page
var elements = document.getElementsByTagName('*');
// store the results
var results = [],
i = 0,
bgIm;
// iterate over the elements
for (;elements[i];i++) {
// get the background-image style property
bgIm = getStyle(elements[i], 'background-image');
// if one was found, push it into the array
if (bgIm && bgIm !== 'none') {
results.push(bgIm);
}
}
// view the console to see the result
console.log(results);
</script>
It sounded like you want the path to the images themselves.
If you wanted the actual elements, change:
results.push(bgIm);
to:
results.push(elements[i]);
You could us jquery:
imgs = [];
$("*").each(function(i) {
if($(this).css("background-image") != "none") {
imgs.push($(this).css("background-image"));
}
});

Categories