I'd like add a button and let performers to copy some text to their clipboard once they click on the button. However, I found:
the element interface { {button}} does not accept an "on-click" property
the original html button tag may work, but when I add the the function to the on_click property and the js section, the page returns the error "the function does not found".
So, my question is, how I can add a user defined js function to a project? Is there any example code/project I can reference to?
Try to add the following code in TASK INTERFACE in your project:
<div>
{{field type="input" name="whatever" value=link size="L" width="70%"}}
{{button label="Copy text to clipboard" href="#" size="L"}}
</div>
<textarea class="hiddenInput"></textarea>
in onRender() in JS field:
onRender: function() {
var _document = this.getDOMElement(),
button = _document.querySelector('.button'),
hiddenInput = _document.querySelector('.hiddenInput'),
task = this;
button.addEventListener('click',function (e) {
e.preventDefault();
hiddenInput.value = task.getTask().input_values.link;
/*hiddenInput.focus();*/
hiddenInput.click();
hiddenInput.select();
document.execCommand('copy');
button.classList.add('button_disabled');
button.querySelector('.button__label').textContent = 'Done';
setTimeout(function () {
button.classList.remove('button_disabled');
button.querySelector('.button__label').textContent = 'Copy text to clipboard';
},1000)
})
},
I am using elementor's popup in wordpress to show my CF7 form. My issue is that the popup closes before it can show the after submit confirmation text.
What could I do in such a situation? That text is very important.
You need to reinitialize the form after the opening of the popup.
You can add a html widget in the page where the popup opens (Or in the footer, if opens in any part of the website) and paste the following code:
<script>
window.addEventListener('DOMContentLoaded', function() {
// More information about elementor popup events
// here https://developers.elementor.com/elementor-pro-2-7-popup-events/
jQuery(document).on('elementor/popup/show', () => {
wpcf7.init(jQuery(".wpcf7-form")[0]);
});
});
</script>
Or even modify the functions.php (In the child theme if is necessary):
// Stop Elementor Popup from Closing after CF7 submission with no validation
function elementor_popup_cf7_fix() {
?>
<script type='text/javascript'>
window.addEventListener('DOMContentLoaded', function() {
jQuery(document).on('elementor/popup/show', () => {
for(var i = 0; i < jQuery(".wpcf7-form").length ; i++) {
wpcf7.init(jQuery(".wpcf7-form")[i]);
}
});
});
</script>
<?php
}
add_action( 'wp_footer', 'elementor_popup_cf7_fix' );
Source: https://github.com/elementor/elementor/issues/7798
I created a custom popup at a fixed position on a Leaflet map. When clicking a marker i'm able to close the popup and open another one by clicking a different marker. However, when I don't close the popup by clicking the close button and instead click another marker the popup content changes but I'm no longer able to close the popup by clicking the close button, it is stuck. How to solve this?
// Custom marker
var redFlag = L.icon({
iconUrl: 'images/mapmarker2.png',
iconSize: [34, 34],
iconAnchor: [17,34]
});
//geoJSON data, stored in 'art' variable
const myLayer = L.geoJSON(art, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: redFlag});
},
onEachFeature: function ( feature, layer) {
layer.on('click', function(e){
var getWrap = document.getElementById('mapid');
var wrap = getWrap.appendChild(document.createElement('div'));
wrap.className = 'wrapper';
wrap.style.backgroundColor = '#fff';
wrap.innerHTML =
`<div class="close">X</div>`+
`<div class="popUpContent" style="background-color:#e8f4ff">` +
`<div class='pic'><img src =
"images/${feature.properties.image}"></div>`+
`<div class="puName"><span
class="puName">${feature.properties.name}</span><br>`+
`<span class="puTitle">"${feature.properties.title}"</span> <br>`+
`<div class="extra3">${feature.properties.extra}</div></div>`+
`</div>`;
if(!feature.properties.title){
wrap.innerHTML =
`<div class="close">X</div>`+
`<div class="popUpContent" style="background-color:#e8f4ff">` +
`<div class='pic'><img src =
"images/${feature.properties.image}"></div>`+
`<div class="puName"><span
class="puName">${feature.properties.name}</span><br>`+
`<div class="extra3">${feature.properties.extra}</div></div>`+
`</div>`;
}
// EventListener attached to close button
document.querySelector('.close').addEventListener('click', closePopup);
function closePopup(e){
if(document.querySelector('.wrapper').style.display = 'block'){
document.querySelector('.wrapper').remove();
}
}
});
}
});
mymap.addLayer(myLayer)
I'm trying to trigger a click event that will open my href sip/tel link when user clicks the button, but it doesn't trigger the click event after the button has been pressed.
jquery code:
$('#next_button').click(function() {
var num = $(this).val();
$('#call-num'+num).trigger('click');
alert(num);
});
href code:
(999) 888-3333
<button id="next_button" value="1">Next</button>
$('#next_button').on('click', function() {
var num = $(this).val();
var call = $('#call-num'+num).attr('href');
location.href = call;
alert(call);
});
In Facebook status update box, when I type # and start typing and choose a name, say Steven Gerrard, from the friends list suggested by fb, my friend's name is highlighted in the textarea like this
I checked with Firebug and there's only
a div.highlighter which contains sort of formated text (Steven Gerrard is within b tags)
a textarea inside a div.uiTypeahead. Nothing interesting i could find
and a hidden input, that contains the actual text that will be posted: #[100001915747xxx:Steven Gerrard] is awesome
What is the secret trick behind this? Normal rich text editors like ckeditor usually have an iframe to display the text and an actual textarea to keep the original content. But in this case, I do not see anything. Someone please shed some lights?
I would like to make something like this but have no clue where to begin. Also, if I would like to display a small thumb next to my friend's name, is it possible at all?
Here is how it works:
You superpose the textarea (in front) and a div (behind) that will have the same size, and the same font size.
The textarea must have a transparent background, so we can see its text, but also see the div behind it.
The div behind it will have a white text and white background, so the text it contains will be transparent.
You set a hook on the textarea's keyup, and you process the text it contains as HTML: replace the line breaks by <br/>, replace the double spaces by , and also replace all the words that you want to highlight by a version surrounded by <span style="background-color: #D8DFEA;"></span>.
Since you can see the highlight div behind the textarea, and that the text the highlight div contains is perfectly aligned with the text in the textarea, and that the <span> is visible, you will have the illusion that the text in the textarea is highlighted.
I've written a quick example based on jquery so you can try it yourself, without too much code to analyze.
Here is a sample code you can just copy-paste-save and try:
This sample code will highlight a defined set of word, here: "hello" and "world".
I'll let you adapt it the way you want.
<html>
<head>
<title></title>
<!-- Load jQuery -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<!-- The javascript xontaining the plugin and the code to init the plugin -->
<script type="text/javascript">
$(function() {
// let's init the plugin, that we called "highlight".
// We will highlight the words "hello" and "world",
// and set the input area to a widht and height of 500 and 250 respectively.
$("#container").highlight({
words: ["hello","world"],
width: 500,
height: 250
});
});
// the plugin that would do the trick
(function($){
$.fn.extend({
highlight: function() {
// the main class
var pluginClass = function() {};
// init the class
// Bootloader
pluginClass.prototype.__init = function (element) {
try {
this.element = element;
} catch (err) {
this.error(err);
}
};
// centralized error handler
pluginClass.prototype.error = function (e) {
// manage error and exceptions here
//console.info("error!",e);
};
// Centralized routing function
pluginClass.prototype.execute = function (fn, options) {
try {
options = $.extend({},options);
if (typeof(this[fn]) == "function") {
var output = this[fn].apply(this, [options]);
} else {
this.error("undefined_function");
}
} catch (err) {
this.error(err);
}
};
// **********************
// Plugin Class starts here
// **********************
// init the component
pluginClass.prototype.init = function (options) {
try {
// the element's reference ( $("#container") ) is stored into "this.element"
var scope = this;
this.options = options;
// just find the different elements we'll need
this.highlighterContainer = this.element.find('#highlighterContainer');
this.inputContainer = this.element.find('#inputContainer');
this.textarea = this.inputContainer.find('textarea');
this.highlighter = this.highlighterContainer.find('#highlighter');
// apply the css
this.element.css('position','relative');
// place both the highlight container and the textarea container
// on the same coordonate to superpose them.
this.highlighterContainer.css({
'position': 'absolute',
'left': '0',
'top': '0',
'border': '1px dashed #ff0000',
'width': this.options.width,
'height': this.options.height,
'cursor': 'text'
});
this.inputContainer.css({
'position': 'absolute',
'left': '0',
'top': '0',
'border': '1px solid #000000'
});
// now let's make sure the highlit div and the textarea will superpose,
// by applying the same font size and stuffs.
// the highlighter must have a white text so it will be invisible
this.highlighter.css({
'padding': '7px',
'color': '#eeeeee',
'background-color': '#ffffff',
'margin': '0px',
'font-size': '11px',
'font-family': '"lucida grande",tahoma,verdana,arial,sans-serif'
});
// the textarea must have a transparent background so we can see the highlight div behind it
this.textarea.css({
'background-color': 'transparent',
'padding': '5px',
'margin': '0px',
'font-size': '11px',
'width': this.options.width,
'height': this.options.height,
'font-family': '"lucida grande",tahoma,verdana,arial,sans-serif'
});
// apply the hooks
this.highlighterContainer.bind('click', function() {
scope.textarea.focus();
});
this.textarea.bind('keyup', function() {
// when we type in the textarea,
// we want the text to be processed and re-injected into the div behind it.
scope.applyText($(this).val());
});
} catch (err) {
this.error(err);
}
return true;
};
pluginClass.prototype.applyText = function (text) {
try {
var scope = this;
// parse the text:
// replace all the line braks by <br/>, and all the double spaces by the html version
text = this.replaceAll(text,'\n','<br/>');
text = this.replaceAll(text,' ',' ');
// replace the words by a highlighted version of the words
for (var i=0;i<this.options.words.length;i++) {
text = this.replaceAll(text,this.options.words[i],'<span style="background-color: #D8DFEA;">'+this.options.words[i]+'</span>');
}
// re-inject the processed text into the div
this.highlighter.html(text);
} catch (err) {
this.error(err);
}
return true;
};
// "replace all" function
pluginClass.prototype.replaceAll = function(txt, replace, with_this) {
return txt.replace(new RegExp(replace, 'g'),with_this);
}
// don't worry about this part, it's just the required code for the plugin to hadle the methods and stuffs. Not relevant here.
//**********************
// process
var fn;
var options;
if (arguments.length == 0) {
fn = "init";
options = {};
} else if (arguments.length == 1 && typeof(arguments[0]) == 'object') {
fn = "init";
options = $.extend({},arguments[0]);
} else {
fn = arguments[0];
options = $.extend({},arguments[1]);
}
$.each(this, function(idx, item) {
// if the component is not yet existing, create it.
if ($(item).data('highlightPlugin') == null) {
$(item).data('highlightPlugin', new pluginClass());
$(item).data('highlightPlugin').__init($(item));
}
$(item).data('highlightPlugin').execute(fn, options);
});
return this;
}
});
})(jQuery);
</script>
</head>
<body>
<div id="container">
<div id="highlighterContainer">
<div id="highlighter">
</div>
</div>
<div id="inputContainer">
<textarea cols="30" rows="10">
</textarea>
</div>
</div>
</body>
</html>
Let me know if you have any question or if you need help with this code.
After reviewing the way of Facebook do this, I see that the text shown on the screen is:
<span class="highlighterContent"><b>Ws Dev</b> is good</span>
That span is put in a table (with lots of div container), which is style accordingly.
So I think this is the process:
When you type in the box, Facebook does have a textarea that capture what you type, but use javascript to show the typed HTML content in a table.
When you submit, the formatted content in a hidden input (that you already spot in the question) get submitted. It's like "#[100001915747xxx:Steven Gerrard] is awesome".
When the formatted message submit, it is saved to the database. Everytime the page get loaded, from the saved message the HTML is composed and return.
To get the similar effect, you can use any jQuery autocomplete plugin.