You are viewing limited content. For full access, please sign in.

Question

Question

Custom html Button in Collection on New Forms Designer to Preview Documents

asked on January 22, 2024

Hi,

We have used the Classic designer for all our development projects, but we have been looking at the new designer since it will solve some of our issues related to bugs being logged on the old designer (Collections and Table large lookup takes long KB: 1014497). I have been looking through many posts and it is really just the beginning. We have tried some scripts as well to see how things will work on the New Forms Designer. I think we were spoiled with all the nice documentation and code we could use for the Classic Designer.  

I have looked at this article https://doc.laserfiche.com/laserfiche.documentation/11/administration/en-us/Default.htm#../Subsystems/Forms/Content/Javascript-and-CSS/JavaScript-in-the-Forms-Designer.htm?TocPath=Forms%257CCreating%2520a%2520Form%257C_____9 to see how this works.

 

Does anyone have a reference or code how we would use the New forms designer to Preview documents either in an Iframe or open up a document to Web Client in n new tab. It would be handy to see how the reference will work on the external url vs inline. Even if you can explain, then that will be really handy please.

 

(The below are test data and not actual data, but what I would like to achieve is to open the bottom URL in a new window linked to web client.)

 

Any guidance will be greatly appreciated. 

 

Kind Regards,

Gert

0 0

Answer

APPROVED ANSWER SELECTED ANSWER
replied on January 22, 2024

You can modify a Custom HTML field using the 'content' setting in changeFieldSettings. The key here is to perform your URL generation using the index (i.e., the row number) of the field. This code should be enough to get you on track. If you are loading the IDs from a lookup, you can listen to the on change event and pass the index of the field from the event parameter, and if the IDs exist on form load, you can just use the code as is.

 

// get all urls from url column
const urls = LFForm.getFieldValues({ fieldId: 13 });
// iterate the url list
for (let i=0; i<urls.length; i++) {
  const url = urls[i];
  // set the custom html field content to the url at its row
  LFForm.changeFieldSettings({ fieldId: 12, index: i }, {
      content: `<a href="${url}" target="_blank">google</a>`
  });
}

 

2 0
replied on January 7

I will give that a try, I had seen this on an ai search but also looks like its for classic.

$(document).ready(function() {
       // Assuming your variable name is "DocumentURL"
       var documentUrl = LFForm.getFieldValues({ variableName: "DocumentURL" });
       // Set the iframe src attribute
       $('#myIframe').attr('src', documentUrl);
   });

Thanks again

0 0
replied on January 7

Ya do not use that code, you can also ignore the index property of the field identification object if your iframe isn't in a collection

0 0
replied on January 9

Hi Zachary, I have tried really hard to figure this out myself but I think I have really hit the wall now. I finally got the url to generated and am able to embed the code into an Iframe. The final problem that I have been unable to overcome is that the iframe gets placed in the text view of the Custom HTML form not the code view and subsequently does not open the dynamically created link to an entry. If I copy and paste the iframe code from the text view to the code view it does work but not the desired outcome. The Devtool errors below are clearly saying nope can't do this.

My code is listed below the errors.

I am suspecting that I need to create an entire web page to post into the text view but I certainly do not know how or why Laserfiche handles the text and code views differently or what the right way to do it would be. Hoping you can help again. If you need anything more from me including remote access please let me know.

DEvTools Output:

Start
VM8:7 set fieldchange trigger event for when the Entry_ID is available
VM8:11 set fieldchange trigger event for when the URL is available
VM8:13 Init complete
app_options.js:571 The Preferences may override manually set AppOptions; please use the "disablePreferences"-option to prevent that.
_checkDisablePreferences @ app_options.js:571Understand this warning
app.js:1559 PDF ad42f5d00b5c275d75ca0cc523bfc955 [1.3 - / -] (PDF.js: 4.9.124 [867aaf01f])
plugin.laserfichelocalhost.com:18436/GetInfo:1  Failed to load resource: net::ERR_CONNECTION_REFUSEDUnderstand this error
plugin.laserfichelocalhost.com:18435/GetInfo:1  Failed to load resource: net::ERR_CONNECTION_REFUSEDUnderstand this error
plugin.laserfichelocalhost.com:18437/GetInfo:1  Failed to load resource: net::ERR_CONNECTION_REFUSED

JavaScript:

console.log("Start");
    var fullURL = "URL";
    var iframeLink = "URL2";
// Set fieldChange trigger event for when the Entry ID is available (rule)
      console.log ("set fieldchange trigger event for when the Entry_ID is available");
        LFForm.onFieldChange(CreateURL, { variableName: "Entry_ID" });
//        var URLfinal = LFForm.getFieldValues({variableName: "edited_URL" });        
// Set fieldChange trigger event for when the URL is available (rule)
      console.log ("set fieldchange trigger event for when the URL is available");
        LFForm.onFieldChange(updateIframeSource, { variableName: "edited_URL" });
    console.log("Init complete");
// Function to create URL for document retrival
   function CreateURL(fullURL,iframeLink) {
     console.log("Create URL");
// Get the url strings and entry ID
       var URLprefx = LFForm.getFieldValues({ variableName: "Prefix_URL" });
       var URLpstfx = LFForm.getFieldValues({ variableName: "Postfix_URL" });
       var URLEntry = LFForm.getFieldValues({ variableName: "Entry_ID" });
// Concatenate the values
       fullURL = URLprefx + URLEntry + URLpstfx;
    console.log("The EntryID =",URLEntry);
      console.log("The concat URL=",fullURL);
     // Set the concatenated value in the target field   
         LFForm.setFieldValues({ variableName: "edited_URL"}, fullURL );
         iframeLink     = LFForm.getFieldValues({ variableName: "edited_URL" });
     console.log("Create Iframe URL default=", iframeLink);
     console.log ("URL created");
     
   }
// now fix it to Iframe
    function updateIframeSource(iframeLink) {
      console.log("Start iframe");
      iframeLink     = LFForm.getFieldValues({ variableName: "edited_URL" });
     console.log("Create Iframe URL after edit=", iframeLink);
    // var iframeLink = "URL3";
      console.log("Create Iframe URL=", iframeLink);     
// Define the URL you want to embed
    let iframeURL = "https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&amp;customerId=1556239797&amp;id=18447#?openmode=PDF&amp;lang=en-US";
// Create the iframe HTML code
    let iframeHTML = `&lt;iframe name="myIframe" src="${iframeURL}" height="500" width="800" title="Document Preview"&gt;&lt;/iframe&gt;`;
// Change the content of a Custom HTML field (replace 'yourFieldId' with the actual field ID)
    LFForm.changeFieldSettings(
    { fieldId: "29" }, // Replace with your field ID
    { content: iframeHTML }
);
      
      
// Set the iframe's src attribute to the new URL
//let encodedURL = encodeURIComponent("https://www.divemaster.ca");
//  let link = `&lt;a href="${encodedURL}" target="_blank"&gt;Document&lt;/a&gt;`;
  //LFForm.changeFieldSettings({ fieldId: 28 }, {
   //content: <iframe name="myIframe" src="https://www.divemaster.ca" height="500" width="800" title="Document Preview"></iframe>
//  });
 }
 

0 0
replied on January 13 Show version history

I cleaned up the code a bit, I don't see any logs for either of your onFieldChange functions. How are the fields being set? If they already exist on the form i.e., form workflow or default values, you need to run the functions on load too. 

 

console.log("Start");

const formFields = {
  // https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&customerId=1556239797&id=
  prefixUrl: { variableName: "Prefix_URL" },
  // #?openmode=PDF
  postfixUrl: { variableName: "Postfix_URL" },
  entryId: { variableName: "Entry_ID" },
  editedUrl: { variableName: "edited_URL" },
  iframeHtml: { fieldId: 29 }
}

// Function to create URL for document retrival
async function CreateURL() {
  console.log("Create URL");
  // Get the url strings and entry ID
  const URLprefx = LFForm.getFieldValues(formFields.prefixUrl);
  const URLpstfx = LFForm.getFieldValues(formFields.postfixUrl);
  const URLEntry = LFForm.getFieldValues(formFields.entryId);
  // Concatenate the values
  const fullURL = URLprefx + URLEntry + URLpstfx;
  console.log("The EntryID =", URLEntry);
  console.log("The concat URL=", fullURL);
  if (URLEntry === "") {
    console.log("Entry ID is empty, clearing edited_URL field");
    await LFForm.setFieldValues(formFields.editedUrl, "");
    return;
  }
  // Set the concatenated value in the target field
  await LFForm.setFieldValues(formFields.editedUrl, fullURL);
  const iframeLink = LFForm.getFieldValues(formFields.editedUrl);
  console.log("Create Iframe URL default=", iframeLink);
  console.log("URL created");

}
// now fix it to Iframe
async function updateIframeSource() {
  console.log("Start iframe");
  const iframeLink = LFForm.getFieldValues(formFields.editedUrl);
  if (iframeLink === "") {
    console.log("Iframe URL is empty, clearing iframe field");
    await LFForm.changeFieldSettings(
      formFields.iframeHtml,
      { content: "<p>Select an entry id to continue</p>" }
    );
    return;
  }
  console.log("Create Iframe URL after edit=", iframeLink);
  // var iframeLink = "URL3";
  console.log("Create Iframe URL=", iframeLink);
  // Define the URL you want to embed
  let iframeURL = iframeLink;
  // "https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&amp;customerId=1556239797&amp;id=18447#?openmode=PDF";
  // Create the iframe HTML code
  let iframeHTML = `<iframe name="myIframe" src="${iframeURL}" height="500" width="800" title="Document Preview"></iframe>`;
  // Change the content of a Custom HTML field (replace 'yourFieldId' with the actual field ID)
  await LFForm.changeFieldSettings(
    formFields.iframeHtml,
    { content: iframeHTML }
  );

}

// Set fieldChange trigger event for when the Entry ID is available (rule)
console.log("set fieldchange trigger event for when the Entry_ID is available");
LFForm.onFieldChange(CreateURL, formFields.entryId);
// Run function on load
CreateURL()

// Set fieldChange trigger event for when the URL is available (rule)
console.log("set fieldchange trigger event for when the URL is available");
LFForm.onFieldChange(updateIframeSource, formFields.editedUrl);
// Run function on load
updateIframeSource()

 

0 0
replied on January 13

Thanks for this, I see that you have formatted functions before runtime code is that a preference or a necessity. More importantly you have added async and await instructions as well as forcing "Run Functions". in the long run I need to know more but in the short term those code changes have not changed the outcome. It seems like the code has some "issues" now and am looking at them.

The attachment shows the before and after console logs

The before logs shows the java running via the console.log commands the after logs looks like its not running at all.

Thanks for taking the time for me on this.

 

0 0
replied on January 13

I updated the original code in my last post, I accidentally kept your function parameters. They aren't needed since you aren't explicitly invoking the functions and instead getting the field values within each function.

I see that you have formatted functions before runtime code is that a preference or a necessity

More of a preference, I prefer defining helper functions/business logic first and then consolidating the "onload" functionality at the bottom. Function declarations get hoisted by the JS engine, but being explicit about ordering helps readability.

You have added async and await instructions as well as forcing "Run Functions"

Async/await is important to always include so you understand the order of operations. For example in "CreateURL" you are setting the edited url field and then getting it again right after (not necessary in this function but I kept it for you). In the getFieldValues right after setFieldValues the value won't exist because you didn't "await" the set operation.

I forced each function to run on load to handle cases of default values (set in the form designer or set via WF/prior tasks). Default values don't fire change events so there is nothing to listen to. If it loads an empty iframe because nothing exists you can either comment out the code or conditionally render the iframe when an entry id exists. I personally prefer the latter since it is more flexible/reusable code.

0 0
replied on January 13 Show version history

sorry did not answer your question " I don't see any logs for either of your onFieldChange functions. How are the fields being set? "

The field change happens in the form as a result of table lookup rules.

As a summary user enters text in a field to initiate a first search, other fields are populated accordingly with results that provides the user on the same form with the opportunity to choose a result from a dropdown. That decision triggers the createURL function. The createURL function changes field "edited_URL" That action triggers the updateiframe function.

0 0
replied on January 13

Well I got it running now, but the errors are bit more scary ;)

VM8:3 Start
VM8:46 set fieldchange trigger event for when the Entry_ID is available
VM8:9 Create URL
VM8:16 The EntryID = 
VM8:17 The concat URL= https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&customerId=1556239797&id=#?openmode=PDF&lang=en-US
VM8:52 set fieldchange trigger event for when the URL is available
VM8:27 Start iframe
VM8:28 Uncaught (in promise) TypeError: Assignment to constant variable.
    at updateIframeSource (eval at window.init (about:srcdoc:18:35), <anonymous>:28:14)
    at eval (eval at window.init (about:srcdoc:18:35), <anonymous>:55:1)
    at window.init (about:srcdoc:22:65)
VM8:27 Start iframe
VM8:21 Create Iframe URL default= https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&customerId=1556239797&id=#?openmode=PDF&lang=en-US
VM8:22 URL created
VM8:28 Uncaught (in promise) TypeError: Assignment to constant variable.
    at Object.updateIframeSource [as handler] (eval at window.init (about:srcdoc:18:35), <anonymous>:28:14)
    at about:srcdoc:33:2309
    at Array.some (<anonymous>)
    at about:srcdoc:33:2263
    at Array.forEach (<anonymous>)
    at about:srcdoc:33:2182
    at Array.forEach (<anonymous>)
    at window.handleEvent (about:srcdoc:33:2126)
    at about:srcdoc:33:2489
app_options.js:571 The Preferences may override manually set AppOptions; please use the "disablePreferences"-option to prevent that.
_checkDisablePreferences @ app_options.js:571
plugin.laserfichelocalhost.com:18437/GetInfo:1  Failed to load resource: net::ERR_CONNECTION_REFUSED
plugin.laserfichelocalhost.com:18436/GetInfo:1  Failed to load resource: net::ERR_CONNECTION_REFUSED
app.js:1559 PDF ad42f5d00b5c275d75ca0cc523bfc955 [1.3 - / -] (PDF.js: 4.9.124 [867aaf01f])
viewer.custom.css:1  GET https://app.laserfiche.ca/laserfiche/v11.0.2512.138/Viewer/web/images/toolbarButton-viewOutline@2x_inverted.png 404 (Not Found)
viewer.custom.css:1  GET https://app.laserfiche.ca/laserfiche/v11.0.2512.138/Viewer/web/images/toolbarButton-viewAttachments@2x_inverted.png 404 (Not Found)
viewer.custom.css:1  GET https://app.laserfiche.ca/laserfiche/v11.0.2512.138/Viewer/web/images/toolbarButton-viewThumbnail@2x_inverted.png 404 (Not Found)
viewer.custom.css:1  GET https://app.laserfiche.ca/laserfiche/v11.0.2512.138/Viewer/web/images/toolbarButton-menuArrows@2x_inverted.png 404 (Not Found)
VM8:9 Create URL
VM8:16 The EntryID = 18447
VM8:17 The concat URL= https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&customerId=1556239797&id=18447#?openmode=PDF&lang=en-US
VM8:27 Start iframe
VM8:21 Create Iframe URL default= https://app.laserfiche.ca/laserfiche/DocView.aspx?repo=r-000139b5c3c0&customerId=1556239797&id=18447#?openmode=PDF&lang=en-US
VM8:22 URL created
VM8:28 Uncaught (in promise) TypeError: Assignment to constant variable.
    at Object.updateIframeSource [as handler] (eval at window.init (about:srcdoc:18:35), <anonymous>:28:14)
    at about:srcdoc:33:2309
    at Array.some (<anonymous>)
    at about:srcdoc:33:2263
    at Array.forEach (<anonymous>)
    at about:srcdoc:33:2182
    at Array.forEach (<anonymous>)
    at window.handleEvent (about:srcdoc:33:2126)
    at about:srcdoc:33:2489
updateIframeSource @ VM8:28
(anonymous) @ about:srcdoc:33
(anonymous) @ about:srcdoc:33
(anonymous) @ about:srcdoc:33
window.handleEvent @ about:srcdoc:33
(anonymous) @ about:srcdoc:33
 

0 0
replied on January 13

Ok I updated (and actually tested this time) the code in my original post. I also added the conditional checks for empty entry ids.

0 0
replied on January 13

Good news now it does what it is supposed to do.

A search generates a list of results, from a drop down the user selects a document of interest and it fills  a Custom HTML with a document via a dynamically created iFrame. Wow great.

It was the const iFrameLink that messed things up from your original fix. Clearly the async and await are what resolved my problem. I was looking for some way to introduce a delay, that's how we did it in the old days, my gut told me that's what it was but I could not find it away to do it. I assumed the on change would catch that.

Anyway the only trouble now is residual errors in the Console see attached that I can't help but wonder are these developer tool /browser errors just unhappy with how Laserfiche creates the code or do I still have problems.

0 0
replied on January 13

The only notable error is "The Preferences may override manually set AppOptions; please use the "disablePreferences"-option to prevent that." which I believe is because you are explicitly setting the language in the postfix url. If this isn't intended you can remove it.

The remaining errors are related to laserfiche communicating with the office plugin. You may need to install/reinstall it to get those errors to go away, otherwise ignore them.

0 0

Replies

replied on January 22, 2024

Hi Zachary,

Thank you for sharing your code, this has helped and we got it working perfectly!

1 0
You are not allowed to follow up in this post.

Sign in to reply to this post.