Angular interpolation function name with (click) Event - javascript

I got a JSON file where I specify dynamic different button but clicking on button does not call the function.
Here is my JSON file structure:
export const liveButtonData = [
{ title: 'My Name', function: 'getName()'}
{ title: 'My Title', function: 'getTitle()'}
{ title: 'My Status', function: ''}
}];
In my Angular HTML code
// the following clicking on the button does nothing
<button title={{button.title}}
(click)=button.function>
</button>
or
<button title={{button.title}}
(click)="button.function">
</button>
// this is not allowed
// the following throws an error
<button title={{button.title}}
(click)={{button.function}}>
</button>
Not sure what other syntax to try. Any help is appreciated and thanks in advance.

In your case the JSON file holds the function names as:
string names (not directly refer to the real method objects)
with () at the end. If we would like to invoke a method via string name should remove the () from the string name
Possible solution:
export const liveButtonData = [
{ title: 'My Name', function: 'getName'}
{ title: 'My Title', function: 'getTitle'}
{ title: 'My Status', function: ''}
}];
<button title={{button.title}}
(click)="functionWrapper(button, button.function)">
</button>
function functionWrapper (functionSource, functionName) {
functionSource[functionName]();
}
Then when we have the name/key of the function. We take it from it's source object with []. And call it with () at the end. And in the case above the () are not a string but real JavaScript invoke.

Related

SemanticUI/ReactJS modal not support html content

I using ReactJS and SemanticUI, want to use modal but look like it's not support html inside it, right? just display plain text. well, I made a compontent for displaying modal called Alert:
<Modal
open={this.props.open}
size={this.props.size}
content={this.props.content}
actions={[
{ key: 'no', content: this.props.actions, positive: false, onClick: this.props.close }
]}
/>
In a page I display alert on click:
goBuy = (e) => {
let obj = {
size: 'tiny',
actions: 'nope',
click: this.goSpend,
content: 'Are you sure?',
}
this.setState({
alert: obj,
alertOpen: true,
})
}
It working fine, but now I want to add some html code in content like this:
content: 'Are you <b>sure</b>?',
But this not working and display html code like plain text and not make it bold. Any idea how can I solve this?
Are you <b>sure</b>?
But want this:
Are you sure?
The problem here is the Modal itself thinks the value you are passing to content is a text value so the modal displays exact same word you have provided. So instead of passing your <br> tag there, you can pass jsx as a content and render it like this.
const content = {
return(<p>Are you <b>sure</b></p>);
}
goBuy = (e) => {
let obj = {
size: 'tiny',
actions: 'nope',
click: this.goSpend,
content: {content },
}
this.setState({
alert: obj,
alertOpen: true,
})
}
No need to using jsx with return just go this way:
const someHtml = (<p>Are you <b>sure</b>?</p>);
You can pass jsx as a content and render it.

variable amount of optional parameters

Im using this tool here http://craftpip.github.io/jquery-confirm/#dialog and i wanted to have a popup that has a variable amount of buttons based on a piece of data used to construct pop up.
Here is an example of what a very simple/empty one looks like.
$.confirm({
title: 'testing',
content: 'this has two static buttons',
buttons: {
confirm: function () {
},
cancel: function () {
},
}
});
What i want is to be able to put a foreach loop in side of "buttons: { ... }".
Is there a way to do so or a way to achieve what i am trying to do?
Just build your options object before :
var options = {
title: 'testing',
content: 'this has two static buttons',
buttons: {},
};
$.each( variable_name, function(){
options.buttons[ this.btn_name ] = this.fn;
} );
$.confirm( options );
Of course, everything depends on how the object you loop looks like, but the logic is here.
Your logic is inverted. The following is an object:
{
title: 'testing',
content: 'this has two static buttons',
buttons: {
confirm: function () {
},
cancel: function () {
},
}
}
So you could do:
var options = {
title: 'testing',
content: 'this has two static buttons',
buttons: {
confirm: function () {
},
cancel: function () {
},
}
};
$.confirm(options);
You then can add items by
options.buttons["mybutton"] = function() { };
You can place the previous code in a loop and change the string "mybutton" to whatever you want for whatever functions you have. You're basically asking how to add a property to and existing javascript object.

Adding multiple buttons in TinyMce in a loop doesn't work

I have a config list for buttons like this:
var config = [{
name: 'first',
insertionConfig: {
title: 'first button',
onsubmit: function(){
// do sth
}
}
},{
name: 'second',
insertionConfig: {
title: 'second button',
onsubmit: function(){
// do sth
}
}
}
]
and in my TinyMce plugin I want to add all buttons according to their config. So it would end up like this:
tinymce.PluginManager.add('myPlugin', function(editor, url) {
for (var i in config) {
item = config[i];
editor.addButton(item.name, {
text: item.name,
onclick: function() {
editor.windowManager.open({
title: item.insertionConfig.title,
onsubmit: item.insertionConfig.onsubmit
}
};
}
});
but when I click on first button, it shows the second button's title. all configs of buttons refer to last added button. I know problem is something about the 'item' in the loop (all buttons refer to same item object which is the last one) but I don't know how to fix it.
Try creating a locally scoped variable for item inside the onclick function:
The issue you are running into is how variables are managed in JavaScript at the time the function is actually run. The click function is not actually run until you click an item and at that time item is pointing to the last item in the array.
EDIT: Check out this TinyMCE Fiddle for how this may happen: http://fiddle.tinymce.com/REfaab/1

TinyMCE Dynamic Buttons/Methods

I'm attempting to create a Wordpress plugin which allows you to easily add a dropdown menu with items in for inserting shortcodes. To do this, I need to 'hook' into TinyMCE, registering a custom plugin. My plan is to allow users to setup the shortcode menu items using a simple PHP array.
The following class is instantiated which registers a new button and the plugin script:
<?php
namespace PaperMoon\ShortcodeButtons;
defined('ABSPATH') or die('Access Denied');
class TinyMce {
public function __construct()
{
$this->add_actions();
$this->add_filters();
}
private function add_actions()
{
add_action('admin_head', [$this, 'print_config']);
}
public function print_config()
{
$shortcodes_config = include PMSB_PLUGIN_PATH . 'lib/shortcodes-config.php'; ?>
<script type='text/javascript' id="test">
var pmsb = {
'config': <?php echo json_encode($shortcodes_config); ?>
};
</script> <?php
}
private function add_filters()
{
add_filter('mce_buttons', [$this, 'register_buttons']);
add_filter('mce_external_plugins', [$this, 'register_plugins']);
}
public function register_buttons($buttons)
{
array_push($buttons, 'shortcodebuttons');
return $buttons;
}
public function register_plugins($plugin_array)
{
$plugin_array['shortcodebuttons'] = PMSB_PLUGIN_URL . 'assets/js/tinymce.shortcodebuttons.js';
return $plugin_array;
}
}
A user would create a PHP array like so (which is included in the above class and output as a javascript variable in the header):
<?php
return [
[
'title' => 'Test Shortcode',
'slug' => 'text_shortcode',
'fields' => [
'type' => 'text',
'name' => 'textboxName',
'label' => 'Text',
'value' => '30'
]
],
[
'title' => 'Test Shortcode2',
'slug' => 'text_shortcode2',
'fields' => [
'type' => 'text',
'name' => 'textboxName2',
'label' => 'Text2',
'value' => '30'
]
]
];
Finally, here's the actual plugin script:
"use strict";
(function() {
tinymce.PluginManager.add('shortcodebuttons', function(editor, url) {
var menu = [];
var open_dialog = function(i)
{
console.log(pmsb.config[i]);
editor.windowManager.open({
title: pmsb.config[i].title,
body: pmsb.config[i].fields,
onsubmit: function(e) {
editor.insertContent('[' + pmsb.config[i].slug + ' textbox="' + e.data.textboxName + '" multiline="' + e.data.multilineName + '" listbox="' + e.data.listboxName + '"]');
}
});
}
for(let i = 0; i <= pmsb.config.length - 1; i++) {
menu[i] = {
text: pmsb.config[i].title,
onclick: function() {
open_dialog(i)
}
}
}
console.log(menu);
editor.addButton('shortcodebuttons', {
text: 'Shortcodes',
icon: false,
type: 'menubutton',
menu: menu
});
});
})();
The button registers fine, the menu items also register fine but when it comes to click on to open up a modal window, I get this error:
Uncaught Error: Could not find control by type: text
I think it's something to do with the fact that the 'fields' is coming from a function which, for some reason, TinyMCE doesn't like - even though it's built correctly.
I had thought of doing this a different way - by creating a PHP file which outputs the correct JS but if I do that, I can't register it as a TinyMCE plugin when using the mce_external_plugins action hook.
I found another question which ran in to the same problem with no answer.
I've really hit a wall with this one, any help would be hugely appreciated!
Well, the typical thing happened - as soon as I post the question, I stumble upon the answer. Maybe I need to get myself a rubber desk duck?
Anyway, the clue is in the error message. Despite having looked at quite a number of tutorials which all suggest using 'text' as the control type, it's actually 'textbox'. I'm guessing this is a more recent change in TinyMCE and the tutorials I was looking at were a bit older.
I searched for yet another tutorial and found the answer staring me right in the face.

bootstrap tooltip: how to specify tooltip text using a javascript function

bootstrap tooltip allows me to specify tooltip for the element by merely specifying the "title" attribute:
<div title="This is a test tooltip"> ... </div>
Is there any way to avoid hardcoding the tooltip content and specify a javascript function instead? I tried title="javascript:myFunction()" but it doesn't resolve it.
I looked at the booststrap code and it seems to contain support for function call I just can't figure out the syntax:
Snippet from bootstrap tooltip:
, getTitle: function () {
var title
, $e = this.$element
, o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
http://twitter.github.io/bootstrap/javascript.html#tooltips
Give your div an id and call
function titleSetter(node) {
return "My Tooltip text";
}
$('#my-div-id').tooltip({
title: 'My Tooltip text'
});
// or
$('#my-div-id').tooltip({
title: titleSetter
})
I dont know how to use a function, but I use a config file to hold the title/body of my tooltips. I then use a data-attribute for the title and body and leave it in my html. Here is my config file (really just some json):
var help = {
'001': {
title: 'Title 1',
description: 'Body 1'
},
'002': {
title: 'Title 2',
description: 'Body 2'
}
}
My html looks just like it sounds:
<div data-help="001"></div>
I then make the title and content return a function in my tool tips, like so:
var tooltipOptions = {
trigger: 'manual',
title: function() {
return help[$(this).attr('data-help')].title;
},
content: function() {
return help[$(this).attr('data-help')].description;
}
};
And I now have a dynamic body and title for my tool tips.
I believe this will solve the problem you were encountering in your question. Good luck!
if you are using bootstrap 3, you can put a id in your div
<div id="title-text" title="This is a test tooltip"> ... </div>
and then use this code
$("#title-text").attr('data-original-title', "the title");

Categories