I have a button in a panel which gets rendered inside a window. And I want to be able to add that button to a bottom bar in the window.
Current I am trying to add an onRender function to the panel to get the parent window using
this.findParentByType('Ext.Window')
however it returns null.
I am even heading in the right direction?
EDIT: I am using extjs 3.2.2
findParentByType takes xtype as parameter. So in your case you should use
this.findParentByType('window')
or
this.up('window')
Have you tried providing a unique id to your window and adding the buttons to it like so:
Ext.getCmp('myWindowId').add(buttonPanel);
#Nitin Singhal #Reflux
For ExtJS4: Ext.ComponentManager.get('html dom id')
Related
I'm trying to retrieve an element inside a material dialog container so that I can use it's position.
I am using Material Angular, and specifically the Dialog.
So far I have tried the getBoundingClientRect() after getting the element with it's associated id.
Using document.getElementById(elementId).getBoundingClientRect() returns {"x":0,"y":0,"width":0,"height":0,"top":0,"right":0,"bottom":0,"left":0}
Where elementId is the id of the button that is inside the mat-dialog.
For anyone that comes across this from my stupidity, the answer is that the element I was looking for was hidden and had no position.
I had two buttons with the same id, and it just got the first one that was in the DOM.
Changing the id of the button fixed that.
I'm using ExtJS 5.1. I have a panel with a definition of button in the items-section with a listerner for event 'click'. The 'this'-keyword refers here to the button itself. But I want a new component to my panel, so I need reference to this panel in the listener-function. 'this.getParent().add(...)' doesn't function, no function error, this.container.getParent().add(...) results in the same error. What is the correct way?
Using .up('panel') in the first argument of the click function, which is the button itself.
Or in ExtJS 5 define a reference property in your panel, and use
this.lookupReference('your_reference_in_panel');
I have a single page app using Backbone, and whenever I over over something and then click the "back" button, the popover forever stays.
I want to destroy all instances of popover when a new instance is loaded.
Finding the popovers that are created through the data API is not difficult and has been covered in other answers like those of David Mulder and Amir Popovich. You just do:
$("[data-toggle='popover']").popover('hide');
Or you can use destroy if you need to or prefer to.
The challenge is to handle those popovers that are created dynamically.
Marking the Elements with Popovers
I would implement something like this. I'd override the default popover method and I'd try to perform this override as early as possible so that everything that needs a popover uses my override. What it does is just mark elements that use a popover with a class. Bootstrap does not mark them itself:
// Override popover so as to mark everything that uses a popover.
var old_popover = $.fn.popover;
function my_popover() {
this.addClass('marked-as-having-a-popover');
return old_popover.apply(this, arguments);
}
$.fn.popover = my_popover;
Then to clear everything before the unloading, I'd put in the code that detects the unloading the following:
$(".marked-as-having-a-popover").popover('hide');
Or it could use destroy rather than hide if testing shows that it works better for your use-case.
Now, the method above will work if the override happens early enough and you do not have a page where multiple jQueries are loaded. (Yep, this is possible.) I use something similar to deal with tooltips in one of my applications so I know the principle is sound. It so happens that in my app, all tooltips are created by my code so there is no risk of missing something.
Finding All Elements with Popovers, Even Unmarked
If you are in a situation where a popover can be created without being marked (I call this an "escapee"), then you need to query the whole DOM and find which elements have popovers. There is no shortcut here. You cannot rely on attributes like data-content because popovers can be created wholly dynamically (i.e. without any of the data- attributes). Also, all kinds of elements can get popovers, so you cannot reliably assume that only button elements will have a popover. The only surefire way to find everything that needs handling is to look at each element in the DOM and check whether it has a popover:
// Obviously this is quite expensive but in a situation where there *can* be escapees
// then you have to check all elements to see if they have a popover.
$("*").each(function () {
// Bootstrap sets a data field with key `bs.popover` on elements that have a popover.
// Note that there is no corresponding **HTML attribute** on the elements so we cannot
// perform a search by attribute.
var popover = $.data(this, "bs.popover");
if (popover)
$(this).popover('hide');
});
Again, destroy could be used rather than hide.
Proof of Concept
Here is a fiddle that illustrates the entire thing:
"Add a Dynamic Popover" simulates code that would add a popover when the override is in effect.
"Add an Escapee" simulates code that would add a popover and somehow manage to use the original Bootstrap code.
"Clear Marked" clears only the marked popovers.
"Clear All" clears every single popover marked or not.
try with this:
$('YOUR_ELEMENT_SELECTOR').popover('dispose');
reference url: https://getbootstrap.com/docs/4.1/components/popovers/
Its very simple, just you have to call one function popover() with argument "destroy" to destroy the popover. It will destroy all popovers which is created by $("[data-toggle=popover]").popover();
you can check documentation for more options and arguments of popover().
I suggest you to destroy popovers with having specific class name instead of using following code.
$("[data-toggle='popover']").popover('destroy');
The above code will destroy all popovers in the page. So instead of this, use class selector.
$(".YourClassName").popover('destroy');
If you have problems and need to remove all for sure:
$('.popover').remove();
will help (Popover automatic add this class, even for dynamicly created objects). It destroys all the popover DOM-Object incl. callbacks, etc.
But thats the rough way. Typically I displose all by popover class (clean way) and to be sure I do a hard clean up after. Works for me fine!
$('.popover').popover('dispose');
$('.popover').remove();
If you like to remove all execpt one, use a filter() with :not-Selector
$('.popover').filter(':not(#yourID)').popover('dispose');
$('.popover').filter(':not(#yourID)').remove();
popover adds also a id with a random number
#popoverxxxxx where xxxxx is a five digit number.
this helps sometimes to compare popovers. Of cause this could also be used to identify the popovers.
Something generic like this (assuming you're using data-bindings) should do the trick:
$('[data-toggle="popover"]').popover('hide')
or the more extreme call
$('[data-toggle="popover"]').popover('destroy')
though I doubt that would make sense often. Still to address the specific bug you're encountering you should create a minimal test case so that that bug itself can be addressed.
Oh and if you specifically want to check for open popovers you can use .data("bs.popover").$tip.parent().length (which is a bit of an hack), for example:
$('[data-toggle="popover"]:eq(0)').data("bs.popover").$tip.parent().length == 1
You can hide all popovers by using this:
$("[data-toggle='popover']").popover('hide');
You can destroy all popovers by using this:
$("[data-toggle='popover']").popover('destroy');
The difference between hide and destory is that when you hide a popover you do not need to reactive it, but when you destroy it you do.
Check out my JSFIDDLE and then:
Click on all popovers and then click hide. After clicking hide you can click on the popovers again.
Click on all popovers and then click destroy. After clicking destroy try clicking on the popovers again and see that nothing will happen since they are destroyed. In order to make them functional again, you will need to click on reactive and then try.
Popovers must be initialized manually, so you know exactly what you have to destroy because you did initialize it.
You should just call the destroy function with the same selector.
Or maybe I am missing something ?
I am trying to add to the context menu programmatically in Javascript.
The model I'm using is vsync's answer here: https://stackoverflow.com/a/9293946/322537
And I am changing it into Javascript. What I have you can see in this fiddle:http://jsfiddle.net/pB76y/
..
As you can see, if you right click the upper image you can see the new context menu 'View Plate Thumbnail'.
But if you change the id of the menu from 'menu_from_image' to 'menu_from_image_js' (which is the javascript version), then you should get the lower image behaving the same way. But it doesn't.
Why?
You had everything right but it seems that you weren't setting the attribute on the DIV in a way that the browsers was recognizing. Instead of using
cmenu.contextmenu = 'menu_for_image_js';
I altered it to be:
cmenu.setAttribute('contextmenu','menu_for_image_js');
I've created a JS Fiddle that shows the change based on your example: http://jsfiddle.net/pB76y/1/
I have client sided code in the onClientLoad event of my form that governs field hiding. Problem is, it depends on values in the first tabPanel. If I switch to the second tabPanel, it stops working. I can no longer switch back to any other tabPanel.
How can I within the onClientLoad event using CSJS identify which panel I currently am on?
In a tab panel whenever you switch between tabs the fields are recalculated.
So, I would rather suggest you to put a visibility formula on field instead.
Make sure all tab panels have a nice id. Then in your script block you can add something like:
var t1 = dojo.byId("#{id:tab1}");
if (t1) { // do your stuff }
Does it work for you?