Custom Component Not Running

Hi there. I have created a custom component which creates a PDF, and opens it in the browser. This is all working fine when I am editing the app, but when I use the preview (or log in as a user), the custom component does not seem to be running. These are the switches that I have set

Any help or thoughts would be much appreciated

Update: So after some more testing, it seems that if the custom component is hidden, then it will not work in the viewer mode. Is this expected behaviour?

Thanks

Adam

1 Like

Hello Adam,

Thank you for bringing this to our attention! I think in order to get a handle on exactly what's triggering this custom component and how it works we would have to see the app or the full code of the custom component. Would you be able to share that? Are you basically saying that when you had the component hidden it wasn't generating any PDFs in preview, but when it was visible it was working as expected?

If you want to write into support using the bottom right "?" icon we could take a look!

John

Bumping this as I've just come across the same issue.

I have a custom component with no visual element, it's just javascript - if I set the component to hidden then it doesn't run at all in preview mode, only edit mode.

Hey @dcartlidge!

Thanks for bumping this, as you mentioned, it doesn't look like this is possible at the moment.

Would you mind describing a bit more of your use case? What functionality are you using that's available in custom component JS but not JS queries?

For completeness - using 'Maintain space when hidden' allows for code to be run while the component is hidden. That doesn't do anything for your case or cases that need to collapse the component but just want to post it here in case it is useful for someone.

Initially I was loading in some external libraries to handle websocket connections and at that stage there was no visual elements, I was just surprised when I previewed it that no connections were being made.
I've now changed this to use a global window object to handle the connections and using standard components to visualise the messages/channel members/presence etc

what component are you using to generate pdf? im looking for this too :slight_smile: to create good looking pdf from data to generate reports

Got it, thanks for that context @dcartlidge!

@agaitan026 if you haven't seen it already there's a great blog post mentioned here that has a bunch of info about creating PDFs. Also curious to know what @turps808 is using, but barring that it might be a good place to start!

2 Likes

yeah thats why im asking, maybe hes using a new way :stuck_out_tongue: as current alternatives are mostly paid, will be nice to see some solution for good looking pdf

Hi @Kabirdas

I am using a custom component displayed in a modal to create a Delivery Note that can be printed as a PDF. The code I have in the iFrame field is:

<style>
      /* Base CSS styles DO NOT CHANGE OR REMOVE */
      body {
        margin: 0;
        padding: 0;
        font:62.5%/1.5 Helvetica, Arial, Verdana, sans-serif;  
      }

      ul, ul li, p, div, ol {
        margin:0;
        padding:0;
        list-style:none;
      }

      #delivery-note {
         margin: 0 12pt;
         width:660px;
        padding: 10px 20px;
         margin: 1em auto;
        clear:both;
        position:relative;
        overflow:hidden;
         background:#fff
      }

      #delivery-note.cancelled {
        background: #fff url(/images/cancelled.gif) top left
      }

      /*Delivery Note Template*/
      /*=========================== TYPOGRAPHY =========================*/
      #delivery-note{
        font-family: Helvetica, Arial, Verdana, sans-serif !important 
      }

      #delivery-note h2 {
        margin: 10px 0;
        font-size: 14pt;
      }

      #delivery-note-parts td, th {
        font-size: 9pt;
      }

      #delivery-note-header #company-address {
        text-align: left;
        font-size: 11pt;
        line-height: 14pt;
      }

      #delivery-note #client-details, #delivery-note-info  p, #delivery-note #delivery-note-other, #delivery-note #payment-details {
        font-size: 9pt;
         line-height: 12pt;
      }

      #delivery-note-info h2, #delivery-note-info h3 {
        margin: 0;
         font-weight: normal;
      }

      #delivery-note-info h2{
        text-transform:uppercase
      }

      #delivery-note-info h3 {
        font-size:12pt;
      }

      #comments {
        font-weight:bold;
        margin-top:15px;
        font-size:10pt
      }

      /*=========================== LAYOUT =========================*/
      #delivery-note{
        padding:0 1cm 1cm 1cm;
       }
  
      #delivery-note-header .vcard {       
        width: 80%;
        float:left;
      }

      #delivery-note-header .logo {
        width: 20%;
        float:right;
      }

      #delivery-note-header{
        margin-top:0.3cm;
        border-bottom:4px solid #000;
        padding-bottom:10px;
        overflow:hidden
      }

      #delivery-note-info{
        margin: 0.7cm 0 20px 0;
        width:250px;
        float:right;
        text-align:right
      }

      #client-details {
        margin:0.7cm 0 20px 0px;
        float:left;
        width:250px
      }

      #delivery-note-parts {
        margin: 10em 0em 5em 0em;
        clear: both;
       }
  
      #delivery-note-other {
        text-align: left;
         float: left;
        width:250px;
       }

      #comments{
        clear:both;
        padding-top:0.5cm
      }

      /*=========================== TABLES =========================*/
      #delivery-note table#delivery-note-parts {
         border-collapse:collapse;
         width:100%;
        clear:both;
      }

      #delivery-note-parts th {
        text-align: left;
        white-space: nowrap;
        padding: 1px 2px 0px 0px;
         font-weight: bold;
        background: #FFF;
        border-bottom: solid 1px #444;
       }

      #delivery-note-parts td.item_r{
        text-align: left;
      }

      #delivery-note-parts .file_name_th{
        width:40%
      }

      #delivery-note-parts .quantity_ordered_th{
        width:20%
      }

      #delivery-note-parts .quantity_shipped_th{
        width:20%
      }

      #delivery-note-parts .po_number_th{
        width:20%;
         text-align:left
      }
  
      .button {
        margin-left: 1em;
      }
</style>
<script src="https://cdn.tryretool.com/js/react.production.min.js" 
        crossorigin></script>
<script src="https://cdn.tryretool.com/js/react-dom.production.min.js" 
        crossorigin></script>
<script src="https://unpkg.com/@material-ui/core@3.9.3/umd/material-ui.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.9.3/html2pdf.bundle.min.js"></script>
<div id="react"></div>
<script type="text/babel">
  const { Input, Button } = window["material-ui"];
  const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => ( 
    <div id="delivery-note">
      <div id="delivery-note-header">
        <div class="vcard" id="company-address">
          <div class="fn org"><strong>Incremental Engineering Ltd</strong></div>
          <div class="adr">
            <div class="address1">9b Reliance Works</div>
            <div class="address2">Newpound</div>
            <div class="town">Wisborough Green</div>
            <div class="county">West Sussex</div>
            <div class="post-code">RH14 0AZ</div>            
          </div>
          <div class="email">sales@incrementalengineering.com</div>          
        </div>
        <div class="logo">
            <img src={model.company.base64logo} alt="Base64 encoded image"></img>
        </div>
      </div>

      <div id="delivery-note-info">
        <h2>Delivery Note <strong>{model.deliveryNoteID}</strong></h2>
        <h3>Shipping Date: {model.shippingDate}</h3>
      </div>

      <div class="vcard" id="client-details">
        <div class="fn">{model.customer.name}</div>
        <div class="adr">
          <div class="cust-address">{model.customer.address}</div>          
          <div class="locality">ClientCity</div>
          <div id="client-postcode"><span class="region">ClientRegion</span> <span class="postal-code">ClientZip</span></div>
        </div>
      </div>

      <table id="delivery-note-parts">
        <thead>
          <tr id="header_row">
            <th class="file_name_th">File Name</th>
            <th class="quantity_ordered_th">Quantity Ordered</th>
            <th class="quantity_shipped_th">Quantity Shipped</th>
            <th class="po_number_th">PO Number</th>
          </tr>
        </thead>

        <tbody>
          {model.partsData.map(d => (
          <tr class="item">
            <td class="item_l">{d.fileName}</td>
            <td class="item_l">{d.quantityOrdered} </td>
            <td class="item_r">{d.quantityShipped}</td>
            <td class="item_r">{d.poNumber}</td>
          </tr>))}
        </tbody>
      </table>

      <div id="delivery-note-other">
        <h2>Other Information</h2>
      </div>

      <div id="comments"></div>
        <p>{model.comments}</p>

      <div id="printing">                
        {pdfprint(model.print)}
        {modelUpdate({"print": false })}
      </div>
    </div>
);

 function pdfprint(print) {
   if (print === true){
     var opt = {
        margin:       0.5,
        filename:     "myfile.pdf",
        image:        { type: "jpeg", quality: 0.98 },
        enablelinks:   true,
        html2canvas:  { scale: 1},
        jsPDF:        { unit: "cm", orientation: "portrait" }
    };

    window.html2pdf().set(opt)
      .from(document.getElementById("react"))
      .toPdf()
      .output("bloburl")
      .then(function(pdfas) {  window.open(pdfas) } );
   }
 }
  const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent);
  ReactDOM.render(<ConnectedComponent />, document.getElementById("react"));  

</script>

and this is the code in the Model

{
  "deliveryNoteID" : "{{tblDeliveryNotes.selectedRow.data.delivery_note_id}}", 
  "company" : {
    "name": "Incremental Engineering Ltd",
    "address1": "",
    "address2" : "",
    "base64logo": "data:image/gif;base64,{{firestoreData.value.configuration.company.logo_base64}}"
  },
  "customer" : {
      "name": {{tblDeliveryNotes.selectedRow.data.company}},
      "address": {{tblDeliveryNotes.selectedRow.data.address}},
      "city" : {{tblDeliveryNotes.selectedRow.data.city}},
      "county": {{tblDeliveryNotes.selectedRow.data.country}},
      "postcode": {{tblDeliveryNotes.selectedRow.data.postcode}},
      "country": {{tblDeliveryNotes.selectedRow.data.country}}
    },
  "shippingDate" : "16/06/2022",
  "comments": "Some comments about this delivery note",
  "partsData": {{deliveryNotePartsFormatForPDF.data}},
  "output": "",
  "print" : false
}

Hope that is useful

Adam

3 Likes

That is awesome, thank you so much for sharing @turps808!

that works ?

I am running into the same issue as @turps808 . I have a custom component that generates the HTML and the PDF and then passes the base64 to the PDF component. The custom component should not be visible as it is just doing behind the scenes work.

But if the CC is hidden then it does not run and then I get no PDF.

Making it 1 U high below the PDF makes it essentially hidden. I assume when it is hidden its iFrame is not even added to the DOM and that is why nothing happens.