I've been writing my first primefaces extension and it's been going well. I have a new component which is entirely functional when using the taglibs I have defined. This is great! However, I am having a lot of trouble when modifying the view through Java code as the resource dependencies are not dynamically being loaded. I have obviously done something wrong, but I'm unclear what.
I have the following structure.
Library name otbofaces
Component name dateentry
- META-INF/resources/otbofaces/dateentry
- dateentry.css
dateentry.js
jquery.autotab.js
jquery.caret.js
jquery.date-entry.js
- dateentry.css
Code: Select all
@FacesRenderer( componentFamily = DateEntry.COMPONENT_FAMILY, rendererType = DateEntryRenderer.RENDERER_TYPE )
public class DateEntryRenderer extends CoreRenderer {
public static final String RENDERER_TYPE = "com.tracegroup.isys.faces.DateEntryRenderer";
Code: Select all
@FacesComponent( value = DateEntry.COMPONENT_TYPE )
@ResourceDependencies( {
@ResourceDependency( library = "primefaces", name = "jquery/jquery.js" ), // JQuery !
@ResourceDependency( library = "primefaces", name = "primefaces.js" ), // PrimeFaces !
@ResourceDependency( library = "otbofaces", name = "dateentry/jquery.autotab.js" ), // Auto Tab for automatic cursor transition between fields.
@ResourceDependency( library = "otbofaces", name = "dateentry/jquery.caret.js" ), // JQuery caret for cursor movement in fields.
@ResourceDependency( library = "otbofaces", name = "dateentry/jquery.date-entry.js" ), // Main body of the DateEntry definition.
@ResourceDependency( library = "otbofaces", name = "dateentry/dateentry.js" ), // Widget definition.
@ResourceDependency( library = "otbofaces", name = "dateentry/dateentry.css" ), // Main body of the DateEntry definition.
} )
public class DateEntry extends HtmlInputText implements Widget, ClientBehaviorHolder {
Code: Select all
<otbofaces:date-entry id="datetime-enabled" date="29" month="1" year="1980" hour="9" minute="52" datepicker="true" format="datetime" binding="#{buttonView.datetime}" />
Code: Select all
UIComponent component = actionEvent.getComponent();
DateEntry dateEntry = new DateEntry();
dateEntry.setFormat( "datetime" );
dateEntry.setDate( 15 );
dateEntry.setMonth( 8 );
dateEntry.setYear( 2011 );
dateEntry.setHour( 20 );
dateEntry.setMinute( 12 );
dateEntry.setDisabled( false );
dateEntry.setDatepicker( true );
datecontainer.getChildren().add( dateEntry );
Code: Select all
String clientId = component.getClientId();
String widgetVar = component.resolveWidgetVar();
WidgetBuilder wb = getWidgetBuilder( context );
wb.initWithDomReady( "DateEntry", widgetVar, clientId, "dateentry" );
encodeClientBehaviors( context, component );
wb.finish();
It's executing the javascript with this javascript:
Code: Select all
$(function(){PrimeFaces.cw("DateEntry","widget_j_idt8_j_id5",{id:"j_idt8:j_id5"},"dateentry");});
A small summary:
- The URL generated by the primefaces.js appears to think that these resources are in the primefaces library. i.e. from /javax.faces.resource/dateentry/dateentry.css.xhtml?ln=primefaces&v=5.3 instead of /javax.faces.resource/dateentry/dateentry.css.xhtml?ln=otbofaces&v=20160125162258 (I have a server-side OtboResourceHandler to add the version, I can include the sources for these later if necessary).
- As you can see, the component maps 5 client side resources to the component. I have only seen that it attempts to get dateentry.js and dateentry.css, so it is ignoring the other resource dependencies that are wired onto the Widget implementation using the @ResourceDependency annotations.
Code: Select all
ResourceDependencies resourceDependencies = DateEntry.class.getAnnotation( ResourceDependencies.class );
for ( ResourceDependency dependency : resourceDependencies.value() ) {
// insert javascript code that loads the javascript or stylesheet if it isn't present in the header.
}
Thanks,
Stuart