package fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.popover; import org.apache.wicket.Component; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.wicketstuff.wiquery.core.javascript.JsScope; import org.wicketstuff.wiquery.core.javascript.JsScopeContext; import org.wicketstuff.wiquery.core.javascript.JsStatement; import org.wicketstuff.wiquery.core.javascript.JsUtils; import com.google.common.collect.ImmutableMap; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.SimpleOptions; /** * Options du plugin <a href="http://twitter.github.com/bootstrap/javascript.html#popovers">Bootstrap Popover</a>. */ public class BootstrapPopoverOptions extends SimpleOptions { private static final long serialVersionUID = 680573363463468690L; // OWSI-Core options private boolean addCloseButton = true; // Bootstrap popover options private Boolean animation; private Boolean html; private PopoverPlacement placement; private String selector; private PopoverTrigger trigger; private String titleText; private IModel<String> titleModel; private Component titleComponent; private JsScope titleFunction; private String contentText; private IModel<String> contentModel; private Component contentComponent; private JsScope contentFunction; private Integer delay; private String container; private IModel<String> cssClassModel; public BootstrapPopoverOptions() { super(); } public CharSequence getJavaScriptOptions(Component popoverComponent) { ImmutableMap.Builder<String, Object> options = ImmutableMap.builder(); if (animation != null) { options.put("animation", animation); } if (html != null) { options.put("html", html); } if (placement != null) { options.put("placement", JsUtils.quotes(placement.getValue())); } if (selector != null) { options.put("selector", JsUtils.quotes(selector)); } if (trigger != null) { options.put("trigger", JsUtils.quotes(trigger.getValue())); } String computedTitleText = (titleModel != null ? titleModel.getObject() : titleText); if (computedTitleText != null) { // Si on veut ajouter un bouton de fermeture, on doit passer par une fonction, // sinon on passe par l'option titleText classique. if (addCloseButton) { options.put("title", getTitleFunction(popoverComponent, new JsStatement().append(JsUtils.quotes(computedTitleText, true)))); } else { options.put("title", JsUtils.quotes(computedTitleText, true)); } } else if (titleComponent != null) { options.put("title", getTitleFunction(popoverComponent, new JsStatement().$(titleComponent).chain("html"))); } else if (titleFunction != null) { options.put("title", titleFunction.render().toString()); } if (contentModel != null) { options.put("content", JsUtils.quotes(contentModel.getObject(), true)); } else if (contentText != null) { options.put("content", JsUtils.quotes(contentText, true)); } else if (contentComponent != null) { options.put("content", new JsScope() { private static final long serialVersionUID = 1L; @Override protected void execute(JsScopeContext scopeContext) { scopeContext.append("return " + new JsStatement().$(contentComponent).chain("html").render()); } }.render().toString()); } else if (contentFunction != null) { options.put("content", contentFunction.render().toString()); } if (delay != null) { options.put("delay", delay); } if (container != null) { options.put("container", JsUtils.quotes(container)); } if (cssClassModel != null) { options.put("cssClass", JsUtils.quotes(cssClassModel.getObject())); } return super.getJavaScriptOptions(options.build()); } private JsScope getTitleFunction(final Component popoverComponent, final JsStatement titleComponentStatement) { return new JsScope() { private static final long serialVersionUID = 1L; @Override protected void execute(JsScopeContext scopeContext) { if (addCloseButton) { scopeContext .append("var titleHtml = " + titleComponentStatement.render()) .append("titleHtml = titleHtml.concat(") .append( JsUtils.quotes( "<a class=\"close\"" // Note : c'est moche, mais au moins ça marche. On renvoie bien du *html* ici, // ajouter des bindings jquery n'aura aucun effet. + " onclick=\"new function() {" + new JsStatement().$(popoverComponent).chain("popover", "'toggle'").render() + " return false;" + "}\"" + ">×</a>", true ) ) .append(");"); } scopeContext.append("return titleHtml;"); } }; } // OWSI-Core options public boolean isAddCloseButton() { return addCloseButton; } public void setAddCloseButton(boolean addCloseButton) { this.addCloseButton = addCloseButton; } // Bootstrap popover options public Boolean getAnimation() { return animation; } public void setAnimation(Boolean animation) { this.animation = animation; } public Boolean getHtml() { return html; } public void setHtml(Boolean html) { this.html = html; } public PopoverPlacement getPlacement() { return placement; } public void setPlacement(PopoverPlacement placement) { this.placement = placement; } public String getSelector() { return selector; } public void setSelector(String selector) { this.selector = selector; } public PopoverTrigger getTrigger() { return trigger; } public void setTrigger(PopoverTrigger trigger) { this.trigger = trigger; } public String getTitleText() { return titleText; } public void setTitleText(String titleText) { this.titleText = titleText; } public IModel<String> getTitleModel() { return titleModel; } public void setTitleModel(IModel<String> titleModel) { this.titleModel = titleModel; } public Component getTitleComponent() { return titleComponent; } public void setTitleComponent(Component titleComponent) { this.titleComponent = titleComponent; } public JsScope getTitleFunction() { return titleFunction; } public void setTitleFunction(JsScope titleFunction) { this.titleFunction = titleFunction; } public String getContentText() { return contentText; } public void setContentText(String contentText) { this.contentText = contentText; } public IModel<String> getContentModel() { return contentModel; } public void setContentModel(IModel<String> contentModel) { this.contentModel = contentModel; } public Component getContentComponent() { return contentComponent; } public void setContentComponent(Component contentComponent) { this.contentComponent = contentComponent; } public JsScope getContentFunction() { return contentFunction; } public void setContentFunction(JsScope contentFunction) { this.contentFunction = contentFunction; } public Integer getDelay() { return delay; } public void setDelay(Integer delay) { this.delay = delay; } public String getContainer() { return container; } public void setContainer(String container) { this.container = container; } public IModel<String> getCssClassModel() { return cssClassModel; } public void setCssClass(String cssClass) { setCssClass(Model.of(cssClass)); } public void setCssClass(IModel<String> cssClassModel) { this.cssClassModel = cssClassModel; } @Override public void detach() { if (contentModel != null) { contentModel.detach(); } if (titleModel != null) { titleModel.detach(); } if (cssClassModel != null) { cssClassModel.detach(); } } }