I'm working in Angular 8, jqgrid working perfectly.
Is there a way I can alter the drag and drop image when DnD between two grids?
I'm playing with:
this.jqgSource.jqGrid(
'gridDnD',
{
connectWith: this.jqgSelectorTarget,
onstart: (ev, ui) => {
$(this).html("new content here");
},
ondrop: (ev, ui, dragdata) => {
const registrationId = dragdata.registrationId;
const moveToTeamId = this.targetTeamId;
this.swapComplete(registrationId, moveToTeamId);
}
});
but no luck...
Oleg got me going.
To change the content of the dragged object
Instead of:
$(this).html("new content here")
I needed to access the ui.helper:
ui.helper.html("new content here")
Related
Hi I have to drag a component which is outside a frame and drop into a iframe body(dragable source)
but it is not draging my component into iframe dragable source
this is code which is am using for get into the iframe and it is working means it is going into the iframe and finding element
const getIframeDocument = () => {
return cy.get(".gjs-frame").its("0.contentDocument").should("exist");
};
const getIframeBody = () => {
// get the document
return (
getIframeDocument()
// automatically retries until body is loaded
.its("body")
.should("not.be.undefined")
// wraps "body" DOM element to allow
// chaining more Cypress commands, like ".find(...)"
.then(cy.wrap)
);
};
and
for drag and drop into iframe like this
getIframeBody().find("#wrapper").as("Target");
cy.get('[title="Url"]').drag("#Target");
this is not giving me any error this drag function working but at the same time drag and drop is not happening
drag and drop execution pic must see this
you can do this by using this code. You just need to change selectors according to your website.
// Define Locators.
drag_element = '.blockbuilder-content-tools .blockbuilder-content-tool:nth-
child(6)';
drop_element = '#u_body #u_row_2';
text_indentation = '[aria-label="Align center"]';
new_box_text = 'This is a new Text block. Change the text.'
// Get iframe body and then drag & drop element.
iframe_interaction(){
let ifm = cy.get('iframe');
ifm
.should(iframe => expect(iframe.contents().find('body')))
.then(iframe => cy.wrap(iframe.contents().find('body')))
.within({}, $iframe => {
cy.get(this.drag_element).drag(this.drop_element, { force: true })
cy.contains(this.new_box_text).dblclick({force: true})
cy.get(this.text_indentation).click()
})
Github Link: https://github.com/sardar-usman/Cypress--Drag-and-Drop
I have a menu item named as Transform table after clicking on it more items are shown for selection. These are all present inside an iframe. I want to click on the options available inside Transform Table, but when I am searching for the options the main pop gets closed. Please suggest some way to keep it open and the select the options in it.
const body = $iframe.contents().find('body');
let getElement = cy.wrap(body);
getElement.find(getdatasourcelocator.SearchBox).should('be.visible', { timeout: 30000 }).type(datasourceType);
getElement = cy.wrap(body);
getElement.find('.textCsv').click();
getElement = cy.wrap(body);
getElement.find(getdatasourcelocator.URL).type(entityURL);
getElement = cy.wrap(body);
getElement.find('button').contains('Next').click();
getElement = cy.wrap(body);
getElement.wait(15000);
getElement.find('button').contains('Transform table').click().then(()=>{
cy.get('button[data-automation-id="PromoteHeaders"]').should('be.visible');
cy.contains('li','Use first row as headers').should('be.visible', { timeout: 30000 }).click()
});
});
}```
Unfortunately, you cannot target elements or interact with anything in an iframe - regardless of it being the same domain or cross-domain iframe. Here is a known issue.
As workaround, you can try to use something from the comments:
Add custom command.
Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframe => {
return new Cypress.Promise(resolve => {
$iframe.on('load', () => {
resolve($iframe.contents().find('body'));
});
});
});
And use this command.
// for <iframe id="foo" src="bar.html"></iframe>
cy.get('#foo').iframe().find('.bar').should('contain', 'Success!');
I'm currently creating a 'smartobject' widget. In the widgets dialog, the user can choose a 'smartobject', which simply put, generates some html, which should be added to the editor. Here comes the tricky part: the html sometimes div elements and sometimes simply span elements. In the case of the div variant, the widget should be wrapped in a div 'template'. In the case of a span variant, the widget should be wrapped in a span and the html should be added 'inline'.
In the widgets API I see the following way to define a template:
editor.widgets.add('smartobject', {
dialog: 'smartobject',
pathName: lang.pathName,
template: '<div class="cke_smartobject"></div>', // <------
upcast: function(element) {
return element.hasClass('smartObject');
},
init: function() {
this.setData('editorHtml', this.element.getOuterHtml());
},
data: function() {
var editorHtml = this.data.editorHtml;
var newElement = new CKEDITOR.dom.element.createFromHtml(editorHtml);
newElement.copyAttributes(this.element);
this.element.setText(newElement.getText());
}
});
But in my case, the template is more dynamic: sometimes a div and sometimes the span will do the correct thing..
How can I fix this without needing to create two widgets which will do the exact same thing, with only the wrapping element as difference?
I've already tried to replace the entire element in the 'data' method, like:
newElement.replace(this.element);
this.element = newElement;
But this seemed not supported: resulted in undefined errors after calling editor.getData().
I'm using ckeditor v4.5.9
Thanks for your help!
It seems I got it working (with a workaround).
The code:
CKEDITOR.dialog.add('smartobject', this.path + 'dialogs/smartobject.js');
editor.widgets.add('smartobject', {
pathName: lang.pathName,
// This template is needed, to activate the widget logic, but does nothing.
// The entire widgets html is defined and created in the dialog.
template: '<div class="cke_smartobject"></div>',
init: function() {
var widget = this;
widget.on('doubleclick', function(evt) {
editor.execCommand('smartobject');
}, null, null, 5);
},
upcast: function(element) {
return element.hasClass('smartObject');
}
});
// Add a custom command, instead of using the default widget command,
// otherwise multiple smartobject variants (div / span / img) are not supported.
editor.addCommand('smartobject', new CKEDITOR.dialogCommand('smartobject'));
editor.ui.addButton && editor.ui.addButton('CreateSmartobject', {
label: lang.toolbar,
command: 'smartobject',
toolbar: 'insert,5',
icon: 'smartobject'
});
And in the dialog, to insert code looks like:
return {
title: lang.title,
minWidth: 300,
minHeight: 80,
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
editor.insertElement(element);
// Trigge the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
},
...etc.
UPDATE
I made the 'onOk' method a little bit better: the smartobject element is now selected after the insertion.
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
var elementId = "ckeditor-element-" + element.getUniqueId();
element.setAttribute("id", elementId);
editor.insertElement(element);
// Trigger the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
// Get the element 'fresh' by it's ID, because the setData method,
// makes the element change into a widget, and thats the element which should be selected,
// after adding.
var refreshedElement = CKEDITOR.document.getById(elementId);
var widgetWrapperElement = CKEDITOR.document.getById(elementId).getParent();
// Better safe then sorry: if the fresh element doesn't have a parent, simply select the element itself.
var elementToSelect = widgetWrapperElement != null ? widgetWrapperElement : refreshedElement;
// Normally the 'insertElement' makes sure the inserted element is selected,
// but because we call the setData method (to ensure the element is transformed to a widget)
// the selection is cleared and the cursor points to the start of the editor.
editor.getSelection().selectElement(elementToSelect);
},
So in short, I partially used the widget API for the parts I wanted:
- Make the html of the widget not editable
- Make it moveable
But I created a custom dialog command, which simply bypasses the default widget insertion, so I can entirely decide my own html structure for the widget.
All seems to work like this.
Any suggestions, to make it better are appreciated:)!
As suggested in this ckeditor forum thread, the best approach would be to set the template to include all possible content elements. Then, in the data function, remove the unnecessary parts according to your specific logic.
I used below code to add toolbar buttons automatically in navigation toolbar below Firefox Australis.
var buttonId = "toolbarbutton-toolbarbutton";
var navBar = document.getElementById("nav-bar");
var currentSet = navBar.currentSet;
var curSet = currentSet.split(",");
if (curSet.indexOf(buttonId) == -1)
{
navBar.insertItem(buttonId);
navBar.setAttribute("currentset", navBar.currentSet);
document.persist("nav-bar", "currentset");
try
{
top.BrowserToolboxCustomizeDone(true);
}
catch (e)
{
}
}
Because user interface and modules changed for Australis, the code needs to be updated. How can I add Toolbar Button for Australis proper way?
You have to use the CustomizableUI module:
try
{
Components.utils.import("resource:///modules/CustomizableUI.jsm");
CustomizableUI.createWidget({
id: "toolbarbutton-toolbarbutton",
defaultArea: "nav-bar",
removable: true,
label: "My button",
tooltiptext: "My tooltip text",
onClick: function()
{
alert("Clicked");
}
});
}
catch (e)
{
Components.utils.reportError(e);
// No such module? Try the old approach.
...
}
Note that the widget no longer needs to be added for each browser window, it is enough to do it once. Unfortunately, the module documentation is practically non-existent right now, the code above has been deduced from module's source code. The documentation should improve soon however.
If it helps, Adblock Plus source code contains an emulation of the CustomizableUI API for older Firefox versions. This one is far from complete however, it is only meant to cover the needs of Adblock Plus.
I'm building a simple dialog plugin to replace the default link tool. The design calls for a particular layout that is difficult to achieve with the CKEdit dialog definition: We want a single field to appear above the tab elements in the dialog (see illustration).
Can anyone suggest a way that this might be implemented? Thanks!
As far as I can tell it is not possible to achieve this using the built-in dialog definition.
I was able to get around this limitation by building my dialog plugin using the iframedialog plugin. This basically pops up a CKEditor dialog window and loads an external URL into it. You can do anything you want in that iframe, and then return the text to CKEditor when the user presses the OK button.
A simple example:
// plugins/iframelink/plugin.js
CKEDITOR.plugins.add('iframelink', {
requires: ['iframedialog'],
init: function(editor){
CKEDITOR.dialog.addIframe('iframelinkDialog',
// title
'Insert a Link',
// src
this.path + 'dialogs/link.html',
// minWidth
500,
// minHeight
250,
// onContentLoad
);
var cmd = editor.addCommand('iframelink', {exec: iframelinkOnclick});
editor.ui.addButton('iframelink', {
label: 'Insert a Link (Special Link Tool)',
command: 'iframelink',
icon: this.path + 'images/world_link.png'
});
}
});
function iframelinkOnclick(editor){
dialog = editor.openDialog('msiteslinkDialog');
};
// plugins/iframelink/dialogs/iframelink.js
$(function() {
if (typeof(window.parent.CKEDITOR) != 'undefined') {
CKEDITOR = window.parent.CKEDITOR;
var dialog = CKEDITOR.dialog.getCurrent();
var editor = dialog.getParentEditor();
// Get value of the selected text:
var selection = editor.getSelection().getSelectedText();
// Do something when the user presses the OK button:
var okListener = function(ev) {
link = yourFunctionToDoSomethingClever();
this._.editor.insertHtml(link);
dialog.removeListener("ok", okListener);
};
// Bind the OK button to your okListener method:
dialog.on("ok", okListener);
};
}
So you can make the dialog look any way you want: