Ext JS - create a tool with dynamic tooltip on a panel - javascript

I have a panel and that panel has a load of tools.
these are defined in an array,
eg:
myPanel.tools = [
{
type : 'down',
tooltip : 'Down',
},
{
type : 'up',
tooltip : 'Up',
},
{
type : 'help',
tooltip : 'Blah Blah',
}
]
But the above is fine if the tooltip is static, but I would like it to be updated whenever the user mouses over it.
Can you pass a function to the config to call when moused over or right before its shown? Is there another way.

tooltip excepts an config object where you can add a listener:
tooltip: {
listeners: {
'render': function(comp){
comp.tooltip = "enter your tooltip";
}
}
}
now you can modify the component like you want.

Related

Cannot add mapkey icon to L.easyButton in Leaflet

I am trying to add an icon from mapkey to L.easyButton using the following code, but I am getting the error below.
var menuButton = L.easyButton({
states: [{
stateName: 'show-menu',
icon: L.icon.mapkey({icon:"bars",color:'#000000',background: false,size:25}),
title: 'Show Menu',
onClick: function (btn, map) {
menu.options.button = btn;
menu.show();
btn.state('hide-menu');
}
},{
stateName: 'hide-menu',
icon: 'fa-star',
title: 'Hide Menu',
onClick: function (btn, map) {
menu.hide();
btn.state('show-menu');
}
}],
id: 'styles-menu',
});
menuButton.addTo(map);
Error:
TypeError: ambiguousIconString.match is not a function
Do I need to add another type of icon or something?
L.easyButton accepts a range of options for icons, but an L.icon object is not one of them. L.icon objects are for defining marker icons in Leaflet. It does not appear that you are defining a marker icon.
I would try using the actual icon class in a <span> for the icon property. For example:
var menuButton = L.easyButton({
states: [{
stateName: 'show-menu',
icon: "<span class='mki mki-bars'></span>",
title: 'Show Menu',
/* ... your other code below ... */
}]
});
Here's an example using JSFiddle. You can see the menu button beneath the +/- buttons on the top left of the map.
Note that I did not build a menu, so clicking the menu button will throw an error.
L.easyButton doesn't take a L.icon argument. Your second use is correct, it can take a Font Awesome icon name. A plain HTML icon could work for you here - see http://danielmontague.com/projects/easyButton.js/v2/examples/#icon-options

Is there a possibility to add a HTML element dynamically inside a dialog of a plugin in CK-EDITOR?

I am creating a widget in ck-editor where when user clicks a toolbar button,a dialog is opened.In a dialog there is text field and one search button,rest area in a dialog is for search results to be shown.
Is it possible that user enters some text in a text field , hit search button and by using some API I display some 50 search results(scrollable) in a dialog of a plugin below the text field and search button?
Right now I am using this code (just a dummy to check if I can add elements dynamically)-
CKEDITOR.dialog.add('simplebox', function(editor){
return {
title: 'Reference',
minWidth: 600,
minHeight: 400,
onShow: function() {
alert(CKEDITOR.dialog.getCurrent().definition.getContents("new_reference").elements);
},
contents: [
{
id: 'new_reference',
label:'New Reference',
elements: [
{
id: 'type',
type: 'select',
label: 'Type',
items: [
[ editor.lang.common.notSet, '' ],
[ 'Book' ],
[ 'Journal' ],
[ 'URL' ],
[ 'PHD Thesis']
]
},
{
type: 'text',
id: 'reference',
label: 'Reference',
validate: CKEDITOR.dialog.validate.notEmpty( "Search field cannot be empty." )
},
{
type: 'button',
align:'horizontal',
id: 'referencebutton',
label:'Search',
title: 'My title',
onClick: function() {
var linkContent = { type : 'html', id : 'test', html : '<div>just a test</div>' };
// this = CKEDITOR.ui.dialog.button
var dialog = CKEDITOR.dialog.getCurrent();
//alert(dialog.getContentElement('new_reference','reference').getValue());
var definition = dialog.definition;
//alert(definition.title);
definition.getContents("new_reference").add(linkContent);
// CKEDITOR.dialog.addUIElement('list',function(){
// definition.getContents("new_reference").add(linkContent);
// });
alert(CKEDITOR.dialog.getCurrent().definition.getContents("new_reference").elements);
}
}
]
},
{
id: 'old_reference',
label:'Old Reference',
elements: [
{
id:'author',
type:'text',
label:'Author'
}
]
}
]
};
});
Inside onShow method I am printing the no. of UI elements inside a content of a dialog.It shows 3 objects. After click of a button,it shows 4 objects since one has been added via code but it does show in the UI?
Any clues on this?
Thanks
Your approach is OK but by calling
definition.getContents("new_reference").add(linkContent);
you're modifying CKEDITOR.dialog.definition, which is used only the first time the dialog is opened – to build it. Then, once built, if you close the dialog and open it again, the editor uses the same DOM to display it. What I mean is that CKEDITOR.dialog.definition is a blueprint, which is used once and has no further impact on the dialog.
To interact with live dialog, use the following
CKEDITOR.ui.dialog.uiElement-method-getDialog,
CKEDITOR.dialog-method-getContentElement (returns CKEDITOR.ui.dialog.uiElement),
CKEDITOR.dialog-method-getValueOf,
CKEDITOR.dialog-method-setValueOf
like
onClick: function() {
var dialog = this.getDialog();
// get the element
console.log( dialog.getContentElement( 'tabName', 'fieldId' ) );
// get the value
dialog.getValueOf( 'tabName', 'fieldId' ) );
// set the value
dialog.setValueOf( 'tabName', 'fieldId', 'value' ) );
}
One way to get around this problem is to use the onShow function and insert an html object in the dialog tab.
onShow : function() {
var element = document.createElement("div");
element.setAttribute('id', "someId");
document.getElementsByName("new_reference")[0].appendChild(element);
}
Then in the onClick function, just access the element and set the content you want, like this:
onClick : function() {
document.getElementById("someId").innerHTML='<div id="example-'+count+'">Hello World</div>';
}
By doing this, you should be able to get data to show in your dialog. Hope it helps.

SenchaTouch 2 : Same toolbar used across the views is firing the same event multiple times

BackGround:
I am using the same toolbar in all my views which is defined in a separate view. This toolbar has four buttons. Since this button has 'id' attribute,
tap event on one button from a view will trigger similar tap events from other views as well since the same toolbar is used across the views.
My Toolbar is as below.
Ext.define("WU.view.WUToolBar", {
extend: "Ext.Toolbar",
alias: "widget.wuToolBar",
xtype:"wuToolBar",
config: {
docked : 'bottom',
cls : 'tabBar',
ui:'widgetBottombarUI',
items : [
{
xtype : 'button',
text : 'My Account',
cls : 'profileTabBar',
id : 'myProfileButton',
listeners : {
tap : function(button, e, eOpts) {
console.log('myProfileButton is clicked');
}
},
{
xtype : 'button',
text : 'Help',
cls : 'helpTabBar',
id : 'helpTabButton',
listeners : {
tap : function(button, e, eOpts) {
console.log('helpButton is clicked');
}
},
]
},
});
I am adding this to my different views in the items config as below.
xtype : 'wuToolBar'
So, tap event on a button in a single view will fires the tap event from all the views since this toolbar is shared across the pages. If I am removing the
id attribute then application works fine but I need to assign the id to the button since I have to access them using getCmp method.
If it is on all views, then I would suggest adding it in your app.js, and then simply add to the Viewport when you move from screen to screen:
In app.js:
...
launch: function() {
...
// Add static components
Ext.Viewport.add([
{
xtype: 'wuToolBar'
docked: 'bottom' // I would recommend moving this out of your customized config
}
]);
...
},
...
You can add a view later using the same method (Ext.Viewport.add(...)), or you can use the Ext.navigation.View component.

Sencha Touch 2: How to override back button on Navigation View

I was wondering how to ovverride the back button on a navigation view. I tried using onBackButtonTap but it doesnt seem to work http://www.senchafiddle.com/#8zaXf
var view = Ext.Viewport.add({
xtype: 'navigationview',
onBackButtonTap: function () {
alert('Back Button Pressed');
},
//we only give it one item by default, which will be the only item in the 'stack' when it loads
items: [
{
//items can have titles
title: 'Navigation View',
padding: 10,
//inside this first item we are going to add a button
items: [
{
xtype: 'button',
text: 'Push another view!',
handler: function() {
//when someone taps this button, it will push another view into stack
view.push({
//this one also has a title
title: 'Second View',
padding: 10,
//once again, this view has one button
items: [
{
xtype: 'button',
text: 'Pop this view!',
handler: function() {
//and when you press this button, it will pop the current view (this) out of the stack
view.pop();
}
}
]
});
The fiddle you've mentioned works well in my local project on my machine. For some reason, it doesn't work on fiddle site. Try running it on your local project.
Still instead of using onBackButtonTap config, it's good to extend Ext.navigation.View class and override onBackButtonTap method. That way you'll have more control over whole components. You'd also like to override other configs as well. Here's what I'd use -
Ext.namespace('Ext.ux.so');
Ext.define('Ext.ux.so.CustomNav',{
extend:'Ext.navigation.View',
xtype:'customnav',
config:{
},
onBackButtonTap:function(){
this.callParent(arguments);
alert('back button pressed');
}
});
the line this.callParent(arguments) will allow component to behave in default way + the way to wanted it to behave. And if you want to completely override the back button behavior you can remove this line. Try doing both ways.
To use this custom component, you can use -
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
var view = Ext.create('Ext.ux.so.CustomNav', {
fullscreen: true,
items: [{
title: 'First',
items: [{
xtype: 'button',
text: 'Push a new view!',
handler: function() {
//use the push() method to push another view. It works much like
//add() or setActiveItem(). it accepts a view instance, or you can give it
//a view config.
view.push({
title: 'Second',
html: 'Second view!'
});
}
}]
}]
});
}
Give this a shot. It'll work for you yoo.

Scope issue in extjs 4

I have this treepanel and i want to call this.getId() method of mainpaneltree from inside "Expand all" button But all i get is method undefined.I tried to put scope:thisin config objects but no success.
Ext.define('MA.view.patient.Tree', {
extend : 'Ext.tree.Panel',
alias : 'widget.EditPatientTree',
title : 'Simple Tree',
width : 150,
store:'Tree',
dockedItems : [ {
xtype : 'toolbar',
items : [ {
text : 'Expand All',
scope: this,
handler : function() {
//this.expandAll gives "Uncaught TypeError: Object [object DOMWindow] has no method 'getId'"
this.expandAll();
//the same error for this.getId();
this.getId();
}
} ]
} ],
rootVisible : false,
initComponent : function() {
this.callParent(arguments);
}
});
So my question is how to get reference to the current component and call its methods while you are inside nested methods or config objects of current component
The handler has arguments that are passed in, 1 of them is normally the button. From the button you can get the container.
Ext.define('MA.view.patient.Tree', {
extend : 'Ext.tree.Panel',
alias : 'widget.EditPatientTree',
title : 'Simple Tree',
width : 150,
store:'Tree',
dockedItems : [ {
xtype : 'toolbar',
items : [ {
text : 'Expand All',
scope: this,
handler : function(button, event) {
var toolbar = button.up('toolbar'), treepanel = toolbar.up('treepanel');
treepanel.expandAll();
treepanel.getId();
}
} ]
} ],
rootVisible : false,
initComponent : function() {
this.callParent(arguments);
}
});
You can make use of the methods like up, down for get references of components that are parent or child. In your case, you could get the reference of the tree panel by:
myTree = this.up('treepanel');
Similarly, you could use the down method, to get hold of any child reference.

Categories