I'm using clipboard js to copy-paste content and there is a tooltip attached to the button by Tippy js.
But how do I change the tooltip content and make it appear for two seconds as long as the clipboard success event is fired? I cannot think of a way to change the content because I'm not using the prop but the attribute method.
Possible related doc:
https://atomiks.github.io/tippyjs/v6/constructor/
https://atomiks.github.io/tippyjs/v6/tippy-instance/
https://atomiks.github.io/tippyjs/v6/methods/
var clipboard = new ClipboardJS('.btn');
tippy('.btn', {
placement: 'bottom',
theme: 'clean'
});
clipboard.on('success', function(e) {
//Change the tooltip content and show for two seconds
});
<button class="btn" data-clipboard-text="Testing...123" data-tippy-content="Tooltip">
Copy to clipboard
</button>
<script src="https://unpkg.com/#popperjs/core#2"></script>
<script src="https://unpkg.com/tippy.js#6"></script>
<script src="https://unpkg.com/clipboard#2/dist/clipboard.min.js"></script>
You just need to get instance of your tippy object and call some methods on it in your event listener.
var clipboard = new ClipboardJS('.btn');
const btnTippy = tippy('.btn', {
placement: 'bottom',
theme: 'clean',
})[0]; // 0-index used because tippy will return array of buttons here. You can use `querySelector` that will return only one instance if don't need array.
const copiedTippy = tippy('.btn', {
placement: 'bottom',
theme: 'clean',
trigger: '',
})[0];
copiedTippy.setContent('Just copied')
clipboard.on('success', function (e) {
copiedTippy.show()
setTimeout(copiedTippy.hide, 2000) // to hide tip after 2 seconds
});
Related
I have a toolbar with this custom html:
var volSlider = $(
'<div class="sliderContainer"><span id="currentVolume" class="sliderLabel">0</span><input id="volSliderRange" type="range" min="0" max="100" value="1" class="rangeStyle1 > <span class="sliderLabel">100</span></div>'
);
My toolbar item contains:
{
type: "html",
id: "vol-slider",
html: volSlider.html(),
hidden: false,
},
If I don't hide "vol-slider", I have this code which works fine:
volumeslider = document.getElementById("volSliderRange");
volumeslider.addEventListener("change",setVolumeHandler,false);
but as soon as I call this:
w2ui["toolbar"].hide("vol-slider"));
then once I show it again, the range no longer has it's previous value, and my event listener doesn't work. I've tried doing the above addEventListener again to no avail. I tried adding this to the element:
onchange="foo()"
and I never get a callback.
(Note, my toolbar code is done as straight JavaScript, not a JavaScript module - don't know if that makes a difference, but I can't use it as a module).
Note: I tried putting a 'refresh' handler:
this.tb.on("refresh", (event) => {
if (event.target === "vol-slider") {
this.updateVolumeSliderPosition(this.volume);
}
});
the this.updateVolumeSliderPosition does
var vs = document.getElementById("volSliderRange");
vs.value = val;
but the range position does not change.
Any suggestions would be appreciated.
I have a page containing multiple instances of ace.js editors, all on read-only, displaying code.
I wish to open the editor like so and highlight its content to allow my user to easily copy it, like so:
My current approach does not show the wanted result, it does open an editor with the code inside of it BUT its height is not at the size of its content:
Heres's how I do it:
function openCodeEditor(event, domElement, language) {
event.preventDefault();
getInstance().then((ace) => {
ace.edit(domElement, {
mode: `ace/mode/${language}`,
theme: 'ace/theme/monokai',
startLineNumber: 1,
trim: true,
});
});
}
// STARTS HERE
// Called on page load to highlight each block of code
function syntaxHighlight(domElement, language, showGutter) {
return getInstance().then((ace) => {
ace.require('ace/ext/static_highlight')(domElement, {
mode: `ace/mode/${language}`,
theme: 'ace/theme/monokai',
startLineNumber: 1,
showGutter,
trim: true,
});
// Catch clicks here, and open the editor for selection
domElement.addEventListener('click', (event) =>
openCodeEditor(event, domElement, language)
);
});
}
Does anyone of you have recommendations or perhaps my approach is faulty?
Thank you !
You can set the height of editor to be same as the height of replaced element.
var editor = ace.edit(null, {
value: domElement.textContent,
theme: 'ace/theme/monokai',
mode: `ace/mode/${language}`,
});
editor.container.style.height = domElement.clientHeight + "px"
domElement.replaceWith(editor.container)
but if the goal is simply to allow copying, selecting contents of domElement should work too.
I have bootstrap popover initialized on events, inside popover content i have button (on click button calls function which changes the extendedProp.status of related event using event.setExtendedProp() method)
//above of my code FullCalendar has rendered and set as variable var = calendar
eventDidMount: function (info) {
$(info.el).popover({
html: true,
content: PopoverHtml(info.event),
container: 'body',
animation: true,
})
}
Since popover is initialized right after the event element has been added to the DOM i need to rerender event to change popover's content
eventChange: function (changeInfo) {
event_source = calendar.getEventSourceById(changeInfo.event.id);
event_source.refetch();
},
I also tried dynamic content setting method of bootstrap setContent()
I use popover with eventClick without problems:
function event_click(info) {
$('.popover_show').popover('dispose');
$(info.jsEvent.srcElement).popover({
container: 'body',
animation: false,
title: 'Zeitraum: '+fc_date_print(info.event.start, true)+" - "+fc_date_print(info.event.end, false)+
"<a href='#' class='float-right' onclick='form_cancel()' ><img src='/icon/x.svg' width='23' height='23' > </a>",
placement: 'bottom',
boundary: 'window',
sanitize: false,
trigger : 'manual',
popperConfig: {eventsEnabled: false },
"html": true,
content: function(){ a = get_form(info.event.extendedProps['id']); return a; }
});
$(info.jsEvent.srcElement).popover('show');
$(info.jsEvent.srcElement).addClass('popover_show');
}
I create the popover-content dynamicly in get_form() (currently in 2 way, one by javascript from extentedProbs, second I load content from popover dynamicly via ajax. This is much more efficent, than creating a popover for every event in advance.
Works fine for me.
The line
$(info.jsEvent.srcElement).popover('show');
do the magic, that you don't need a second click.
I add the class popover_show to the sourceElement, so $('.popover_show').popover('dispose');
will close all popover. (I do that before open a new popover)
But there are plenty other ways for that.
I am using the jQuery U.S. map plugin.
Found here. https://github.com/NewSignature/us-map/
I am trying to add 10 additional buttons, that will ALSO correlate with the state data. For instance by default you can HOVER over a state and there is a HOVER COLOR. I'm trying to maintain this effect over the new states in which I'm creating ADDITIONAL buttons for.
For instance, new button below.
$("#star_btn1").click(function() {
$('#ca').toggle();
The plugin has hover styles defined and customizeable.
'stateHoverStyles': {
fill: '#ffc600',
},
and:
_defaultMouseOverAction: function(stateData) {
// hover effect
this.bringShapeToFront(stateData.shape);
this.paper.safari();
// ... for the state
var attrs = {};
if(this.options.stateSpecificHoverStyles[stateData.name]) {
$.extend(attrs, this.options.stateHoverStyles, this.options.stateSpecificHoverStyles[stateData.name]);
} else {
attrs = this.options.stateHoverStyles;
}
stateData.shape.animate(attrs, this.options.stateHoverAnimation);
Any ideas how I can incorporate this with my new buttons as well?
You can have the event handlers for the buttons trigger the events for the map plugin.
HTML:
<button type="button" class="stateBtn" data-name="CA">California</button>
<button type="button" class="stateBtn" data-name="MN">Minnesota</button>
<br />
<br />
<div id="map" style="width: 550px; height: 350px;"></div>
<div id="clicked-state"></div>
Original JavaScript for the map:
$('#map').usmap({
click: function (event, data) {
$('#clicked-state')
.text('You clicked: ' + data.name)
.parent().effect('highlight', {
color: '#C7F464'
}, 2000);
}
});
Additional JavaScript for the buttons:
$('.stateBtn').on('click mouseout mouseover', function(e) {
var name = $(this).attr('data-name');
$('#map').usmap('trigger', name, e.type, e);
});
Notice how additional state buttons can be added without needing to add any additional JavaScript code.
Demo on jsfiddle
US Map Plugin Documentation
I have a TinyMCE 4.x instance where the text should be in read only mode. But I still have some buttons that I want to have enabled. For example, one button could provide a character count for the part of the text I've selected.
But when I turn on read only mode for TinyMCE all buttons are disabled. Can I enable just my buttons while still retaining read only mode?
It's probably too late for you but other people may pass by here.
I came up by writing this function
function enableTinyMceEditorPlugin(editorId, pluginName, commandName) {
var htmlEditorDiv = document.getElementById(editorId).previousSibling;
var editor = tinymce.get(editorId);
var buttonDiv = htmlEditorDiv.querySelectorAll('.mce-i-' + pluginName.toLowerCase())[0].parentElement.parentElement;
buttonDiv.className = buttonDiv.className.replace(' mce-disabled', '');
buttonDiv.removeAttribute('aria-disabled');
buttonDiv.firstChild.onclick = function () {
editor.execCommand(commandName);
};
}
It does the trick in 2 steps:
make the button clickable (remove mce-disabled CSS class and remove the aria-disabled property)
assign the good command to the click event
And in my editor init event I call the function.
editor.on('init', function () {
if (readOnly) {
editor.setMode('readonly');
enableTinyMceEditorPlugin(htmlEditorId, 'preview', 'mcePreview');
enableTinyMceEditorPlugin(htmlEditorId, 'code', 'mceCodeEditor');
}
});
Current version of TinyMCE for which I wrote this code is 4.4.3. It may break in a future version, specifically about the selectors to get and modify the good HTML elements.
Command identifiers can be found at this page otherwise you can also find them under tinymce\plugins\PluginName\plugin(.min).js
Here is a simple way to enable your custom toolbar button and attach a click event handler inside a read only TinyMCE editor using JQUERY:
//Initialize read only Tinymce editor so that Lock button is also disabled
function initReadOnlyTinyMCE() {
tinymce.init({
selector: '#main'
, toolbar: 'myLockButton'
, body_class: 'main-div'
, content_css: 'stylesheets/index.css'
, readonly: true
, setup: function (readOnlyMain) {
readOnlyMain.addButton('myLockButton', { //Lock button is disabled because readonly is set to true
image: 'images/lock.png'
, tooltip: 'Lock Editor'
});
}
});
}
function displayReadOnlyTinyMCEwithLockButtonEnabled() {
var edContent = $('main').html();
$("#main").empty();
initReadOnlyTinyMCE(true);
tinyMCE.activeEditor.setContent(edContent);
//enable the lock button and attach a click event handler
$('[aria-label="Lock Editor"]').removeClass("mce-disabled");
$('[aria-label="Lock Editor"]').removeAttr("aria-disabled");
$('[aria-label="Lock Editor"]').attr("onclick", "LockEditor()");
}
function LockEditor() {
alert("Tiny mce editor is locked by the current user!!");
//Write your logic to lock the editor...
}
I couldn't find an easy way to do this. The simplest way is to remove the contenteditable attribute from the iframe body instead and substitute a read only toolbar set. It also means that people will still be able to copy content from the editor.
$("iframe").contents().find("body").removeAttr("contenteditable");
How about this :
editor.addButton('yourButton', {
title: 'One can Enable/disable TinyMCE',
text: "Disable",
onclick: function (ee) {
editor.setMode('readonly');
if($(ee.target).text() == "Disable"){
var theEle = $(ee.target).toggle();
var edit = editor;
var newBut = "<input type='button' style='opacity:1;color:white; background-color:orange;' value='Enable'/>";
$(newBut).prependTo($(theEle).closest("div")).click(function(e){
edit.setMode('design');
$(e.target).remove();
$(theEle).toggle();
});
}
}
});
You can try to run the code below:
$("#tinymce").contentEditable="false";
if you have more than one editors, you can use their id like below
$("#tinymce[data-id='idOfTheEditor']").contentEditable="false";