Trying to get Zeroclipboard.js to work in a Meteor app following an example here: http://www.thewebflash.com/2014/10/copy-to-clipboard-cross-browser-using.html.
I have the latest ZeroClipboard.js and ZeroClipboard.swf in the Client folder.
Within my template I have:
<template name="listPage">
<!-- some other markups -->
<input type="text" id="input1" />
<button type="button" id="btn-copy1" class="btn-copy">Copy to Clipboard</button>
<span class="span-message"></span>
</template>
Pair with event:
Template.listPage.events({
'click .btn-copy': function(e) {
e.preventDefault();
var client = new ZeroClipboard($('.btn-copy'));
client.on('ready', function(event) {
client.on('copy', function(event) {
// `this` === `client`
// `event.target` === the element that was clicked
// Get the text content of <input> or <textarea> that comes immediately before the clicked button
var $prevEle = $(event.target).prev();
var text = $prevEle.is('textarea') ? $prevEle.val().replace(/\n/g, '\r\n') : $prevEle.val();
// If value of `text` is not empty, set the data to clipboard
if (text) {
event.clipboardData.setData('text/plain', text);
}
});
client.on('aftercopy', function(event) {
// Check if copied text is not empty
if (event.data["text/plain"]) {
// Call something on successful copying
$(event.target).next().stop().css('opacity', 1).text('Copied!').fadeIn(30).fadeOut(1000);
}
});
});
client.on('error', function(event) {
ZeroClipboard.destroy();
});
}
});
I've also tried the simple example on https://github.com/zeroclipboard/zeroclipboard
Not sure what I'm doing incorrectly. Help is greatly appreciated.
probably you have put zeroclipboard.swf in wrong place.
inspect in browser "copy button". if new ZeroClipboard($('.btn-copy')) worked ok - you ll see something like this.
<object id="global-zeroclipboard-flash-bridge"
name="global-zeroclipboard-flash-bridge"
type="application/x-shockwave-flash"
data="http://localhost:3000/client/lib/ZeroClipboard.swf?noCache=1432275841705"
height="100%" width="100%">.........</object>
note path to ZeroClipboard.swf. in my case it is /client/lib/ZeroClipboard.swf - that is, i've put ZeroClipboard.min.js to /client/lib - and it tries to search swf at same path.
this means you have to put .swf into /public folder of your meteor project, and create subfolders there that match that path. i believe there is an option when creating new ZeroClipboard instance to set this path explicitly - but .swf has to reside in /public folder. while it is in /client folder - it s not available.
also, are you sure it will work with class selector (new ZeroClipboard($('.btn-copy')))? id selector (#) returns single item, class selector returns an array..
Related
I am editing a plone page to open an Excel document on a specific sheet. I created two buttons to see if either would appear as actual buttons and use the JS function I reference. With this code the exact part of the page looks like the image below.
Why is only text showing instead of the button and why is the onclick attribute not working?
Note: I have changed to links to the spreadsheet for posting it on here but the link has been tested on other webpages
<script type="text/javascript">
function Open_Excel_File(path,sheet)
{
fso = new ActiveXObject("Scripting.FileSystemObject");
if (!fso.FileExists(path))
alert("Cannot open file.\nFile '" + path + "' doesn't exist.");
else
{
var myApp = new ActiveXObject("Excel.Application");
if (myApp != null)
{
myApp.visible = true;
Book = myApp.workbooks.open(path);
var excel_sheet = Book.Worksheets(sheet).Activate;
myApp.range(f_range).Select;
}
else {
alert ("Cannot open Excel application");
}
}
}
</script>
<div>
<button onclick='Open_Excel_File("file://///fs-01\Departments\Underwriting\Statistical%20Data%20and%20Medical%20Information\Statistics\Cancers\Cancer%20Statistics%\Cancer%20Statistics%.xlsx", "Vulvar Ca");'>Open File</button>
<input type="button" onclick="Open_Excel_File('file://///fs-01\deps\uw\stat%20Data%20and%20Medical%20Information\Statistics\Cancers\Cancer%20Statistics%202018\Cancer%20Statistics%.xlsx', 'VCA');'>OPEN FILE</input>
</div>
your onclick value is not a function, it is the result of a function call. Try to change that to onclick="Open_Excel_File"; You'll have to provide the file path at some point
Accessing file system from browser is super restricted for security matters, the only way I see fit is to have a file input and using what user provides
Also Plone filter out a bounce of potential "nasty" tags through a specific configurable tool.
It seems to me that you have injected the in the source HTML of a Page (document) type.
If so, you will see in your browser that in, the page source code, the script tag has been totally stripped away.
So,
a correct way to inject some js in your page, is to load it as portal_javascript resource (plone<=4) or in resource_registry (plone>=5).
tha nasty way is to access, in the ZMI, at https://yourseite:8080/Plone/portal_transforms/safe_html/ and configure it to accept script tags inside a document (all document in your site actually).
If this answer does not satisfy you try to ask in the official community:
http://community.plone.org
hth,
alessandro
I have a dropzone in my project and I need to delete files from a folder when clicked on the remove button. I create the dropzones with this:
$('.dropzone').dropzone(
{
init: function ()
{
this.on("removedfile", function (file)
{
console.log($(file.previewTemplate));
console.log(file.previewTemplate.children[7].value);
//$.post("delete-file.php?id=" + file.serverId); // Send the file id along
});
}
});
My dropzone HTML is:
<div class="dropzone" style="width: 500px; height: 500px;" data-uploadPath="the/path/here/" data-multipleUpload="true"></div>
Now, the file parameter contains the previewTemplate of the file. I want to get the/path/here/ by the parents, but if I use:
file.previewTemplate.parentNode
It returns undefined, why doesn't parentNode work?
If you override removedFile function, then need to manually remove preview of image. Dropzone will not automatically remove file preview.
removedfile: function (file) {
file.previewElement.remove();
}
Alright, I faced a similar problem, and based on the comments on your question, I figured out the solution.
The arguments are of no use, but the context 'this' is.
this.element returns the respective dropzone element. In my case, I needed to find the enclosing form element. Hence, all I needed to do was
var $form = $(this.element).closest('form');
I am implementing a jQueryFileTree (http://www.abeautifulsite.net/jquery-file-tree/) as a file browser and would like each file or directory the user clicks on to stay highlighted. I know this can be done using simple JavaScript or CSS, but I don't understand the source code well enough to know how or where to implement the highlighting. Can anyone point me in the right direction?
Well, you can capture a click using the click handler and add a class using addClass.
$('.thing-i-will-click-on').click(function() {
$(this).addClass('selected');
});
You can also remove a class using a similar method.
$('.selected').removeClass('selected');
Combining these two things should give you the desired result.
So after a little tinkering I got it to work!
First you have to go into the jqueryFileTree.js and modify line 80 from this:
h($(this).attr('rel'));
to:
h($(this));
This will return the object that is clicked on instead of the file name. To get the file name within the function(file) within the definition of the .fileTree you'll have to use:
file.attr('rel');
Now you have the object and you can use this in the function(file) to highlight you code. (selected is a CSS class I created that changes the background color)
$(".selected").removeClass('selected');
file.addClass('selected');
$('#your_filelist_id').fileTree({
root: '/',
script: '/connectors/jqueryFileTree.php'
}, function(file) {
var flist = $('#your_filelist_id a[rel="' + file + '"]');
if(flist.hasClass('selected')) {
flist.removeClass('selected');
}
else {
flist.addClass('selected');
}
});
I am currently working on some small helper utility. The approach is an in-page web app which is typically loaded from the local file system. That all works. Inside that app I need to be able to load and process local files (storing and reloading a profile). That works so far, but I have a problem left where I would like to ask for help:
I am using the filereader.js wrapper around the html5 file reader API. Things work so far, I am able to select, read and process a file in-page. Great! I even can process several files one after another. However there is one problem where I don't know how to start debugging it: I can not read a specific file a second time. I can select it, sure, but it is not read, thus not processed. It looks like there are no events generated at all by the file reader API. This might be connected to either caching or the prior usage of the file not having been terminated by me correctly, I have no idea.
Here is the relevant code:
My FileReader JS function:
function FileReader( selector, options ) {
var options = $.extend({
clicked: function(){},
payload: function(){},
selected: function(){}
}, options||{} );
var widget = convert( selector );
var selector = widget.find( 'input:file');
function clicked( event ) {
event.stopPropagation();
// highlight button as user feedback
highlight();
// raise the file selection dialog
selector.click();
// signal action to element
options.clicked();
}
function convert( selector ) {
var widget = $( selector );
// create new content for widget
var hotspot = $( '<a class="hotspot">' + widget.html() + '</a>' ).bind( 'click', clicked );
var selector = $( '<input type="file" style="display:none;" />' );
// replace initial content of widget
widget.empty().append( $('<form />').append(selector).append(hotspot) );
widget.find( 'input:file' ).fileReaderJS( { accept: false,
readAsDefault: 'BinaryString',
on: { load: selected } } );
return widget;
}
function highlight() {
// flash button by changing the background color for 100 msecs
widget.css( 'background-color', 'whitesmoke' );
setTimeout( function(){ widget.css( 'background-color', 'transparent' ); }, 100 );
}
function selected( event, file ) {
// process payload
options.payload( event.target.result );
// signal event to controlling element
options.selected();
}
return {}
} // FileReader
This method is called with '#wProfileImport' as value of the argument selector, which actually works and converts the markup below
<span id="wProfileImport" class="control button">
<img src="assets/img/profile-import.png">
</span>
such that it contains a (hidden) file input tag which is used to fire the file selection dialog (which works fine):
<span id="wProfileImport" class="control button">
<form>
<input type="file" style="display:none">
</form>
<a class="hotspot">
<img src="assets/img/profile-import.png">
</a>
</span>
Now when clicking the image the file selector is fired, I can select a local file and its content is handed over to the options.payload callback. As said all fine and working also for more than a single file one after another. The only problem that remains: being able to read in the same file again. No event is fired, no content read, nothing.
So my question is: what do I have to do the process a file a second time, if it is selected by the user?
This has to do with how the onchange event works in JavaScript.
If you have a text input and you type a word, let's say "bird". You unfocus the field, this will cause the onchange event to trigger. If you then go back into the field and change the word, then without unfocussing change it back to "bird" and then unfocus the onchange event will not fire because the value didn't change.
Other events like onkeydown and onfocus will fire however.
See if you can find another event that you can use. Maybe onclick or onfocus. I do fear that these fire too early.
A workaround to to destroy the input once you read the file and render a new one in it's place. This way if the user selects the same file it will count as an onchange again.
Another possibility is to not use the onchange event but do the process once you press a submit button. You can get a reference to the file with:
var file = document.getElementById("#the_file_input").files[0];
I'm using http://www.steamdev.com/zclip/#usage to copy some text to the clipboard and that code is working just fine. It uses flash to create a crossbrowser solution and it is based on ZeroClipboard, which seems to be considered to be the best working solution at the moment.
However I would like to have multiple copy to clipboard buttons or links on my page. Here is an example.
http://jsfiddle.net/stofke/TB23d/
This code works, it copies the text of the coupon code to the clipboard and opens up a new page with the correct link. How can I use that code on other links without having to duplicate it for each and every link / id.
Using just the class
$(function() {
$('.copy').zclip({
path: 'http://shopsheep.com/js/ZeroClipboard.swf',
copy: $(this).text(),
afterCopy: function() {
window.open($(this).attr('href'));
}
});
});
doesn't work: as you can see here: http://jsfiddle.net/stofke/EAZYW/
if you remove the afterCopy function you'll see that $(this).text() will return the whole page instead of just the text between the link tag.
doing something like this
$(function() {
$('a.copy', this).zclip({
path: 'http://shopsheep.com/js/ZeroClipboard.swf',
copy: $('a.copy', this).text(),
});
});
slightly improves upon it but returns all text between the link tag as you can see here.
http://jsfiddle.net/stofke/hAh3j/
UPDATE: This no longer works but I cannot delete the post
This seems to work - someone might be able to make it more elegant
http://jsfiddle.net/5nLw6/7/
$(function() {
$('.copy').each(function() {
var linkId = $(this).attr("id");
$(this).zclip({
path: 'http://shopsheep.com/js/ZeroClipboard.swf',
copy: $("#"+linkId).text(),
afterCopy: function() {
window.open($('#'+linkId).attr('href'));
}
});
});
});
I actually discovered that using ZeroClipboard directly is just as easy, I just added this code in case someone wants a solution without using zclip.
ZeroClipboard.setMoviePath('http://shopsheep.com/js/ZeroClipboard.swf');
$(document).ready(function() {
$(".copy").each(function(i) {
var clip = new ZeroClipboard.Client();
var myTextToCopy = $(this).text();
var myTextUrl = $(this).attr('href');
clip.setText(myTextToCopy);
clip.addEventListener('complete', function(client, text) {
window.open(myTextUrl);
});
clip.glue($(this).attr("id"));
});
});
http://jsfiddle.net/stofke/JxMbd/
This is what we follow in Oodles Technologies.
To use zero copy to clipboard you need two files
1 . ZeroClipboard.js
2 .ZeroClipboard.swf
both file can be download from here
<html>
<head>
<script src =”../ZeroClipboard.js”></script>
<script >
// configure ZeroClipboard first
ZeroClipboard.config( { moviePath : /path/swffile/ZeroClipboard.swf } );
// initialize constructor
var client = new ZeroClipboard($(“#elementid”));
/* elementid is the element on which click , the data will copy to clipboard. you can also pass multiple elements, it use jquery selector */
</script>
<body>
<input type=”text” id =”targetid”></button>
<button id =”elementid” data-clipboard-text ='data for copy’ >copy</button>
</body>
</head>
<html>
ZeroClipboard automatically copy the value of data-clipboard-text attribute when event accur on element pass to ZeroClipboard's constructor
Light weight jQuery solution... re-use class to copy text from any element.
$(document).on('click', '.copytoclipboard', function(e) {
if($("#holdtext").length < 1)
$("body").append('<textarea id="holdtext" style="height:0;width:0;border:0;outline:0;resize:none;"></textarea>');
$("#holdtext").val($(this).text()).select();
document.execCommand("Copy");
});