/** * Copyright 2014-2017 Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). * * This file is part of BootsFaces. * * BootsFaces is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BootsFaces is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with BootsFaces. If not, see <http://www.gnu.org/licenses/>. */ package net.bootsfaces.component.slider2; import java.io.IOException; import java.lang.reflect.Method; import java.util.Map; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; //!//import javax.faces.convert.DoubleConverter; import javax.faces.render.FacesRenderer; import net.bootsfaces.component.ajax.AJAXRenderer; import net.bootsfaces.component.badge.BadgeRenderer; import net.bootsfaces.render.A; import net.bootsfaces.render.R; import net.bootsfaces.render.Tooltip; import net.bootsfaces.utils.BsfUtils; /** This class generates the HTML code of <b:slider2 />. */ @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.slider2.Slider2") public class Slider2Renderer extends BadgeRenderer { /** * This methods receives and processes input made by the user. More specifically, it ckecks whether the * user has interacted with the current b:slider2. The default implementation simply stores * the input value in the list of submitted values. If the validation checks are passed, * the values in the <code>submittedValues</code> list are store in the backend bean. * @param context the FacesContext. * @param component the current b:slider2. */ @Override public void decode(FacesContext context, UIComponent component) { Slider2 slider = (Slider2) component; if (slider.isDisabled() || slider.isReadonly()) { return; } decodeBehaviors(context, slider); String clientId = slider.getClientId(context); String submittedValue = (String) context.getExternalContext().getRequestParameterMap().get(clientId); if (submittedValue != null) { slider.setSubmittedValue(submittedValue); } new AJAXRenderer().decode(context, component, clientId); } /* ! @Override public Object getConvertedValue(FacesContext fc, UIComponent c, Object sval) throws ConverterException { Converter cnv = resolveConverter(fc, c); if (cnv != null) { return cnv.getAsObject(fc, c, (String) sval); } else { cnv = new DoubleConverter(); return cnv.getAsObject(fc, c, (String) sval); } } */ /** * This methods generates the HTML code of the current b:slider2. * @param context the FacesContext. * @param component the current b:slider2. * @throws IOException thrown if something goes wrong when writing the HTML code. */ @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { if (!component.isRendered()) { return; } Slider2 slider = (Slider2) component; ResponseWriter rw = context.getResponseWriter(); encodeHTML(slider, context, rw); } private void encodeHTML(Slider2 slider, FacesContext context, ResponseWriter rw) throws IOException { String clientId = slider.getClientId(context); String mode = slider.getMode(); String label = slider.getLabel(); int min = slider.getMin(); int max = slider.getMax(); Object v = slider.getSubmittedValue(); if (v == null) { v = slider.getValue(); } if (v == null) { v = slider.getValue(); slider.setValue(v); } if (v == null) { v = max / 2; slider.setValue(v); } //!//double val = A.toDouble(v); int val = A.toInt(v); if (val > max) { val = max; } if (val < min) { val = min; } //!//String valS = Double.toString(val); String o; if (slider.getOrientation() != null) { o = slider.getOrientation(); } else { o = "horizontal"; } boolean isVertical = o.startsWith("vertical"); boolean bottom = o.endsWith("bottom"); int span = slider.getSpan(); rw.startElement("div", null);// form-group rw.writeAttribute("id", clientId, "id"); Tooltip.generateTooltip(context, slider, rw); rw.writeAttribute("class", getWithFeedback(getInputMode(slider.isInline()), slider), "class"); rw.startElement("div", null); String s = "row " + (isVertical ? "slider2-vertical" : "slider2"); if (slider.getStyleClass()!=null) { s += " " + slider.getStyleClass(); } rw.writeAttribute("class", s, "class"); writeAttribute(rw, "style", slider.getStyle()); // --------------------------------------------------------------> // <<-- Vertical -->> if (isVertical) { if (label != null && !bottom) { rw.startElement("div", null); String lsc = slider.getLabelStyleClass(); if (lsc == null) lsc = ""; else lsc = " " + lsc; rw.writeAttribute("class", "row " + getErrorAndRequiredClass(slider, clientId) + lsc, "class"); writeAttribute(rw, "style", slider.getLabelStyle()); encodeVLabel(slider, rw, label); rw.endElement("div");/* Row */ } rw.startElement("div", null); rw.writeAttribute("class", "row", "class"); if (bottom) { encodeSliderInput(slider, rw, isVertical, span, clientId, val); rw.endElement("div");/* Row */ rw.startElement("div", null); rw.writeAttribute("class", "row", "class"); } encodeInput(slider, rw, mode, context, val, clientId, isVertical, min, max); if (!bottom) { rw.endElement("div"); /* Row */ rw.startElement("div", null); rw.writeAttribute("class", "row " + getErrorAndRequiredClass(slider, clientId), "class"); encodeSliderInput(slider, rw, isVertical, span, clientId, val); } rw.endElement("div"); /* Row */ if (label != null && bottom) { rw.startElement("div", null); String lsc = slider.getLabelStyleClass(); if (lsc == null) lsc = ""; else lsc = " " + lsc; rw.writeAttribute("class", "row " + getErrorAndRequiredClass(slider, clientId) + lsc, "class"); writeAttribute(rw, "style", slider.getLabelStyle()); encodeVLabel(slider, rw, label); rw.endElement("div"); /* Row */ } } else { // <<-- Horizontal -->> if (label != null) { rw.startElement("div", null); rw.writeAttribute("class", "row " + getErrorAndRequiredClass(slider, clientId), "class"); R.encodeColumn(rw, null, 6, 6, 6, 6, 0, 0, 0, 0, null, null); rw.startElement("label", slider); rw.writeAttribute("for", clientId, null); String styleClass=""; if (!BsfUtils.isLegacyFeedbackClassesEnabled()) { styleClass = "control-label"; } if (slider.getLabelStyleClass() != null) { styleClass += " " + slider.getLabelStyleClass(); } writeAttribute(rw, "class", styleClass); writeAttribute(rw, "style", slider.getLabelStyle()); rw.write(label); rw.endElement("label"); // Label rw.endElement("div");// Column rw.endElement("div");/* Row */ } rw.startElement("div", null); rw.writeAttribute("class", "row", "class"); encodeInput(slider, rw, mode, context, val, clientId, isVertical, min, max); encodeSliderInput(slider, rw, isVertical, span, clientId, val); rw.endElement("div");/* Row */ } // <<--------------------------------------- rw.endElement("div"); // rw.write("<!-- Slider Widget Row // -->\n");//Slider Widget Row rw.endElement("div"); // rw.write("<!-- form-group -->\n");//form-group encodeJS(slider, rw, clientId, mode); Tooltip.activateTooltips(context, slider); } private void encodeVLabel(Slider2 slider, ResponseWriter rw, String label) throws IOException { R.encodeColumn(rw, null, 12, 12, 12, 12, 0, 0, 0, 0, null, null); rw.startElement("p", slider); if (!BsfUtils.isLegacyFeedbackClassesEnabled()) { rw.writeAttribute("class", "control-label", null); } rw.write(label); rw.endElement("p"); // Label rw.endElement("div"); // Column } private void encodeInput(Slider2 slider, ResponseWriter rw, String mode, FacesContext context, int val, String clientId, boolean vo, int min, int max) throws IOException { int cols = (vo ? 12 : 1); if (!mode.equals("basic")) { /* * int span, int offset, int cxs, int csm, int clg, int oxs, int * osm, int olg */ R.encodeColumn(rw, null, cols, cols, cols, cols, 0, 0, 0, 0, null, null); if (mode.equals("badge")) { generateBadge(context, slider, rw, clientId, slider.getBadgeStyleClass(), slider.getBadgeStyle(), Integer.toString(val), "_badge"); } } removeMisleadingType(slider); // Input rw.startElement("input", slider); rw.writeAttribute("id", clientId, null); rw.writeAttribute("name", clientId, null); rw.writeAttribute("type", (mode.equals("edit") ? "text" : "hidden"), null); rw.writeAttribute("size", String.valueOf(max).length() - 2, null); rw.writeAttribute("min", min, null); rw.writeAttribute("max", max, null); rw.writeAttribute("maxlength", String.valueOf(max).replace(".", "").length(), null); if (slider.isDisabled()) { rw.writeAttribute("disabled", "disabled", null); } if (slider.isReadonly()) { rw.writeAttribute("readonly", "readonly", null); } String styleClass = "form-control input-sm" + (vo ? " text-center" : ""); if (slider.getBadgeStyleClass()!=null) { styleClass += " " + slider.getBadgeStyleClass(); } rw.writeAttribute("class", styleClass, "class"); writeAttribute(rw, "style", slider.getBadgeStyleClass()); rw.writeAttribute("value", val, null); rw.endElement("input"); if (!mode.equals("basic")) { rw.endElement("div"); } // Column } /** * remove wrong type information that may have been added by AngularFaces */ @SuppressWarnings("rawtypes") private void removeMisleadingType(Slider2 slider) { try { Method method = getClass().getMethod("getPassThroughAttributes", (Class[]) null); if (null != method) { Object map = method.invoke(this, (Object[]) null); if (null != map) { Map attributes = (Map) map; if (attributes.containsKey("type")) attributes.remove("type"); } } } catch (Exception ignoreMe) { // we don't really have to care about this error } } private void encodeSliderInput(Slider2 slider, ResponseWriter rw, boolean vo, int span, String clientId, int val) throws IOException { int cols = span; if (!slider.getMode().equals("basic")) { cols--; } /* * int span, int offset, int cxs, int csm, int clg, int oxs, int osm, * int olg */ // For Horizontal, we keep one column for the input/badge //R.encodeColumn(rw, null, (vo ? 12 : cols), (vo ? 12 : cols), (vo ? 12 : cols), (vo ? 12 : cols), 0, 0, 0, 0, null, null); // Issue #172 //<div class="col-md-12 col-xs-12 col-sm-12 col-lg-12" align="center"> if (vo) { rw.startElement("div", null); rw.writeAttribute("class", "col-md-12 col-xs-12 col-sm-12 col-lg-12", "class"); rw.writeAttribute("align", "center", null); } else { R.encodeColumn(rw, null, cols, cols, cols, cols, 0, 0, 0, 0, null, null); // Issue #592 } // Slider <input> rw.startElement("input", null); rw.writeAttribute("id", clientId + "_slider", null); // concat rw.writeAttribute("data-slider-id", clientId + "_slider_id", null); if(BsfUtils.isValued(slider.getMin())) rw.writeAttribute("data-slider-min", slider.getMin(), null); if(BsfUtils.isValued(slider.getMax())) rw.writeAttribute("data-slider-max", slider.getMax(), null); if(BsfUtils.isValued(slider.getValue())) rw.writeAttribute("data-slider-value", val, null); if(BsfUtils.isValued(slider.getStep())) rw.writeAttribute("data-slider-step", slider.getStep(), null); if(BsfUtils.isValued(slider.getHandleShape())) rw.writeAttribute("data-slider-handle", slider.getHandleShape(), null); if(BsfUtils.isValued(slider.getTooltipVisibility())) rw.writeAttribute("data-slider-tooltip", slider.getTooltipVisibility(), null); if(BsfUtils.isValued(slider.isTooltipSplit())) rw.writeAttribute("data-slider-tooltip-split", slider.isTooltipSplit(), null); if(BsfUtils.isValued(slider.getTooltipSliderPosition())) rw.writeAttribute("data-slider-tooltip-position", slider.getTooltipSliderPosition(), null); if(BsfUtils.isValued(slider.getOrientation())) rw.writeAttribute("data-slider-orientation", slider.getOrientation().startsWith("vertical") ? "vertical" : "horizontal", null); if(slider.isDisabled() || slider.isReadonly()) rw.writeAttribute("data-slider-enabled", "false", null); if(BsfUtils.isValued(slider.getPrecision())) rw.writeAttribute("data-slider-precision", slider.getPrecision(), null); if(BsfUtils.isValued(slider.getScale())) rw.writeAttribute("data-slider-ticks-scale", slider.getScale(), null); if(BsfUtils.isValued(slider.isFocus())) rw.writeAttribute("data-slider-focus", slider.isFocus(), null); if(BsfUtils.isValued(slider.getLabelledBy())) rw.writeAttribute("data-slider-labelledby", slider.getLabelledBy(), null); rw.endElement("input"); rw.endElement("div"); // Column } private void encodeJS(Slider2 slider, ResponseWriter rw, String clientId, String mode) throws IOException { String fClientId = BsfUtils.escapeJQuerySpecialCharsInSelector(clientId); String VarName = clientId.replace(":", "_"); rw.startElement("script", slider); //# Start enclosure rw.writeText("$(document).ready(function() {", null); rw.writeText( // build slider structure "var " + VarName + "_sv = new Slider('#" + fClientId + "_slider', { " + (BsfUtils.isStringValued(slider.getFormatter()) ? "formatter: " + slider.getFormatter() + "," : "") + "}); ", null); rw.writeText( "$('#" + fClientId + "_slider').on('slide', function(slideEvt) { " + "$('#" + fClientId + "').val(slideEvt.value); "+ "$('#" + fClientId + "_badge').text(slideEvt.value); "+ "}); ", null); String fchange="$('#" + fClientId + "').val($('#" + fClientId + "_slider').val()); "; if (mode.equals("badge")) { fchange+="$('#" + fClientId + "_badge').text($('#" + fClientId + "_slider').val()); "; } //Fix #699 rw.writeText( "$('#" + fClientId + "_slider').on('change', function() { " + fchange + "}); ", null); rw.writeText( "$('#" + fClientId + "').keyup(function(event) { " + " var val = this.value; " + " if(typeof val === 'string') val = Number(val); " + " " + VarName + "_sv.setValue(val, true, true); " + "}); ", null); rw.writeText("});", null); rw.endElement("script"); } }