<f:repeatable> tag throws Uncaught TypeError: Cannot read property 'hasClassName' of undefined in browser console

40 views
Skip to first unread message

george....@ullink.com

unread,
Sep 7, 2018, 4:43:42 AM9/7/18
to Jenkins Developers
I'm trying to display a list of labels inside the job configuration page of Jenkins using the <f:repeatable> tag like so:

<f:repeatable var="p" name="customLabels" items="${instance.customLabels}">
<tr>
<td></td>
<td>
<div style="font-weight: bold; border-bottom: 1px solid black; margin-bottom: 0.2em; margin-top: 0.4em;">
${p.labelName}
</div>
</td>
</tr>
</f:repeatable>

where I've declared custom labels in my java class:

private List<CustomLabelValue> customLabels;

When I build the .hpi and upload it to jenkins, when refreshing the job configure page I get a loading modal plus:

newitem.PNG

Anyone got an idea? Thanks!

george....@ullink.com

unread,
Sep 7, 2018, 8:11:58 AM9/7/18
to Jenkins Developers
Answer: It's because you can't have entries inside </f:repeatable>

Jesse Glick

unread,
Sep 7, 2018, 8:32:28 AM9/7/18
to Jenkins Dev
Perhaps my earlier message was not worded strongly enough, so I will
try to expand on it.

There are, broadly speaking, two kinds of Jelly code used in Jenkins
configuration pages. The familiar code, as exemplified in
`ui-samples-plugin`, uses a limited set of high-level controls which
all either take a `field` attribute or expect to be inside an
`f:entry` defining the `field`. These may specify a `default` in
certain cases, but `name` and `value` should not be used, nor should
there be extra HTML tags beyond `f:advanced` and a couple of similar
helpers. Each `config.jelly`, plus any associated `help.html` and/or
`help-fieldName.html`, corresponds to one `Describable` type, with a
`@DataBoundConstructor` defining mandatory fields and
`@DataBoundSetter`s defining optional fields. `f:textbox` completion,
`f:select` contents, and form validation are all done by
conventionally-named web methods in the `Descriptor` using
`@QueryParameter`. Structured forms are created by fields of type
`SomeOtherDescribable` or `List<SomeOtherDescribable>` and the
corresponding controls. Pipeline and/or JEP-201
(“configuration-as-code”) support generally comes for free or with
minimal intervention like adding `@Symbol`s. This is called “modern
databinding”. Virtually all plugin code should be using it, and you
can file bug reports or request advice on the developer list if
anything goes wrong.

The other kind of code uses low-level controls like `f:repeatable`.
This should generally only be used to _implement_ higher-level
controls, or to handle very specialized use cases, and only
experienced Jenkins developers should consider touching it as it is
very tricky to get right and you will in general need to use Java
and/or JavaScript source debuggers, HTML inspectors, etc. to track
down issues, which may require tested Jenkins core patches. Pipeline
or JEP-201 support would require custom adapters. Plenty of _existing_
plugin code still uses these controls, only because the maintainers
were ignorant of modern databinding, or because it was written before
modern databinding existed and no one ever felt an immediate need to
rewrite the configuration forms.

I have seen no indication that you need to be using the latter
category. While I do not understand the exact use case, it is
something like: I need a list of pairs of label and some number. So
define a `Describable` for that kind of pair, and a top-level
`Describable` taking a list of them. It is up to the user to select
label names. You can use standard features of modern databinding to
offer completion or even fixed dropdowns. If the list is incomplete or
has duplicates or invalid labels or whatever, deal with it gracefully.
You would need to do that anyway for JEP-201 users who are just
editing a YAML file, or (if applicable) Pipeline users writing some
Groovy expression.

george....@ullink.com

unread,
Sep 7, 2018, 8:47:59 AM9/7/18
to Jenkins Developers
Thank you very much, Jesse. I've took up the task to add support for custom gerrit labels on gerrit-trigger-plugin, and for someone that never contributed to jenkins or jenkins plugins before, it's quite hard to make sense of how it should be done.

The use case: Considering a list of labels (which can contain any number of labels at each time) and that each label object has 5 particular int fields that represent votes (one per each build outcume - started, successful, failed, unstable, not built) then display each label and its corresponding votes in an entry inside the Gerrit Trigger job configure page.

I was able to achieve this: 

job_config.PNG



Problem: How can I persist the votes of each label since I don't know beforehand how many labels I have in my label list or what their names are? Because this means I can't use the default @DataBoundSetter mechanism that the plugin currently uses (1-to-1 relationship between a field on the web UI and the setter in the java class which gets called automatically). Currently I just display hardcoded values and any modifications are not persisted in the config.xml file.

It's something that I've been stuck on for over 2 weeks and you shedding some light on this will really make my day!

Thank you,
George

Jesse Glick

unread,
Sep 8, 2018, 11:04:44 AM9/8/18
to Jenkins Dev
On Fri, Sep 7, 2018 at 8:48 AM <george....@ullink.com> wrote:
> The use case: Considering a list of labels (which can contain any number of labels at each time) and that each label object has 5 particular int fields that represent votes (one per each build outcume - started, successful, failed, unstable, not built) then display each label and its corresponding votes in an entry inside the Gerrit Trigger job configure page.

The UI in your screenshot is not implementable via standard, supported
Jenkins databinding. You can use the standard approach I described in
my previous message, where the config form merely lets a user *Add »*
new label blocks and type in / complete / select the label; or you can
try some tricks to get a nonstandard UI and pray that you can make it
work.

Björn Pedersen

unread,
Sep 10, 2018, 12:45:46 AM9/10/18
to Jenkins Developers
Hi,

you probably should take a look at the dynamic parameter plugins like:

Extended Choice, Extensible Choice, Git Parameter, Activce Choices or Autocomplete Parameter  (I didi not check ones are currently actively maintained)

on how they solve this problem.

Björn

george....@ullink.com

unread,
Sep 10, 2018, 3:58:15 AM9/10/18
to Jenkins Developers
Thanks for the suggestion! I'll check them out asap.
Reply all
Reply to author
Forward
0 new messages