Dynamic binding of fields bug?

I was developing very simple XPages component recently and because it was basically loop through a list of field names (and the task was to show something for each of them) I have used repeat control and inside of it there was custom control with properties such as fieldName (String), label (String), isRequired (boolean) and so on. In the custom control I was binding fileDownload and fileUpload controls (based on read/edit mode) to document field via EL as "document1[compositeData.fieldName]" where document1 is data source defined in XPage that "calls" this custom control. Everything worked fine and as expected, I had one generic custom control to "show" all fields I wanted. Parameter isRequired was passed to validation formula, ...bla bla bla....I was happy with the solution.

But delete icon in fileDownload control was not working correctly. It simply did not delete attached file at all. I had too little time to investigate the problem thoroughly. I have tried passing also data source object to custom control to make sure it receives proper data. But even this did not help. And even without this parameter proper data was shown on fileDownload and uploaded through fileUpload (so custom control was able to access data source defined in the parent XPage).

Then I tried to make copy of this custom control and bind fileDownload control to document1.myfield where "myfield" is name of existing rtf field on my form (one of those fields repeat in the XPage was going through). And suprise suprise, delete started to work.
So what I did (shame on me): made several copies of custom control each with hard binding for field it was supposed to show. And if they want to change anything in the way the fields are shown? Yes I'm gonna repeat myself (or more likely shoot myself in the head) and change it in all copies :-(

I always follow DRY (Don't repeat yourself) pattern. Except when I can't. But it hurts...

Have any of you see this problem, guys? Or can anyone suggest better solution? Please? Pretty please? :-)

EDIT: I'm not sure if I'm describing it well. Lets simplify it: there is a notes form with RTF fields named field_1, field_2, field_3, ..., field_99. Based on value in some other field I want to show all even or all odd numbered fields. This is just silly but lets play along. And I do not want to have 99 hard coded custom controls or to place 99 controls on XPage. Attachments have to be in these fields. And I want fileDownload to allow user to delete attached file.

EDIT2: I was trying solution suggested by Stephen in the comment #1, but it did not help as well.
But I noticed where my mistake was. I forgot to set repeatControls="true" for my repeat (in the Properties tab it is checkbox Create controls at page creation). If this is set, even my way of binding (send just fieldName - as String - and bind it in the control via EL as "document1[compositeData.fieldName]") works. Ufff, so much time wasted...

Tags: 

Comments

You might need to change your binding

Actually not good approach. If you want to bind a control to a second document or a memory variable it won't work. Your control has a dependency (document1) that is not defined in the "contract" (a.k.a. the parameters) Instead of document1[compositeData.fieldName] } handover the full qualified binding as parameter. I use "bindingName" as my parameter. Then use #{'${compositeData.bindingName}'} as EL binding.
I use that one in the multi-column checkbox control on OpenNTF, you might want to check the exact source there.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
12 + 3 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.