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

Question

Question

Using innerHTML within a Collection

asked on October 30, 2019 Show version history

I am hoping someone can help me with some JavaScript. I know I'm on the right track but there seems to be something that I'm missing.

I have a collection (class = addendums) that contains a single line field and a blank custom html field in each set. The single line field (#q95) is being populated with a URL from a Lookup Rule. I am using JS to insert the URL as an iframe into the custom html field (#q96). I have successfully implemented this method before but it was not inside a collection. Right now, it is working for the first set, but not the subsequent sets. I was thinking the .each would take care of that but no luck so far. 

 

This code is inside the $(document).ready function. 

//Insert the iframe stuff into the html field
  function loadAddendums(){
    $('.addendums .rpx').each(function(){
      var urlA = $('#q95 input').val()
      var fullhtmlA = "<iframe id='myframe' src='" + urlA + "' width='100%' height='600px'></iframe>";
      document.getElementById("q96").innerHTML = fullhtmlA;
    })
  }
  
  //Execute the iframe function whenever the collection field changes
  $('.addendums').change(loadAddendums);

 

The URL field will eventually be hidden... it is visible for now while I am testing.

0 0

Answer

SELECTED ANSWER
replied on October 30, 2019 Show version history

Since you're working with JQuery objects, the getElementsByClassName isn't going to work that way. Basically, your current code is trying to use the object itself in a method that expects a class name so it finds nothing.

You actually already have the element as a JQuery object for the "neighbor" variable, so you don't have to retrieve it again at all.

Instead, you can just act directly on the object you already have and use the JQuery html method instead of vanilla innerHTML since you're working with JQuery objects instead of DOM objects.

You could either do

neighbor.html(fullhtmlA);

or, you could skip the extra neighbor and fullhtmlA variables and just set the html directly.

$('.frameContainer').eq(row - 1).html("<iframe id='myframe' src='" + urlA + "' width='100%' height='600px'></iframe>");

I don't see anything wrong with using the variables because it helps keep the lines shorter and makes the steps easier to follow, but they aren't "necessary"

1 0

Replies

replied on October 30, 2019

This is a pretty common challenge with tables and collections. The following post should point you in the right direction.

https://answers.laserfiche.com/questions/153832/Table-and-Collection-JavaScript-Event-Handlers

1 0
replied on October 30, 2019

That is perfect!! Thanks!

0 0
replied on October 30, 2019

Ok so this has helped a ton with identifying the row-specific URL field number. However, I am still struggling with how to do identify the row-specific custom html field number - probably because I am like 4% competent with programming concepts. When I inspect the elements, the custom html fields are not named "field#(row#)" so I'm not sure how to tell the innerHTML function where to insert the "guts". I looked at this post but I'm still not getting it.

I'm also not sure how to target the row-specific URL field input. I have tried several ideas incorporating the row variable but the code below just shows the generic field input syntax because nothing that I tried worked. 

  //Execute the iframe function whenever the collection field changes
  $('li.addendums').on('change','.addendURL',function(e){
    var field = e.target.id.match(/\d+/g)[0];
    var row = e.target.id.match(/\d+/g)[1];
    var urlA = $('#q95 input').val();
    console.log(field + '(' + row + ')');
    console.log(urlA);
    var neighbor = $('#Field96\\('+ row + '\\)');
    
    var fullhtmlA = "<iframe id='myframe' src='" + urlA + "' width='100%' height='600px'></iframe>";
    //document.getElementById("#q96").innerHTML = fullhtmlA;
  });

0 0
replied on October 30, 2019 Show version history

CustomHTML elements will be a bit different because they don't have inputs that would get the row numbering.

First, you don't want to set "id" for your iframes. An id attribute should only ever apply to one element as that is what JavaScript expects.

Instead change that to a class, or tack the row number onto the id so it is unique.

Now to get the custom html element for the target row, you want to apply a custom class to it in the form designer

Then, you can use that in combination with the :eq selector to target the one for the corresponding row.

Row number will be 1 off since indexing starts with 0, so you'll need to either subtract when you get the row number, or when you target the html element.

For example,

var neighbor = $('.frameContainer').eq(row - 1);

 

If the URL input triggered the change, it will be the "e.target"

For example, the following would get you the value from that field (i.e., no need to "find" it because you already have it from the event triggering).

$(e.target).val()

 

On a related note, this is one of the reasons I favor custom CSS classes over using the built-in field identifiers; they're more universal and make it easier to identify what is happening in the code (i.e., #field82 doesn't tell you much, but .frameContainer does).

1 0
replied on October 30, 2019

I am so close I can feel it! I may have misunderstood the piece of your response that was talking about changing from an ID to a class. I applied the frameContainer class to the custom HTML field. Then, I also changed the innerHTML function to look at getElementsByClassName instead of getElementByID. I tried several syntax variations but that is the only piece that isn't working yet. 

  //Execute the iframe function whenever the collection field changes
  $('li.addendums').on('change','.addendURL',function(e){
    var field = e.target.id.match(/\d+/g)[0];
    var row = e.target.id.match(/\d+/g)[1];
    var urlA = $(e.target).val();
​​​​​​    console.log(urlA);
    var neighbor = $('.frameContainer').eq(row - 1);
    var fullhtmlA = "<iframe id='myframe' src='" + urlA + "' width='100%' height='600px'></iframe>";
    document.getElementsByClassName(neighbor).innerHTML = fullhtmlA;
  });

I can't tell you how much I appreciate all your help!!!

0 0
SELECTED ANSWER
replied on October 30, 2019 Show version history

Since you're working with JQuery objects, the getElementsByClassName isn't going to work that way. Basically, your current code is trying to use the object itself in a method that expects a class name so it finds nothing.

You actually already have the element as a JQuery object for the "neighbor" variable, so you don't have to retrieve it again at all.

Instead, you can just act directly on the object you already have and use the JQuery html method instead of vanilla innerHTML since you're working with JQuery objects instead of DOM objects.

You could either do

neighbor.html(fullhtmlA);

or, you could skip the extra neighbor and fullhtmlA variables and just set the html directly.

$('.frameContainer').eq(row - 1).html("<iframe id='myframe' src='" + urlA + "' width='100%' height='600px'></iframe>");

I don't see anything wrong with using the variables because it helps keep the lines shorter and makes the steps easier to follow, but they aren't "necessary"

1 0
replied on October 31, 2019

Thank you for the clarification! I like the cleaner variables too. Everything works perfect now!! 

  //Execute the iframe function whenever the collection field changes
  $('li.addendums').on('change','.addendURL',function(e){
    var field = e.target.id.match(/\d+/g)[0];
    var row = e.target.id.match(/\d+/g)[1];
    var urlA = $(e.target).val();
    var neighbor = $('.frameContainer').eq(row - 1);
    var fullhtmlA = "<iframe id='myframe' src='" + urlA + "' width='100%' height='600px'></iframe>";
    neighbor.html(fullhtmlA);
  });

 

Thank you so much!!!

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

Sign in to reply to this post.