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

Question

Question

Displaying URL in Collections

asked on July 15

Hi everyone!

 

I’ve been working on this for quite a while, and I’m hoping someone can point out what I’m missing to get this working as intended.

I’ve created a quiz system in Laserfiche Forms, and I’m currently trying to add the functionality to display an image alongside each question. Each question is stored as a row in a collection, and I’ve already:

  • Built a lookup that retrieves a Laserfiche DocView URL for an image from our repository.

  • Mapped the URL to a field (File_URL) inside each collection row.

  • Used custom HTML and JavaScript to inject the URL into an <iframe> to preview the image.

This works perfectly when there’s only one row, but when I add multiple rows to the collection, the last row’s URL gets applied to all of the iframes. The result is that every row displays the same image — the one from the final row.

From what I can tell, the issue is that my JavaScript isn’t correctly scoping the src assignment to just the current row — it’s applying the src to all iframe elements globally instead of the one in the matching row.

I’ll include my current JavaScript and custom HTML setup below, but so far, everything I’ve tried either applies the wrong image to each row or fails to render at all. If anyone has experience properly targeting elements inside collection rows in Laserfiche Forms, especially when working with custom HTML and JavaScript, I would really appreciate your help!

Thanks in advance!
 

Picture URL - Single Line with class fileurl and variable name File_URL

Java

$(document).ready(function () {
  /* 1) initial auto-grow */
  autoGrowML();

  /* 2) re-apply after new rows are added */
  $('.cf-table-add-row, .cf-collection-append').on('click', function () {
    setTimeout(autoGrowML, 100);            // wait for new DOM to render
  });

  /* 3) re-apply when specific fields change */
  $('#Field40, #Field39').on('change', autoGrowML);

  /* ---------- iframe-reload logic ---------- */
  $(document).on('change', '.fileurl input', function () {
    const url = $(this).val();
    $('.field iframe').attr('src', url);
  });
});

Custom HTML Field with class field

<iframe id="myframe" src="{/dataset/File_URL}" width="50%" height="500px"></iframe>

 

Fields.png
1 Question.png
2 Questions.png
Fields.png (320.62 KB)
1 Question.png (1.98 MB)
0 0

Answer

SELECTED ANSWER
replied on July 15

If I'm understanding correctly, it sounds like you have an iframe for each row of the collection, but your code for updating the iframe URL doesn't have anything to single out a specific row, so it updates all of them every time that function is triggered.

If that's the case, you just need to get more specific on the target, and something like the following should do the trick.

/* ---------- iframe-reload logic ---------- */
$(document).on('change', '.fileurl input', function () {
    const url = $(this).val();
    $(this).closest('.rpx').find('.field iframe').attr('src', url);
});

$(this).closest('.rpx') will move up the DOM tree to get the closest collection row parent/container.

Then, .find() will retrieve the iframe within that same parent; this way you only update the iframe associated with the same row as the triggering field.

1 0
replied on July 16

That worked!! Thank you so much Jason!!

0 0
replied on July 17

Is there any reason why that code wouldn't work on the next form that loads all of the selected questions in the same way? It's still a collection, it's still the same variables, but instead of selecting the questions one at a time, all of the questions are being loaded in automatically on a lookup all at one time. 

0 0
replied on July 17

Because the code is triggered by the change event and the values are already present on the second form, meaning no change event is triggered.

One way to handle that is to manually trigger the change event right after you assign the handler so it always runs at least once.

The easiest way to do that is to use .change() after you assign the handler

// add change event handler
$(document).on('change', '.fileurl input', function () {
    const url = $(this).val();
    $(this).closest('.rpx').find('.field iframe').attr('src', url);
});

// trigger change event for prefilled rows
$('.fileurl input').change();

If you want everything included on a saved copy or read-only form, that will also require additional changes because the fields become static text content when saving to the repository or viewing a read-only user task.

0 0
replied on July 17

What would you need to do to add it to the read-only form?

0 0
replied on July 17

There's a lot of different approaches you could take. I don't have anything doing exactly what you're doing because you have both the change event and the need to update values on a read-only copy, but I've used code like the following to populate data on forms that may or may not be read-only.

$(document).ready(function(){
  // preload data from existing field values
  $('.dataSource').each(function(){
    mapData($(this));
  });
});

function mapData(e){
  let value = '';
  
  // radio fields
  if(e.hasClass('dataRadio')){
    value = e.find('.cf-field input:checked').val() || '';
  }
  // input fields (input for interactive, div for read-only/saved)
  else {
    value = e.find('.cf-field :input').val() || $(e).find('.cf-field div[type]:eq(0)').html() || '';
  }
  
  // update the url field here
}

Basically, instead of putting all the code in the change handler, I would call the mapData method and pass the triggering field as a parameter.

Then, instead of manually triggering the .change() event, you would use .each() to loop through each of the fields and call the mapData method; manually triggering the change is no longer necessary since you'll be running the process even when there are no input elements to change.

The important thing is that this requires careful consideration of the scope and selectors you use; you can't just pass the input directly because read-only forms won't have the input.

This makes things a bit more complicated because you have to make sure it works in both scenarios. I don't have a specific example of that because I generally create a separate form with different styling for my saved or read-only versions of the form.

Also note that when I say "read-only" I'm referring to forms that are marked as read-only at the user task level; marking specific fields/sections as read-only from the designer doesn't change the input elements.

0 0

Replies

You are not allowed to reply in this post.
You are not allowed to follow up in this post.

Sign in to reply to this post.