Getting element by id in DOM - javascript

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...

Related

Untick Include Annotation Checkbox by default in PDFTron PrintModal

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

Jquery finds no elements after click unless first alert

Using the Firefox browser console I'm trying to select an element in an i-frame. The i-frame is shown in a modal dialog which opens when I click a link.
This example code below does the following:
Click the first link on page which opens a modal dialog
Show alert
Once I close the alert, the code finds all span elements with class
Code then prints the number of span elements found.
This code works at this link:
https://www.sec.gov/edgar/search/#/q=%2522food%2520and%2520drug%2522
$('.preview-file').eq(1).trigger('click');
alert("close this alert");
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
But, when I take out the alert("close this alert"), the code no longer works. Without the alert the code does not find any span elements and prints 0 to the console.
nonworking code (returns 0):
$('.preview-file').eq(1).trigger('click');
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
Why doesn't this code work without the alert? How can I fix this?
Edit:
I tried a while loop to see if I had to wait for something to load, but it also did not work (never-ending loop).
$('.preview-file').eq(i).trigger('click');
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
while($(all).length < 1){
previewFrame = $('#ipreviewer');
all = $(previewFrame).contents().find(".sect-efts-search-match-khjdickkwg");
console.log($(all).length);
}
The iframe doesn't exist on initial page load
Here's an approach you can play with that uses setInterval() to check for existince of the iframe and items inside the iframe that for me is returning a count of four items found
const timer = setInterval(function(){
const $frme=$('#ipreviewer');
// check if frame exists
if($('#ipreviewer').length){
const $items = $frme.contents().find(".sect-efts-search-match-khjdickkwg");
// check if items found
if($items.length){
// do something with the items
console.log('Found ', $items.length, ' items');
// clear interval timer when found
clearInterval(timer)
}
}else{
console.log('Not found')
}
},100)// 1/10th second intervals
$('.preview-file').eq(1).trigger('click');

Button onClick Event Listener not working in Electron app

Background:
I am using ElectronJS to make a game and I have a class for a shop which I named Shop.
It has a method that I call 'createItemElement' which takes an object named 'item' and creates an li element to be later added to a ul element. The code for this can be found below.
class Shop {
// ...
createItemElement(item) {
// Item Container
const li = document.createElement("li");
// Title
const title = document.createElement("h3");
title.textContent = item.title;
// Info
const info = document.createElement("p");
info.textContent = `Type: ${item.type}`;
// Add to Cart
const addButton = document.createElement("button");
addButton.textContent = "Add to Cart";
addButton.onclick = () => console.log("Adding to cart!");
li.appendChild(title);
li.appendChild(info);
li.appendChild(addButton);
return li;
}
// ...
}
Problem:
Interestingly, all of the HTML is correctly rendered and everything looks as it should, but the 'onclick' event just plain does not work.
Since all of these elements are in fact being rendered, it should be safe to assume that the code is indeed being run in the renderer process.
For some reason, however, the event is not being carried over to the app.
When I click the button in the app, nothing happens.
I checked the devTools and looked at the elements individually.
As expected, all of the elements were listed out correctly in element inspector, but when I inspected that 'addButton' button, there was no 'onclick' property to be seen.
Also, there are no errors in the console whatsoever, so that's nice (sarcasm).
And I am aware that there are many seemingly similar questions asked on StackOverflow, but none of the answers that I found have helped or applied to my situation.
It is extremely confusing as to why the elements are being rendered perfectly but the event listener is not working.
The full project can be found here and the file being excerpted below can be found here.
I looked at your shop.js page, and you incorrectly camel-case the onclick event in one place, but not in another. Using the camel-cased version of onclick will yield no error and do nothing.
Won't work:
empty_cart_button.onClick = (evt) => this.emptyCart();
Works:
addButton.onclick = () => this.addToCart(item);
As I can see from you're code, you're using el.innerHTML in the shop instance .getHTML() method. this will return the inner HTML as a raw string without any event listeners, this is why you see the rendered content as expected but the click listener doesn't work.
In the sketch.js file, the toggleShop function should use appendChild so instead of:
document.querySelector("#shop-container").innerHTML = shop.getHTML();
you should do:
document.querySelector("#shop-container").appendChild(shop.getElement())
and in the Shop class add the getElement method:
getElement() {
return this.el;
}
Be sure to toggle the shop and remove the #shop-container innerHTML when you want to toggle it off.
Also, as #Andy Hoffman answered, you should set the onclick property and not the onClick.

Prevent closure in jQuery/JavaScript

I'm trying to do something that seems (to me, at least) to be a fairly easy, common thing to do.
Here's the HTML for what I've got on a web page:
<div class="allergiesDiv">
<div>
<span class="editButton">Allergies</span><br />
</div>
<span>Allergies</span>
</div>
</div>
I turn the first <span> into a jQuery button with $('.editButton').button().
(I have many of these pairs on the page.)
What I am trying to do is the following:
When the button is clicked, it loads a jQuery Dialog with the value of the span that follows it loaded into a <textarea>. (BONUS: When the dialog is loaded, I'd like the <textarea> to be focused and all text inside highlighted.)
The user is able to edit the value and then click 'OK'.
When the user clicks 'OK', the Dialog is dismissed and the new value that was entered is used to replace the old value for the span.
Here's the code I'm trying to use (this works OK in IE, but breaks in Mobile Safari and Chrome for PC):
NOTE: I've been chopping the code up some to try to get each problem isolated. I have had this working, at least in IE.
// How I get the button and bind to the click event
$('.editButton')
.button({icons: {primary:'ui-icon-pencil'} })
.click(EditClicked);
// 'Edit' button click handler
function EditClicked() {
var span = $(this).parent().next().children().first();
var text = span[0].innerText;
var dialog = $('<div>').prop('title', 'Edit: ' + $(this).text());
var textArea = $('<textarea>').css('width', '98%').prop('rows', '4').html(text);
textArea.appendTo(dialog);
var windowWidth = $(window).width();
var buttonTop = $(this).button().offset().top;
$(dialog).dialog({
modal: true,
minWidth: windowWidth / 2,
position: ['center',buttonTop],
buttons: {
'Ok' : function () {
OKClicked(span);
},
'Cancel' : function () {
$(this).dialog('close').remove();
}
}
});
textArea.focus().select();
}
// Dialog 'OK' button click handler
function OKClicked(span) {
var text = $(this).find('textarea')[0].innerText;
span.html(text);
$(this).dialog('close').remove();
}
This is currently broken when it gets to var buttonTop..., with the error message of "button is undefined". I haven't yet figured out why that is (I used to have a variable in that method named 'button', but it's gone now. Not sure if that's a caching issue.)
Other than that, can anyone see what's wrong with my process? It seems like I've got some kind of misunderstanding with closure, but I'm not yet good enough with JavaScript to understand how to get the kink out of this code.
what about
var buttonTop = $(this).offset().top;
I am not sure, that $('<div>') is properly syntax for jQuery. Try to use $('div') instead.
When you use $(this).button() - you try to call button method of $(this) object. Seems like a bug.

Jquery UI Dialog Remove Issue

Back from this issue
Multiple Dialog
I was able to solve the issue but now problem is that it removes the div so when I access that Div it give error. It gives error because when I open dialog it works fine after removing on close it gives e.rror
I don't want to removed jQuery('#divPopup') If there is only one div present. If multiple jQuery('#divPopup') are there remove() should be working fine.
jQuery('.register_button_class').live('click',function () {
var iFrameobj = createIframe('',iframeUrl);
jQuery('#divPopup').html(iFrameobj);
createDialogWithClose(url,'#bodyId');
return false;
});
Dummy Div for Dialog Popup, This get removed, when Click on Close Jquery Ui Popup.
So when I say
jQuery('#divPopup').html(iFrameobj);
It gives error.
<div id="divPopup"></div>
I'm assuming that your function:
createDialogWithClose(url, '#bodyId');
removes the div id="divPopup" each from the DOM when you close it.
I would suggest not initially including that div in your markup and change your function to create the div and append it to the DOM when it runs. Then remove like you're already doing.
jQuery('.register_button_class').live('click',function () {
var iFrameobj = createIframe('',iframeUrl);
jQuery("body").append("<div id='divPopup' />").html(iFrameobj);
createDialogWithClose(url,'#bodyId');
return false;
});
It's hard to tell what other issues you may be running into with this bit of code that you posted, however, jQuery("body").append("<div id='divPopup' />").html(iFrameobj); will create the divPopup each time the function runs. So, when you close it and it gets removed it will just get created again the next time that button is clicked.
EDIT: How to check if a Div exists -
if ($("#divPopup").length > 0){
// do something here
}
I solved like this
var length = jQuery('#divPopup').length;
if(length>1)
{
jQuery('#divPopup').dialog('destroy').remove();
}else
{
jQuery('#divPopup').dialog('destroy');
}

Categories