Skip to content

Commit

Permalink
Overhauled poll:
Browse files Browse the repository at this point in the history
* Added stop attribute.
* Added widgetVar.
* Added widgetVar.stop() JS function.
* Update and execute are now processed using ExpressionResolver.
  • Loading branch information
jepsar committed May 20, 2017
1 parent 428ff45 commit ccf0dde
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 68 deletions.
207 changes: 162 additions & 45 deletions src/main/java/net/bootsfaces/component/poll/Poll.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@
*
* This file is part of BootsFaces.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.bootsfaces.component.poll;

import java.io.IOException;
Expand All @@ -27,13 +26,14 @@
import javax.faces.context.ResponseWriter;
import javax.faces.event.ActionEvent;
import net.bootsfaces.C;
import net.bootsfaces.render.Tooltip;
import net.bootsfaces.expressions.ExpressionResolver;
import net.bootsfaces.utils.BsfUtils;

/**
* The poll component refreshes a portion of the JSF view periodically via AJAX.
*
* @author Stephan Rauh
* @author Jasper de Vries <jepsar@gmail.com>
*/
@FacesComponent(Poll.COMPONENT_TYPE)
public class Poll extends HtmlCommandButton {
Expand All @@ -51,9 +51,20 @@ public class Poll extends HtmlCommandButton {
*/
public static final String COMPONENT_FAMILY = C.BSFCOMPONENT;

/**
* Property keys.
*/
enum PropertyKeys {
execute,
interval,
once,
update,
stop,
widgetVar
}

public Poll() {
setRendererType(null); // this component renders itself
Tooltip.addResourceFiles();
}

public void setValueExpression(String name, ValueExpression binding) {
Expand Down Expand Up @@ -89,49 +100,155 @@ public void encodeEnd(FacesContext context) throws IOException {
* context.getApplication().publishEvent(context,
* PreRenderComponentEvent.class, this);
*/

String id = getClientId();
String update = (String) attrs.get("update");
if (null == update)
update = "@form";
Integer intervalInMillseconds = BsfUtils.toInteger(attrs.get("interval"));
if (null == intervalInMillseconds)
intervalInMillseconds = 1000;
String execute = (String) attrs.get("execute");
if (null == execute)
execute = "@none";
String once = (String) attrs.get("once");
boolean isOnce = "true".equalsIgnoreCase(once);
String widgetVarName = getWidgetVar() == null ? BsfUtils.widgetVarName(id) : getWidgetVar();
String intervalId = "window." + BsfUtils.javaScriptVarName(id);
String update = ExpressionResolver.getComponentIDs(context, this, getUpdate());
String execute = ExpressionResolver.getComponentIDs(context, this, getExecute());

rw.append("<script id='" + id + "' type='text/javascript'>");
rw.append("\r\n");
rw.append("new function() {");
rw.append("\r\n");
rw.append(" var pollId;");
rw.append("\r\n");
rw.append(
" var handleError = function(){clearInterval(pollId);console.log('error with b:poll " + id + "');};");
rw.append("\r\n");
rw.append(" pollId = setInterval(function() {");
rw.append("\r\n");
if (isOnce) {
rw.append(" clearInterval(pollId);");
if (isStop()) {
rw.append(" clearInterval(" + intervalId + ");");
}
else {
rw.append(widgetVarName + " = new function(){");
rw.append("\r\n");
rw.append(" clearInterval(" + intervalId + ");");
rw.append("\r\n");
rw.append(" var handleError = function(){clearInterval(" + intervalId + ");console.log('error with b:poll " + id + "');};");
rw.append("\r\n");
rw.append(" " + intervalId + " = setInterval(function(){");
rw.append("\r\n");
if (isOnce()) {
rw.append(" clearInterval(" + intervalId + ");");
rw.append("\r\n");
}
rw.append(" jsf.ajax.request('" + id + "', null, {'" + id + "':'" + id + "', execute:'" + execute
+ "', render:'" + update + "', onerror:handleError });");
rw.append("\r\n");
rw.append(" }, " + getInterval() + ");");
rw.append("\r\n");
rw.append(" this.stop = function(){clearInterval(" + intervalId + ");};");
rw.append("\r\n");
rw.append("}();");
}
rw.append(" jsf.ajax.request('" + id + "',null, {'" + id + "':'" + id + "', execute:'" + execute
+ "', render:'" + update + "', onerror:handleError });");
rw.append("\r\n");
rw.append(" }, " + intervalInMillseconds + ");");
rw.append("\r\n");
rw.append("}();");
rw.append("\r\n");

rw.append("</script>");
// popComponentFromEL(context);
//popComponentFromEL(context);
}

@Override
public String getFamily() {
return COMPONENT_FAMILY;
}

/**
* Returns which input fields are to be sent? Default value: @none.
*
* @return Which input fields are to be sent? Default value: @none.
*/
public String getExecute() {
return (String) getStateHelper().eval(PropertyKeys.execute, "@none");
}

/**
* Sets which input fields are to be sent?
*
* @param execute Which input fields are to be sent?
*/
public void setExecute(String execute) {
getStateHelper().put(PropertyKeys.execute, execute);
}

/**
* Returns number of milliseconds between polls. Default value is 1000.
*
* @return Number of milliseconds between polls. Default value is 1000.
*/
public Integer getInterval() {
return (Integer) getStateHelper().eval(PropertyKeys.interval, 1000);
}

/**
* Sets number of milliseconds between polls.
*
* @param interval Number of milliseconds between polls.
*/
public void setInterval(Integer interval) {
getStateHelper().put(PropertyKeys.interval, interval);
}

/**
* Returns if the poll should called only once. Default value is false.
*
* @return If the poll should called only once. Default value is false.
*/
public boolean isOnce() {
return (Boolean) getStateHelper().eval(PropertyKeys.once, false);
}

/**
* Sets if the poll should be called only once.
*
* @param once Indicate if the poll should called only once.
*/
public void setOnce(boolean once) {
getStateHelper().put(PropertyKeys.once, once);
}

/**
* Returns which region of the screen is to be updated? Default value: @form.
*
* @return Which region of the screen is to be updated? Default value: @form.
*/
public String getUpdate() {
return (String) getStateHelper().eval(PropertyKeys.update, "@form");
}

/**
* Sets which region of the screen is to be updated?
*
* @param update Which region of the screen is to be updated?
*/
public void setUpdate(String update) {
getStateHelper().put(PropertyKeys.update, update);
}

/**
* Returns if the poll needs to stop. Default value: false.
*
* @return {@code true}, if the poll needs to stop. Default value: false.
*/
public boolean isStop() {
return (Boolean) getStateHelper().eval(PropertyKeys.stop, false);
}

/**
* Sets if the poll needs to stop.
*
* @param stop Indicate if the poll needs to stop.
*/
public void setStop(boolean stop) {
getStateHelper().put(PropertyKeys.stop, stop);
}

/**
* Returns optional widget variable to access the datatable widget in JavaScript code.
*
* @return Optional widget variable to access the datatable widget in JavaScript code.
*/
public String getWidgetVar() {
return (String) getStateHelper().eval(PropertyKeys.widgetVar);
}

/**
* Sets optional widget variable to access the datatable widget in JavaScript code.
*
* @param widgetVar widget variable name.
*/
public void setWidgetVar(String widgetVar) {
getStateHelper().put(PropertyKeys.widgetVar, widgetVar);
}

}
19 changes: 0 additions & 19 deletions src/main/java/net/bootsfaces/utils/BsfUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -707,25 +707,6 @@ public static Float[] getSliderValues(String value, boolean isArray) {
return floatList.toArray(values);
}

/**
* Convert object to integer.
* @param object
* @return Integer value of object or {@code null} if object is {@code null}.
* @throws IllegalArgumentException If object is not a string or number.
*/
public static Integer toInteger(Object object) {
if (object == null) {
return null;
}
if (object instanceof String) {
return Integer.valueOf((String) object);
}
if (object instanceof Number) {
return ((Number) object).intValue();
}
throw new IllegalArgumentException("Object is not numeric");
}

public static float getSliderValue(String value) {
Float[] values = getSliderValues(value);
if(values != null) return values[0];
Expand Down
16 changes: 14 additions & 2 deletions src/main/meta/META-INF/bootsfaces-b.taglib.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16889,13 +16889,13 @@
<description><![CDATA[How often is the poll action to be called? Denotes the number of milliseconds between polls. Default value is 1000.]]></description>
<name>interval</name>
<required>false</required>
<type>java.lang.String</type>
<type>java.lang.Integer</type>
</attribute>
<attribute>
<description><![CDATA[If true, the poll is called only once. Default value: false.]]></description>
<name>once</name>
<required>false</required>
<type>java.lang.String</type>
<type>java.lang.Boolean</type>
</attribute>
<attribute>
<description><![CDATA[Boolean value to specify the rendering of the component, when set to false the component will not be rendered.]]></description>
Expand All @@ -16909,6 +16909,18 @@
<required>false</required>
<type>java.lang.String</type>
</attribute>
<attribute>
<description><![CDATA[If true, the poll will stop. Default value: false.]]></description>
<name>stop</name>
<required>false</required>
<type>java.lang.Boolean</type>
</attribute>
<attribute>
<description><![CDATA[Optional widget variable to access the datatable widget in JavaScript code.]]></description>
<name>widgetVar</name>
<required>false</required>
<type>java.lang.String</type>
</attribute>
</tag>

<!-- *********** b:progressBar ************************* -->
Expand Down
6 changes: 4 additions & 2 deletions xtext/BootsFaces.jsfdsl
Original file line number Diff line number Diff line change
Expand Up @@ -1564,10 +1564,12 @@ widget poll
action-listener javax.faces.event.ActionListener "A method expression that refers to a method with this signature: void methodName(Action-Event)."
execute "Which input fields are to be sent? Default value: @none"
id inherited "Unique identifier of the component in a namingContainer."
interval "How often is the poll action to be called? Denotes the number of milliseconds between polls. Default value is 1000."
once "If true, the poll is called only once. Default value: false."
interval Integer "How often is the poll action to be called? Denotes the number of milliseconds between polls. Default value is 1000."
once Boolean "If true, the poll is called only once. Default value: false."
rendered Boolean inherited "Boolean value to specify the rendering of the component, when set to false the component will not be rendered."
update "Which region of the screen is to be updated? Default value: @form"
stop Boolean "If true, the poll will stop. Default value: false."
widgetVar "Optional widget variable to access the datatable widget in JavaScript code."
}

widget progressBar
Expand Down

0 comments on commit ccf0dde

Please sign in to comment.