Archive | Bootstrap RSS for this section

Triggering a Partial Refresh when a Select2 Value is Changed in XPages

In my last post, I showed how to add Bootstrap error styling to a Select2. As I’ve continued to work with Select2, I came across another challenge — triggering a partial refresh when a Select2 value is changed — because standard component events aren’t executed on a Select2.

This issue is because a component is converted to a Select2 after the page loads. It takes your combobox or listbox and converts it to a div surrounding the entire field, a div for the search, and an unordered list of elements to display in the drop-down. Any event handler code that you entered on the combobox or listbox will no longer be associated with the field because it’s been replaced with the Select2 UI elements.

It is common to update a part of a page based on a value selected in any variation of a list field, so, fortunately, this issues can be worked around by using event delegation to trigger a client-side JavaScript function when the Select2 is changed.

Take this example of converting a field (with a class name of “mySelect2”) to a Select2:

$(".mySelect2").select2({
  placeholder: "Select the value..."
});

To trigger a partial refresh when the value is changed, add this code on the client load or document ready event after the previous code to enable the Select2:

	
$(".mySelect2").on("change", function(e) { 
  XSP.partialRefreshPost("#{id:myPanel}");
})

The code will watch for any change on the Select2 and it will trigger a partial refresh via client-side JavaScript. (See Mark Roden’s post on jQuery event delegation for a good explanation of jQuery event delegation.)

It must trigger a partialRefreshPost (rather than a partialRefreshGet) because it has to send the new value to the server. For the same reason, the field must be within the partial refresh target area.

You can only write client-side JavaScript code here, but if you have a larger piece of server-side JavaScript or Java code that needs to be executed, you could put that code on a hidden button (it must be rendered, but could be hidden from the screen with CSS) and trigger a click() event on that button with client-side JavaScript.

_

Advertisements

Adding Bootstrap Error Styling to a Select2

In this excellent post, Mark Leusink shows how to create a reusable control that makes it easier to create Bootstrap-styled fields with labels and field validation. While using a similar concept — computing the class of the div around a field based on whether there’s an error in the field — I found that Select2 fields need a little bit of extra work to display with the error styling.

Boostrap looks for an error class in the div surrounding a field and label and it styles them accordingly. See Mark’s post for a more detailed explanation.

This works well in general, but Select2 fields are different, because they are generated on the front end as the page is loaded. The same thing happens with dojo-enabled fields (date and time pickers, etc) — the lose some styling that you try to define when they’re rendered on the page.

Adding the error class to the div around a Select2 will not cause it to pick up error styling. However, with a little CSS, you can easily update a Select2 field to be highlighted in red if the surrounding div contains the error class.

/* Styling for Select2 with error */
div.has-error ul.select2-choices {
  border-color: rgb(185, 74, 72) !important;
}

This looks for a div with the error class (which is has-error in Bootstrap 3) and then locates a ul with the class select2-choices within that div. I just found this by looking at the generated html and trying classes on different elements until it worked.

The CSS sets the border color to the same color that it sets other error fields. I found that by flagging a field as an error and checking the styles that it picked up.

The good news is that these 3 lines of CSS will do the trick for any instance of a Select2 that’s contained in a div that’s flagged as an error.

Note

I’m using Bootstrap 3, so the class names are a little different than on Mark’s page, but the concept remains the same.

Set the Bootstrap class for all multiline text fields and labels in XPages with a Theme

In my last post, I showed how to automatically set the class name to pick up Bootstrap styling on all text fields in an XPages application via the theme. In this post, I’ll show how to set the class name on multiline fields and field labels as well.

If I update the form from the last post to include a multiline edit box, it will look this (if I already have the code from the last post included in the theme):

BootstrapTextArea_Labels_Before

The multiline edit box doesn’t match and the field labels also aren’t picking up Bootstrap styling.

This code in the theme will update the multiline edit box controls to pick up the required form-control class:

<!-- Set all multiline inputs to Bootstrap styling -->
<control>
  <name>InputField.TextArea</name>
  <property mode="concat">
    <name>styleClass</name>
    <value>form-control</value>
  </property>
</control>

This code will automatically provide the class to all field labels via the theme:

<!-- Set all labels to Bootstrap styling -->
<control>
  <name>Text.Label</name>
  <property mode="concat">
    <name>styleClass</name>
    <value>control-label</value>
  </property>
</control>

Now, everything on the form is picking up the correct styling:

BootstrapTextArea_Labels_After

Set the Bootstrap class for all text fields in XPages with a Theme

In order to enable your fields to pick up Bootstrap styling, you must specify the class name form-control on each of them. In this post, I’ll show how to make this much easier by setting it for all text fields at one time via the theme.

In an application that is set up to work with Bootstrap 3, I created a div with the class well and added three labels and fields. This is what it looks like by default:

BootstrapFields_Before

My application is already using a custom theme in order to make Bootstrap and other resources available globally, so I added this code to automatically add the form-control class to all input text controls.

<!-- Set all inputs to bootstrap styling -->
<control>
  <name>InputField.EditBox</name>
  <property mode="concat">
    <name>styleClass</name>
    <value>form-control</value>
  </property>
</control>

This instructs the server to look for all text fields and add form-control to the styleClass attribute. The property mode is set to concat so it will add the class to any other classes you define on the control rather than overwrite it. Now, all text fields will automatically pick up the correct styling!

BootstrapFields_After

That’s more like it.

Note

This assumes you already have bootstrap enabled in your application. The specific layout in these screen shots was created with a well and other divs with standard Bootstrap scaffolding classes.