I'm using Element UI's split-button which renders an extra button which is not in the template. However, I can get access to the button in question by setting ref="dropdown" on the dropdown holding this button, and referring to it with this.$refs.dropdown.$children, and finally loop over the $children array. Now, I want to set the HTML attribute disabled on this button but I can't seem to find a straightforward way to do this in the Vue docs.
How do I go about setting attributes on references?
You could use vm.$el to get the underlying Element, and then use Element.querySelector to select the dropdown's caret button. With the button reference, you could then use Element.setAttribute('disabled', '') to add the disabled attribute, and Element.removeAttribute('disabled') to remove it:
const btn = this.$refs.dropdown.$el.querySelector('.el-dropdown__caret-button');
if (enabled) {
btn.removeAttribute('disabled');
} else {
btn.setAttribute('disabled', '');
}
demo
Related
I have two editors on the screen, one read-only. What I want to do is allow the user to select content from the read-only editor and paste it into the current position of the other by clicking a button. (the logic may manipulate the text which is one reason I don't want to use the system's clipboard.)
So far I have the function that is able to paste the text like as follows. (I am using the Angular wrapper which explains the presence of the CKEditorComponent reference.
doPaste(pasteEvent: PasteEvent, editorComponent: CKEditorComponent) {
const editor = editorComponent.editorInstance;
editor.model.change(writer => {
writer.insertText(pasteEvent.text, editor.model.document.selection.getFirstPosition() );
});
}
What I can't find from the documentation is how to extract the selected text. What I have so far is:
clickPasteSelectedPlain(editorComponent: CKEditorComponent) {
const editor = editorComponent.editorInstance;
const selection = editor.model.document.selection;
console.log('clickPasteAll selection', selection);
console.log('clickPasteAll selectedcontent', editor.model.document.getSelectedContent);
}
The selection appears to change depending on what is selected in the editor's view. The getSelectedContent function is undefined. How do I get the content?
With a bit of poking around I figured out how to do this. I'll document it here on the chance that it will help someone down the road avoid the process of discovery that I went through.
On the source document I have a ckeditor element like this:
<div *ngIf="document">
<ckeditor #ckEditor
[editor]="Editor" [config]="ckconfig" [disabled]="true"
[(ngModel)]="document.text"></ckeditor>
<button mat-flat-button (click)="clickPasteSelectedPlain(ckEditor)">Paste Selected Text Plain</button>
</div>
In the component the function called on the click event is like this:
#Output() paste = new EventEmitter<PasteEvent>();
...
clickPasteSelectedPlain(editorComponent: CKEditorComponent) {
const editor = editorComponent.editorInstance;
this.paste.emit({
content: editor.model.getSelectedContent(editor.model.document.selection),
obj: this.document,
quote: false
});
}
The PasteEvent is defined as an exported interface which I will omit here to save space. The content key will refer to a DocumentFragment.
Note that I am passing the CKEditorComponent as a parameter. You could also access it via an Angular #ViewChild declaration but note that my ckeditor is inside an *ngIf structure. I think that works well in Angular 6 but in the past I have had difficulty with #ViewChild references when the target was conditionally in the DOM. This method always works but use whatever method you want.
The event fired by the emit is processed with a method that looks like this:
doPaste(pasteEvent: PasteEvent, editorComponent: CKEditorComponent) {
const editor = editorComponent.editorInstance;
editor.model.insertContent(pasteEvent.content);
}
Because the content is a DocumentFragment the paste operation will include all formatting and text attributes contained in the selected source. But that's all there is to it.
how do I find out if my custom widget has focus in Dojo?
i have dojo editor i wnat to know if the editor has already focus or not?
you can use the module dijit/focus to find out the focus
FROM DOJO DOCS
Tracking active widgets
At any point in time there is a set of (for lack of a better word)
“active” or “focused” widgets, meaning the currently focused widget
and that widget’s ancestors. “Ancestor” can mean either DOM ancestor
(ex: TextBox –> Form), or a logical parent-child relationship (ex:
TooltipDialog –> DropDownButton).
For example, if focus is on a TextBox inside a TabContainer inside a
TooltipDialog triggered by a DropDownButton, the stack would be
TextBox –> ContentPane –> TabContainer –> TooltipDialog –>
DropDownButton.
The activeStack[] parameter indicates this set of widgets, and an app
can monitor changes to activeStack[] by:
require([ "dijit/focus" ], function(focusUtil){
focusUtil.watch("activeStack", function(name, oldValue, newValue){
console.log("Focused widget + ancestors: ", newValue.join(", "));
});
});
the question in title has a different answer than the one in the descriptions.
there are two ways achieving the question in the title, by using dojo's focusUtil ("dijit/focus"). both ways give you something that you could find the widget using it and the dijit's registry ("dijit/registry").
focusUtil.curNode: gives you the DOM Node that currently has the focus. the function below, you could get the widget reference.
function getWidgetByNode(node){
var result;
while (!result && node){
result = registry.byNode(node);
if (node.parentElement)
node = node.parentElement;
else
node = null;
}
return result;
}
var focusedWidget = getWidgetByNode(focusUtil.curNode)
focusUtil.activeStack: gives you an array of the widgets (parent to child) that has the focus. so the last item in the array is the direct widget which has the focus. index values are widget ids, so you should get the widget by the following code
var focusedWidgetId = focusUtil.activeStack[focusUtil.activeStack.length-1];
var focusedWidget = registry.byId(focusedWidgetId);
now if you want to know if the currently focused widget is some specific one, it depends on what you have in hands from that specific widget:
widget itself: like the return values of above samples. now you have to compare if these are the same thing. you can not compare two widget objects using the == operator. you could compare their ids like this:
myWidget.id == focusedWidget.id
widget's id: this way you just easily get the id of the current node from focusUtil and compare it with the id you have liek this:
myWidgetId == focusedWidgetId
references:
http://dojotoolkit.org/reference-guide/1.9/dijit/focus.html
http://dojotoolkit.org/reference-guide/1.9/dijit/registry.html
require([ "dijit/focus" ], function(focusUtil){
var activeElement = focusUtil.curNode; // returns null if there is no focused element
});
check blow url here you can see some examples
http://dojotoolkit.org/reference-guide/1.8/dijit/focus.html#dijit-focus
a) For dojo 1.6: call dijit.getFocus(). This will return an object containing the currently focused dom node, among other things (selected text, etc.). To get the corresponding widget, simply do:
var activeElement = dijit.getEnclosingWidget(dijit.getFocus().node);
This is the full reference for dijit.getFocus(), from the source code:
// summary:
// Called as getFocus(), this returns an Object showing the current focus
// and selected text.
//
// Called as getFocus(widget), where widget is a (widget representing) a button
// that was just pressed, it returns where focus was before that button
// was pressed. (Pressing the button may have either shifted focus to the button,
// or removed focus altogether.) In this case the selected text is not returned,
// since it can't be accurately determined.
//
// menu: dijit._Widget or {domNode: DomNode} structure
// The button that was just pressed. If focus has disappeared or moved
// to this button, returns the previous focus. In this case the bookmark
// information is already lost, and null is returned.
//
// openedForWindow:
// iframe in which menu was opened
//
// returns:
// A handle to restore focus/selection, to be passed to `dijit.focus`.
b) For dojo 1.7 and up, use dijit/focus:
require([ "dijit/focus" ], function(focusUtil) {
var activeElement = focusUtil.curNode; // returns null if there is no focused element
});
I have a custom menubutton in my tinyMCE editor that uses specific HTML elements elsewhere on the page as the menu items. I use a jQuery selector to get the list of elements and then add one each as a menu item:
c.onRenderMenu.add(function(c,m) {
m.add({ title: 'Pick One:', 'class': 'mceMenuItemTitle' }).setDisabled(1);
$('span[data-menuitem]').each(function() {
var val = $(this).html();
m.add({
title: $(this).attr("data-menuitem"),
onclick: function () { tinyMCE.activeEditor.execCommand('mceInsertContent', false, val) }
});
});
});
My problem is that this only happens once when the button is first clicked and the menu is first rendered. The HTML elements on the current page will change occasionally based on user clicks and some AJAX, so I need this selector code to run each time the menu is rendered to make sure the menu is fully up-to-date. Is that possible?
Failing that, is it possible to dynamically update the control from the end of my AJAX call elsewhere in the page? I'm not sure how to access the menu item and to update it. Something using tinyMCE.activeEditor.controlManager...?
Thanks!
I found a solution to this problem, though I'm not sure it's the best path.
It doesn't look like I can make tinyMCE re-render the menu, so instead I've added some code at the end of my AJAX call: after it has updated the DOM then it manually updates the tinymce drop menu.
The menu object is accessible using:
tinyMCE.activeEditor.controlManager.get('editor_mybutton_menu')
where mybutton is the name of my custom control. My quick-and-dirty solution is to call removeAll() on this menu object (to remove all the current menu items) and then to re-execute my selector code to find the matching elements in the (new) DOM and to add the menu items back based on the new state.
It seems to work just fine, though tweaks & ideas are always welcome!
Let's say in a view I have a DojoX Mobile ListItem that is pulling an HTML view fragment into the DOM via AJAX and then transitioning to that view. Assume this is all working fine.
Now, I go back to the initial view that had that ListItem on it and click some other button that destroys that view node from the DOM. If I now click on that ListItem that previously loaded that view node into the DOM (which has now been removed), it will try to transition to a view that doesn't exist. It doesn't know that it has been removed.
Is there some type of way to tell a ListItem that it needs to fetch the HTML again because what was previously fetched no longer exists? I am not seeing anything about doing this in any documentation anywhere. I don't think a code sample is really necessary here, but I can provide a minimal one if necessary.
I went a different route and left the view exist in the DOM, and simply made a function that clears all sensitive data out of the view.
Okay, in this case, i guess you could hook the onShow function of your ListItem container(or any other onchange event). Create a listener for said handle to evaluate if your item needs reloading. Following is under the assumtion that it is the item.onclick contents showing - and not the label of your item which contains these informations
Or better yet, do all this during initialization so that your ListItem container will be an extended with custom onClick code.
Seems simple but may introduce some quirks, where/when/if you programatically change to this item, however here goes:
function checkItem() {
// figure out if DOM is present and if it should be
if( isLoggedIn() ) {
this.getChildren().forEach(function(listitem) {
if( dojo.query("#ID_TO_LOOK_FOR", listitem.domNode).length == 0 ) {
// this references the listItem, refresh contents.
// Note: this expects the listitem to be stateful, have no testing environment at time being but it should be
listitem.set("url", listitem.url);
}
});
}
}
Preferably, set this in your construct of the container for your ListItems
var listItemParent = new dojox.mobile.RoundRectList({
onShow : checkItem,
...
});
Or create listener
var listItemParent = dijit.byId('itemRegistryId');
// override onClick - calling inheritance chain once done
dojo.connect(listItemParent, "onClick", listItemParent, checkItem);
I've created a dijit.TooltipDialog and everything works as it should. However, if another dialog is produced from within the tooltip dialog it shows up behind the tooltip dialog instead of on top of it. I checked the zIndex on the 2 dialogs and the tooltip dialog is 1000 and the other dialog is 950.
I've tried setting the zIndex on the respective container node and the tooltip dialog's "domNode" both with no luck. So does anyone know how to set the zIndex on the tooltip dialog?
as you will find if you inspect the dom after creating a programmatic tooltip - the tooltip is placed in an overlay container beneath <body>.
As mentioned, seek alternative methods for this.. But the answer is as follows; For you to successfully set a z-index you must find the correct node - which is not the domNode since the dialog has a 'layer' of its own via the dijit.popup design.
Here's the fiddle for it: http://jsfiddle.net/rQHSP/
In short, this is what you could do.
myDialog.onShow = function() {
node = this.domNode
// loop upwards untill we hit a wall or nodes class mathes popup
while (node
&& (!node.className || !node.className.match("dijitTooltipDialogPopup")))
node = node.parentNode
console.log(dojo.style(node, "zIndex")
}
Following mschr's answer I couldn't find the underlayAttrs property of dijit.TooltipDialog. But that did lead me to finding _popupWrapper which is the wrapper node of the entire popup. This node had a zIndex of 1000. The below code corrected the issue:
var dij = dijit.byId(dojo.query("[id*='_TooltipDialog_']")[0].id);
dij.onShow = function() {
dojo.style(dij._popupWrapper,"zIndex",900);
}