Get primefaces widgetVar in javascript and update it - javascript

I have a primefaces component like this:
<p:panel styleClass="errorsPanelClass" id="errorsPanel" header="Messages" toggleable="true" effect="drop" toggleSpeed="0" closeSpeed="0" widgetVar="errorsPanelWidget">
and i'm trying to get the component in javascript context and update it.
I already tried with:
function getWidgetVarById(id) {
for (var propertyName in PrimeFaces.widgets) {
if (PrimeFaces.widgets[propertyName].id === id) {
return PrimeFaces.widgets[propertyName];
}
}
}
or
How to find a widgetVar?
or
Get widgetVar with JavaScript or check/uncheck all other PrimeFaces checkboxes
It will be great if I'll find a solution to take the widgetVar by class, but any other solutions are welcomed.
I also tried:
function getWidgetVarById() {
for ( var propertyName in PrimeFaces.widgets) {
alert(PrimeFaces.widgets[propertyName].id);
}
}
but I get an javascript error "'PrimeFaces.widgets.length' is null or not an object"
Any ideas?

There is not mapping between the id and a widgetVar for PrimeFaces 3.5. In 3.5 the widgets are added to the 'window' object and not stored somewhere else. This means that the widgetVar is already directly a variable u can use.
<p:panel id="errorsPanel" widgetVar="errorsPanelWidget">
3.5/4.0: (in 4.0 this still works but is deprecated in favour of the PF('..') way)
errorsPanelWidget.close()
5.0 and up:
PF('errorsPanelWidget').close() (unless you configure the legacy mode after which it will behave like 3.5/4.0)
Easiest is then to use a convention that you name your widgetVar like your id but with a postfix e.g. id_widget. You could (advise against it) leave the widgetVar out and then the widget is idententical to the id (this can cause classhes in cases, that is why PF dropped this convention).
And you could still check if in 3.5 the widgetVar value is in one way or another added to the outer html element of the widget. You could then retrieve it with some jquery. Personally, I used the 'convention' way in previous PF versions (appending 'Widget' to the value that is also in the id and putting that in the widgetVar attribute)
And if with 'updating' the widget, you mean updating the content of the widget, you can't. There is no refresh() kind of method that does this. What you could do is send the id(!) to the server and execute an update(..) there via the requestContext like this
RequestContext context = RequestContext.getCurrentInstance();
context.update("errorsPanel");
But it might be even better to just to this the moment you update the list serverside. So it might be that you've fallen into the XY trap.
But if it is really needed, here is an example that works, using the PrimeFaces extensions remoteCommand since that is the easiest way)
xhtml:
<pe:remoteCommand id="refreshWidgetCommand" name="refreshWidget" process="#this" actionListener="#{updateWidgetController.refresh}">
<pe:methodSignature parameters="java.lang.String"/>
<pe:methodParam name="id"/>
</pe:remoteCommand>
Bean:
#ManagedBean
#RequestScoped
public class UpdateWidgetController {
public void refresh(final String id) {
RequestContext context = RequestContext.getCurrentInstance();
context.update(id);
}
}
calling refreshWidget('errrosPanel'); will achieve what you want.
Don't wan't to use PFE (or can't use this due to version incompatibilities), you can achieve the same with PF remoteCommand But the specific example for 3.5 might differ a little

Related

How can I change Vaadin Components in Java through Javascript

I implemented Shepherd in my Vaadin Project, so i can guide users in tours through my web application.
But, i need to get access from the javascript on the Accordion Components in Vaadin, to open or close specific tabs. For this, i need to have access on the open() and close() method for the Accordion Components. So how can i access them through Javascript?
Already seen the Tutorial on the Website of them:
Vaadin calling java from javascript,
but sadly nothing over there, what could help me.
I already tried to use something like this:
UI.getCurrent().getPage().executeJs("window.startTour($0, $1)", this, Accordion1.getElement());
But when i try to bind it in javascript through:
window.startTour = (element, accordion) => { ... }
and in this window:
beforeShowPromise: function () {
return new Promise(function(resolve) {
element.$server.openAccordion(accordion.$server, 1);
resolve();
});
},
with the following method in java:
#SuppressWarnings("unused")
#ClientCallable
public void openAccordion(Object object, int index) {
Accordion accordion = (Accordion) object.get(this);
accordion.open(index);
}
i only get the following error message:
Class '...' has the method 'openAccordion' whose parameter 0 refers to unsupported type 'java.lang.Object'
No matter what i use as first parameter, everythin that extends Object doesnt work and i dont know why.
I found a recent post with the same question, but it was not helpful for me:
Unable to send a new bean instance to the server
Im using Intellij and in my Project: Java, Spring, Vaadin and Shepherd
Already tried to use different parameters, but only the int parameter is working, Object doesnt work.
The Problem is, i cant change the opened Tab of the Accordion from the Javascript over the Java, because of this error, so i have to implement for each Accordion 2 methods to open and close it.
Maybe somebody can help me with it or knows some tricks to master this.
Thanks
When using #ClientCallable you can pass only json or primitive types from JavaScript call to server. There is a real systems boundary here. Object is not supported and furthermore, you can cast that parameter to Java object.

JQuery Mobile and Scala.js: How to call functions like "navbar()" or "toolbar()"?

In JQuery mobile, to make persistent headers, footers and nabbers work as expected, you have to do something like this:
$(function() {
$( "[data-role='navbar']" ).navbar();
$( "[data-role='header'], [data-role='footer']" ).toolbar();
});
What is the equivalent in Scala.js?
As usual in Scala.js, as a first "draft" you can always use the dynamically typed API:
js.Dynamic.global.$("[data-role='navbar']").navbar()
If you want a statically typed API, you can define it. As far as I know, no one has written facade types for jQuery mobile yet. However, there are facades for jQuery itself, such as 1. You can then "pimp" additional methods provided by a jQuery plugin, such as jQuery mobile, using the monkey patching pattern for Scala.js facades:
import org.querky.jquery._
trait JQueryMobile extends JQuery {
def navbar(): Unit
}
implicit def JQueryMobileOps(jQ: JQuery): JQueryMobile =
jQ.asInstanceOf[JQueryMobile]
and then you can do:
$("[data-role='navbar']").navbar()
and it will be statically typechecked.

How to access ZK components from JavaScript

I want to set value of a zk datebox from javascript. Actually I can set the value but when I want to access its value, it is throwing a null pointer exception. More generally, some abilities of the zk components can be manupulated but others not. For example I can fire a button onclick event but I can not set an attribute of that button by javascript.
For example these two work :
zk.Widget.$('$startDateProxy').setValue(start); zk.Widget.$('$addEventBtn').fire('onClick');
But these two not:
zk.Widget.$('$startDateProxy').setAttribute("startDate",start) -> cutting the operation
alert(startDateProxy.getValue().toString()) -> null pointer
Thanks
PS: I am trying to use FULLCALENDAR (arshaw.com/fullcalendar)
Thank you for your answer. startDateProxy component is Datebox, not Calendar. Sorry for missing information. I solved the problem by using AuService. I defined a hidden button. Fired its onClick with the parameters. Sample usage:
Client Side:
zk.Widget.$('$eventBtn').fire('onClick',{start : start ,end : end});
Server Side:
public void service(AuRequest request, boolean everError) {
if (Events.ON_CLICK.equals(request.getCommand())) {
Map data = request.getData(); // can be read start,end parameters from here
//dosomething here
}
Try it instead
alert(this.$f('addEventBtn').getLabel());
The Class Calendar does not have a setAttribute method (see the docs).

Is it possible to receive Objects from the JS side via WebView.addJavascriptInterface?

Can I receive an Object through the WebView.addJavascriptInterface interface ? something like:
public class JavaScriptInterface {
public void method(WhatEverKindOfType param) {
Log.i(tag, param.toString());
}
}
( with: theView.addJavascriptInterface(new JavaScriptInterface(), "obj"); )
and in the JS, for example: obj.method(myEvent);
I obviously tried that, with Object param and String param, but they all come as null. I know I can JSON.stringify it, but this brings that circular object issue (which is solvable, I know, but I don't want to start messing with it)
Is it even possible ?
First off you should not use addJavascriptInterface if you are using PhoneGap. Please, please write a PhoneGap plugin instead. The reason you want to use our Plugin interface is that we have worked around a number of issues with addJavascriptInterface.
When you use the plugin interface you pass a JSONArray to the Java side. That supports all the basic types like int, String, boolean and of course JSONObject. It is the JSONObject that you can store more structured data.

Instantiating javascript objects from ASP.NET Pages

Most of the examples you find on the web, of using javascript from ASP.NET pages puts the javascript in the markup file (*.aspx). This is, of course, a really bad idea(tm), for all but the simplest uses of javascript.
What we want, of course, is to wrap the javascript up into a class, and to instantiate an instance of that class and tie it to the code-behind.
Microsoft provides a framework for doing this for user controls and server controls, in its IScriptControl interface. This allows a developer to create a javascript "component" - to define a javascript class in a *.js file, to include the *.js file on the page that contains the control, to instantiate an instance of the component, to set variables in the component from values in the code-behind, and to get a reference to the component in javascript on the client side.
The thing is - IScriptControl only works for user and server controls. It cannot be used to instantiate javascript objects at the page level.
So - how do people do this? We have some patterns we've been using, that seem to work. I was wondering what everyone thought of them, and what other people were using.
We start by defining a javascript class in a *.js file. In the code-behind, we create a loadJavascript() function, that we call from Page_Load on initial load or full postback (but not on partial postbacks).
In loadJavascript(), we include the *.js file with ScriptManager.RegisterClientScriptInclude(), and then construct a bit of javascript that instantiates an instance of the class, assigns a reference to a known name, and registers the object's initialize() and dispose() methods as handlers for window.load and window.unload.
E.g.:
string url = this.ResolveUrl("./FooBar.js");
ScriptManager.RegisterClientScriptInclude(this, this.GetType(), url, url);
string script = #"
if (typeof {0}_obj == 'undefined')
{0}_obj = {{}};
{0}_obj.fooBar = new FooBar();
Sys.UI.DomEvent.addHandler(window, 'load',
function()
{{
{0}_obj.fooBar.initialize('{1}', '{2}');
}}
);
Sys.UI.DomEvent.addHandler(window, 'unload', {0}_obj.fooBar.dispose);
";
script = String.Format(script,
new object[]
{
this.ClientID,
this.foo.ClientID,
this.bar.ClientID
});
ScriptManager.RegisterStartupScript(
this, this.GetType(), this.ClientID, script, true);
We construct an object name in the global namespace, based on the ClientID of the page, if we haven't already. We add an instance of our new class as a member of our global object. We add a window.load handler that calls our object's intialize() method, passing the clientIDs of the controls on the page that the object's methods need to access. And we add a window.unload handler that calls our object's dispose() method, that does whatever cleanup that is necessary.
This seems to be working, for us. We've used this pattern on a number of pages, some of which did significant amounts of partial-postbacks, without any problems.
I was wondering, first, what people thought of the pattern.
But more, I was wondering if we'd been reinventing the wheel, and if there were other approaches to dealing with the issues we were addressing, that we weren't aware of.
Anyone have any better ideas?
But more, I was wondering if we'd been reinventing the wheel, and if there were other approaches to dealing with the issues we were addressing, that we weren't aware of.
I think this the most good approaches, I use the same way some years now with out any problem in very complex javascript code. I do not see why you question your self :)
The idea is this you follow, now maybe there are some variations, maybe I not call the unload, nether create an object to keep the foobar and call the foobar rightway, but the idea is the same. I also check if the Javascript file have been loaded...
string script = #"
if (typeof (FooBar) != "undefined") {{
var {0}fooBar = new FooBar();
Sys.UI.DomEvent.addHandler(window, 'load',
function()
{{
{0}fooBar.initialize('{1}', '{2}');
}}
);
}}

Categories

Resources