Hey all, so I was trying to make a portlet that ha...
# suitescript
k
Hey all, so I was trying to make a portlet that had a collapsible section (think a button that toggles whether a div is hidden or not), so I used inline HTML, thinking I'd be able to inline some vanilla javascript that would be able to attach a click handler, change the display properties etc of the divs I was inlining - but this approach did not work for me for some reason. The inline javascript that I included in the portlet would be triggered (so I could
console.log
etc) but for whatever reason I could not get any click events to fire. Is what I'm trying to do possible? Or am I just attacking it incorrectly? Thanks for any help!
l
I remember trying this years ago... I think NS was manipulating the DOM contents. So any events you fired ended up attached to the wrong element.
Try attaching your handler to the element after a 500ms delay. I think that's how I got around it.
k
thanks 🙂
I'll try that
yeah ok, same thing's happening to me as when I tried a 250ms delay - nothing in
setTimeout
ever fires, even with a long (5s+) delay
j
can you share your code
k
Copy code
console.log($(".order-info-minimize-ship"));
console.log($(".order-info-minimize-unship"));

setTimeout(function() {
    console.log("we survived the timeout!");

    $(".order-info-minimize-ship").click(function() {
        if($(".shippable-order-container").css("display") === "none") {
            $(".shippable-order-container").css("display", "flex");
            $(this).text("Hide Orders");
        } else {
            $(".shippable-order-container").css("display", "none");
            $(this).text("Show Orders");
        }
    });

    $(".order-info-minimize-unship").click(function() {
        if($(".unshippable-order-container").css("display") === "none") {
            $(".unshippable-order-container").css("display", "flex");
            $(this).text("Hide Orders");
        } else {
            $(".unshippable-order-container").css("display", "none");
            $(this).text("Show Orders");
        }
    });
}, 1000);
The above is minimized and included at the end of the html that's assigned to
portlet.html
the first two lines do show up in the console, the console.log in the settimeout does not
j
I take it this script is embedded in script tags in an inline html field?
k
yeah
j
and if you inspect the html using dev tools the setTimeout code is there?
k
hmmm strange, no, it is not! and yet it console logs the first two lines....
j
🤔
z
I think you can do it by wrapping all your code in $()
Example:
<script>jQuery(function($){require([], function(){" + jsCodeAsString + ";})})</script>
k
@zach_calh hmm not sure I understand what's going on there, but running this causes nothing in my
jsCodeAsString
to show up, even the first console.log
Copy code
'<script>$(function($){require([], function(){console.log("I swear I am not crazy...");setTimeout(function(){console.log("we survived the timeout!"); $(".order-info-minimize-ship").click(function(){if($(".shippable-order-container").css("display")==="none"){$(".shippable-order-container").css("display", "flex"); $(this).text("Hide Orders");}else{$(".shippable-order-container").css("display", "none"); $(this).text("Show Orders");}}); $(".order-info-minimize-unship").click(function(){if($(".unshippable-order-container").css("display")==="none"){$(".unshippable-order-container").css("display", "flex"); $(this).text("Hide Orders");}else{$(".unshippable-order-container").css("display", "none"); $(this).text("Show Orders");}});}, 1000);})})();</script>'
(on the line above I put
$ = jQuery
)
j
$(your function)
runs your function once the entire html document has been parsed if you can get the script into your html document and it's not working, it's probably simpler to drop jquery and just use vanilla event handlers (especially isnce you are just toggling a css value)
k
the jquery was a hail mary after my vanilla js wasn't working 😕
j
😟
Copy code
<script>
function toggleShippableOrderContainer(div) {
  var container = document.querySelector('.shippable-order-container');
  var isDisplay = getComputedStyle(container).display === 'flex';
  container.style.display = isDisplay ? 'none' : 'flex';
  div.textContent = isDisplay ? 'Hide Orders' : 'Show Orders';
}
</script>
<div class=".order-info-minimize-ship" onclick="toggleShippableOrderContainer(this);">
...
something like that ought to work. if not then it might be a problem for a another day lol ¯\_(ツ)_/¯
z
test-portlet.js
that’s a functional example above
of course, you don’t need the <p> element — i just wanted to know that the html parsed!
k
interesting, you add it to a field, I could see that working - I'll have to give that a try in a bit 🙂
z
Ahh that’s what i thought you were doing! Do you have the portlet set up as a simple form or as html? This approach only works if set up as a simple form
k
as html
so you use the
portlet.defaultValue
as a sort of pseudo-html field?
interesting
j
I thought you had it set up as a form with an inline html field too lol
z
it isn’t a pseudo-html field — it’s real html! But you have to make sure it gets run after the page has loaded. If the goal is to have a portlet as a form but to spice it up, I recommend adding the inline-html field.
also just realized that i sent you a buggy version of my code…
1 sec
test-portlet.js
i didn’t save the file i quickly created before sharing — you create an inline html field then do
field.defaultValue
to set the html
k
woohoo, I got it to work, thanks all 🙂