Posted: 1 Jun 2017 11:04 EDT Last activity: 10 Aug 2017 11:58 EDT
Iterate through a Table Using Clones
I am attempting to iterate through a table using clones. Since the table designer won't recognize textboxes this is the only way I can iterate through a table and keep the ability to write to the text box. Currently I am attempting to iterate through each row. Once I get the row I am attempting to then iterate through the columns to pull the outer html so that I can determine what table header I am in. I am currently able to iterate through the columns correctly but I am never able to move off of row one. Each time I run through the loop I am getting the outer html from the textboxes in row 1 each time. I can tell that the loop is pulling the correct amount of rows because the loop continues as many times are there are rows. Any insight would be greatly appreciated.
***Edited by Moderator: Marissa to add SR Details***
If I am understanding you, you want to fill in a textbox that is in one of the cells. If that is the case, there is a trick to this. After you have designed the table, set the Interrogator back to "Default" then interrogate the textbox in the table. It should show up in the table structure as a textbox. Totally counterintuitive.
I am confused by your code, though. I rather prefer a forLoop myself. I use the count for the tablesection from the Table properties, and use that to index through the rows. Note that the arrow points to a Link and not a cell. I interrogated that after the table was designed.
Good to hear from you. So I did exactly what you suggested, I interrogated the table using the html designer and then I used the default on the actual text box. What I am trying to do though is instead of using that one text box, I made clones of that box so that I could iterate through the rows and then iterate through the different text boxes. Each text boxes outer html tells me the header of that column, so if I need to fill in the first name text box, I want it to go to row 1 and integrate through the columns until it finds the text box with First Name. Then once that's completed, it would go to the second row and do the same.
I also was using the Forloops and using proxies for the limits but it still only gives me the first row (also the support desk suggested I used listloops instead). I attached a copy of the table so you can see what I am talking about.
For each row of the table, there is a text box in each column.
Then you should interrogate the text box and get it to match for the text box in that specific column. You can use an AttributeValueMatchRule and set the Attribute to OuterHtml and identify the text box you need. There really isn't a built-in way to handle clones of clones because GetClones does not accept a key value, so you will always get the first row. You can build your own table of clones by using the created event for each one to store it into a lookup table, but I think that might be overkill. My suggestion would be to identify the specific text box and match it, then iterate through the rows and pass the value to the text box and set its key property to the Index of the loop.
I would use what Thomas suggested. You seem to have a limited number of columns in your table so just directly interrogate those. Good to see you posting by the way!
The table designer is used to interrogate a table. A table by definition has Rows, Columns and Cells. Those are the elements you can have in a table. If a developer adds controls inside of a table cell you interrogate that control separately (I use Select Element) after the table is defined. Always interrogate these items in the first row of the table. It may seem counterintuitive at first but makes sense when you realize that for you to get the textbox or link to appear inside the table, the table needs to be created first.
Thank you both for the responses. Unfortunately the table that I am using is much bigger than the one I attached. There can be up to 25 different columns (different groups will have different amounts in each table) that I would need to iterate through. Although the suggestion Thomas gave would work, it would take a lot of code to do so, which I will be happy to create if need be. I was just hoping to avoid that by creating clones and loops so that I would only need a few boxes to accomplish this rather than interrogating all 25 different boxes and then determining if the specific table I am looking at has all 25 or not.
I appreciate any other suggestions/ideas on this issue.
Just wanted to write to say thanks much! I followed the approach for a somewhat complex scenario - table has checkboxes as well as links, have to take action at a per-row level based on content in that row, and the approach suggested worked like a charm.
So here is the trick to working with clones of clones. The problem is that the GetClones method of your child clone collection does not accept a key (it uses the key of "none" essentially sticking you with only the first row). You can build your own clone collection however, but I'm not sure how this would work with an HTML table as the child doesn't have the traditional parent. I'll document this technique here though in case it would work with a table section, but I know it will work with regular controls that are cloned and have cloned children.
We will be constructing our own table to store the keys of the clones in, so that we can get the key out of this table rather than iterating through GetClones collection. Create a lookup table to store whatever you need in addition to the following; the key for the control, and the key for its parent control (the one that is cloned). For your example, you might want to also store the OuterHTML as you could do all your evaluation within the table. Using the Created event for the child control, store this data into the table (LookupTable.AddRecord). Also remember to remove the data from the table when the control is destroyed (LookupTable.RemoveRecord). Now when you are needing to handle a specific child clone, you can iterate through the LookupTable (by calling GetKeys and passing that to a ListLoop followed by a GetRecord call, or better yet, use a script to work with the DataTable directly - LookupTable.GetTable).
I have used this method in the past with great success, however I have never tried with an HTML table. I do not have an example to try this with however, but if you can provide a public one or some simple page HTML, I'll be happy to try.