Untick Include Annotation Checkbox by default in PDFTron PrintModal - javascript

As per my knowledge, there is no explicit properties given in pdftron to untick Include Annotation Checkbox which is checked by default.
You can go to https://www.pdftron.com/webviewer/demo/ and see the print modal by pressing ctrl+P:
So I am looking for work around in javascript, to make it disaable, having id "include-annotations". The issue is when the code runs, dom object is 'NULL', then after some time that same code works on console.
How to make this trigger when print modal dom gets loaded.
document.addEventListener("keydown", (e) => {
if (e.ctrlKey && e.code === "KeyP") {
const annotationUncheck = document.getElementById(
"include-annotations"
) as HTMLElement;
annotationUncheck.click();
}
});

The reason why document.getElementById("include-annotations") is coming up as null, is because Webviewer runs inside an iframe and its components will not be part of the main DOM. To get the checkbox from inside the iFrame and uncheck it, you can use this code:
WebViewer({...}, viewerElement).then(function (instance) {
const { UI } = instance;
UI.iframeWindow.document.getElementById("include-annotations").click();
});
Here is the relevant API for getting the iFrame window.
https://www.pdftron.com/api/web/UI.html#.iframeWindow

Related

my sapUI5 app only jumps once into my print method

this is my very first question on Stackoverflow. I am currently developing a print function in my sap ui5 app to print out certain UI controls. I've got the function from here: http://embed.plnkr.co/jjyEPa1updkjBiNZqumS/preview
However, during runtime, when I click on the print button, my app only jumps to the method once and executes it correctly (to print). But after that, I can press the printbutton as often as I want, nothing happens and I can't find out why.
what the method does: i replace the body with a temporary body, which only contains the elements to be printed and execute window.print(). afterwards i insert the original body content again. Of course I use the UI controls to grab the HTML tags.
onPrintChart: function(oEvent){
var oTarget = this.getView(),
sTargetId = oEvent.getSource().data("targetId");
if (sTargetId) {
oTarget = oTarget.byId(sTargetId);
}
if (oTarget) {
var $domTarget = oTarget.$()[0],
sTargetContent = $domTarget.innerHTML,
sOriginalContent = $(document.body)[0].innerHTML;
$(document.body)[0].innerHTML = sTargetContent;
window.print();
$(document.body)[0].innerHTML = sOriginalContent;
} else {
jQuery.sap.log.error("onPrint needs a valid target container [view|data:targetId=\"SID\"]");
}
}
I managed to do it in a different, more elegant way without using a temporary body. I used CSS to hide all irrelevant elements (display: none) and keep only the relevant element for printing.
Apparently ui5 hung up when replacing the original body temporarily with another body. I noticed that ALL buttons didn't work anymore, not only the print button.

tinyMCE-Angular and the code plugin - binding to events in modal

Angular 7, using tinyMCE-angular, and we've configured it to use the 'code' plugin. That plugin (in our case) inserts a button [< >] into the tinymce toolbar.
When you click that button, a modal opens.
The problem I have is that we have an (onKeyUp) event triggering when the content of the main tinymce editor is edited--but it doesn't trigger when the code modal is used, because that modal inserts content without using an (onKeyUp) event.
The HTML:
<editor [init]="tinyMceSettings" apiKey="{{tinyMceApiKey}}" id="_featureTabContent" [(ngModel)]="marketPlaceModel.featureContent"
(onKeyUp)="onEditorKeyUp('Features_Tab')"></editor>
The Component code, which is enabling a 'Preview' button below the tinymce editor to either be enabled or disabled.
onEditorKeyUp(str) {
if (this.marketPlaceModel.featureContent != null && this.marketPlaceModel.featureContent.length != 0) {
this.disablePreviewBtns.featuresbtn = false;
this.marketPlaceModel.featureTabValVisbile = false;
}
else {
this.disablePreviewBtns.featuresbtn = true;
this.marketPlaceModel.featureTabValVisbile = true;
}
tinyMCE has event triggers (https://github.com/tinymce/tinymce-angular#event-binding), I'm assuming I can use those events somehow (like we're using the onKeyUp event currently) to trigger the same onEditorKeyUp() event, but I can't seem to get that to work.
Is there some way to do this that is built into the tinymce editor already, and I'm just missing it?
OK so we ended up fixing this, doing the following:
<editor [init]="tinyMceSettings" apiKey="{{tinyMceApiKey}}" id="_featureTabContent" [(ngModel)]="marketPlaceModel.featureContent"
(onKeyUp)="onEditorKeyUp('Features_Tab')" (onDirty)="onEditorKeyUp('Features_Tab')"></editor>
Adding the onDirty call successfully updates the button when the class is changed from ng-pristine to ng-dirty. However, if you then remove all of the content, it does not re-update the field until the button is clicked. To fix that, we updated the method:
onEditorKeyUp(str) {
if (this.marketPlaceModel.featureContent != null && this.marketPlaceModel.featureContent.length != 0) {
this.ref.detectChanges();
this.disablePreviewBtns.featuresbtn = false;
this.marketPlaceModel.featureTabValVisbile = false;
}
else {
this.disablePreviewBtns.featuresbtn = true;
this.marketPlaceModel.featureTabValVisbile = true;
}
That fixed the issue for us.

Getting element by id in DOM

I'm creating an element and then want to add an event listener to it. I'm doing:
console.log('about to create modal');
this.createModal(
'There are unsubmitted changes in this Access Request.',
'Do you wish to discard them?',
'Yes',
'No',
'tabCloseModal'
);
console.log('created modal');
const modal = this.shadowRoot.querySelector('#tabCloseModal');
console.log(`modal = ${modal}`);
modal.addEventListener('px-modal-accepted', function(e) {
console.log('removing tab');
this.removeTab(index);
});
Where createModal creates an element:
createModal(headerText, bodyText, acceptText, rejectText, id, opened = true) {
const modal = document.createElement('px-modal');
//assign parameters
document.swQuerySelector('body').appendChild(modal);
console.log('Child appended');
modal.visible = true;
this.fire('modal-visible');
}
No matter what I do (I tired swQuerySelector, swQuerySelectorAll, querySelector, querySelectorAll), I can't seem to get a hold of the modal. When I log it it just shows up as either empty, undefined or [object Object] or something like that, and I never get to 'removing tab'. What am I missing? The modal is showing up, but the mapping of the accepted event listener does not work.
To solve this:
Return the modal from createModal, and confirm it works as expected in the calling code.
If it does, the problem is in your this.shadowRoot.querySelector line. Set a breakpoint at that point and try some paths to querySelector in the devtools command line until you get your modal. Try to find the modal in your devtools elements window to see where it lies. Without seeing a layout of your DOM, we cannot suggest the the exact path to the parent element.
The Shadow DOM can get 'shady' at times...

manual click event only triggers on second click

I build a small color-picker module. But it only opens up (and then works) when pickColor is called a second time. I also tried to wrap the _openColorPicker into a setTimeout but that didn't work either. In fact, the color-picker didn't show up at all when I did that.
What I found interesting is that the binding to the change event works, so the $ selector must have found the element already.
So I have two questions:
1) why is the picker only showing after the second call to _openColorPicker?
2) why didn't the picker open at all when I wrapper the _openColorPicker call in a setTimeout?
Edit: The _openColorPicker functions gets executed after the user has right-clicked into the document and then clicked on context-menu which is now showing.
Complete Code:
const ColorUtils = {
_initialized: false,
_openColorPicker: function () {
$('#color-picker').click();
},
pickColor: function (onChangeCallback, context) {
if (!this._initialized) {
$('<input/>').attr({
type: 'color',
id: 'color-picker',
display: 'hidden',
value: '#ffffff'
}).appendTo('#centralRow');
this._initialized = true;
$('#color-picker').on('change', onChangeCallback.bind(context));
}
this._openColorPicker();
// version with timeOut
const scope = this;
setTimeout(function () {
scope._openColorPicker();
}, 1000);
}
};
export default ColorUtils;
Above code is used like ColorUtils.pickColor(onColorPicked, this);
Check out this post. Looks like you can't trigger a click on an invisible color picker. That answer suggests giving the element an absolute position and placing it off screen, like so:
position:absolute;
left:-9999px;
top:-9999px;
I tried to replicate your case (for what I understood) : JSFIddle
I made some changes.
I moved the $('<input/>') in a property of the object ColorUtils and appended it to the DOM with absolute position and outside the screen.
(And also commented display:'hidden' because it's either display:none or visibility:hidden and as a CSS property, not Html attribute)
On right clic on the document I instantiate the picker (and register the callback + context) then add a button to the DOM to trigger the picker again.
Does it fulfill your requirements ?

Magento WYSIWYG editor error: Target element not found for content update

I added editor to widget. I used solution described in this answer. Everything works fine excepting inserting image to editor where widget is inserted.
When I open widget and save it or close it, I can not insert image into original editor because it lost reference. I get error "Target element not found for content update" when I try to insert image.
I checked browser.js and checked value for this.targetElementId inside getTargetElement function. It has value of closed widget editor and not original active editor. I tried to change this value just to see if this would solve the problem:
getTargetElement: function() {
this.targetElementId = 'myeditor_content';
if (typeof(tinyMCE) != 'undefined' && tinyMCE.get(this.targetElementId)) {
if ((opener = this.getMediaBrowserOpener())) {
var targetElementId = tinyMceEditors.get(this.targetElementId).getMediaBrowserTargetElementId();
return opener.document.getElementById(targetElementId);
} else {
return null;
}
} else {
return document.getElementById(this.targetElementId);
}
},
but then other errors shows up in console.
TypeError: tinyMceEditors.get(...).getMediaBrowserOpener(...) is null
Is there any easy way to somehow destroy reference to old editor (editor from widget which was closed)?
Try to add editor handle to layout.
For example:
<default>
<update handle="editor"/>
</default>

Categories