How to refresh a BeanFieldGroup after a client request whitout a button? - ajax

i hope i will find help here.
Is it possible to refresh a single component in Vaadin.
For example do a client request which change a value [ type = String] inside a single component and refresh this component after it immediate.
Here the content for better understanding:
My Vars:
private static BeanFieldGroup<Service> binder = new BeanFieldGroup<Service>(Service.class);
private FormLayout form = new FormLayout();
My Constructor:
public ServiceDetails()
{
vl = new CssLayout();
vl.addComponent(new Label("Service Details"));
vl.addComponent(form);
vl.setStyleName("details");
vl.setSizeFull();
addPropertyChangeListener(new MyPropertyChangeListener());
refreshBT = new Button("Show Updated Content");
form.addComponent(refreshBT);
addListener();
form.addComponent(binder.buildAndBind("S-ID: ", "id"));
form.addComponent(binder.buildAndBind("Name: ", "name"));
form.addComponent(binder.buildAndBind("Description: ", "description"));
form.addComponent(binder.buildAndBind("Service Tags: ","allTagsOfService"));
form.addComponent(binder.buildAndBind("Attributes: ","allInOnAtt"));
form.addComponent(binder.buildAndBind("Capabilities: ","allInOnCapa"));
form.addComponent(binder.buildAndBind("Categorization: ","allInOnCat"));
form.addComponent(binder.buildAndBind("Relations: ","allInOnRela"));
form.addComponent(binder.buildAndBind("Stakeholder: ","allInOnStkh"));
form.addComponent(binder.buildAndBind("Resources: ","allInOnRes"));
form.addComponent(binder.buildAndBind("Quality: ","quality"));
form.addComponent(binder.buildAndBind("Process: ","process"));
form.addComponent(binder.buildAndBind("Finance: ","finance"));
form.setImmediate(true);
setCompositionRoot(vl);
}
The Button will update the shown content for the user. If a AJAX-request is done the data will be at the server but not shown. If the button is clicked the userview will be updated correctly.
Each variable change call a method which setup my content for the BeanFieldGroup.
public void setService(Service service)
{
setServ(service);
binder.setItemDataSource(getServ());
}
The Problem is now that i need to click this button for a userview refresh, if i clicked on the service inside a canvas structure. By the way this structure is realized in javascript, and a click will always do a AJAX-request [ type = POST] to the server. The send data will be saved correctly in a temporary variable but nothing will be shown at my page. The content change will not be shown to the user page. But this only appear if i use AJAX-requests. If i do click at another component it works without using the button. ):
Any idea how to fix this kind of problem.
Thx for each reply.

When working with http, you have to keep in mind, that the server usually can't inform the client about changes done on server side.
In vaadin, if you modify the UI on server side, outside of the normal "Action from client", then these changes will show up only on the next interaction with the client.
If you need to send the changes from the server to the client, you will have to use a push technology, where the server can inform the client about new/changed content.
Fortunally vaadin includes a easy to use implementation of this push system.
In the Book of Vaadin there is a complete section about server push.
Basically you add the #Push annotation to your UI class and add the required libraries.
You have to keep in mind, that you will need to synchronize access to the UI to get consistent results. (Also documented in the book of vaadin)

Related

Can I use SignalR to trigger an AJAX request on all clients?

I have a DIV in a view that must be refreshed when some data changes on the server. I can't update it regularly using an interval. The data changes as a result of a user doing something in their client.
In other words: User A clicks a button, and data changes on the server. All users should "immediately" see the change as a DIV in their page gets refreshed.
How can it be done?
I think you can follow this tutorial to realize your feature. But you need to do some changes based on the code.
First, that tutorial provides a sample which looks like a chat room, that means some in his client hit the send button, then other clients will display the newly send message immediately. So I think it really fits your scenario. All codes are provided inside the tutorial page and I show the code where you need to change below.
First, you can change the ChatHub.cs file to add the logic about updating database.
public class ChatHub : Hub
{
public async Task SendMessageToAllAndUpdateData(string user, string message, string state)
{
//write some code to update the database here
await Clients.All.SendAsync("ReceiveMessage", user, message, state);
}
}
Then you need to modify the js file which now works like append an li element to the page, but you should change it to update the data displayed before.
connection.on("ReceiveMessage", function (user, message, state) {
var li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
li.textContent = `${user} says ${message} and his state is ${state}`;
//write code here to modify the data displayed in the page
document.getElementById("stateInput").value = state;
});

Previously working (in 1.4.7) Apache Wicket 6 DataView not updating when data source SortableDataProvider is updated from a ModalWindow

As the title says, I am trying to update a web app to a more recent Apache Wicket version. The problem is very like this one here, albeit the link is very old (and an ancient version of Wicket, which is not what I'm using)
http://users.wicket.apache.narkive.com/tG6XOAUM/refresh-page-after-form-submit-within-modalwindow
So what I do is:
- display a DataView in a regular page, populated using a SortableDataProvider
- create a panel inside a ModalWindow to make some data changes;
- on onSubmit (using an AjaxFallbackButton) inside this panel, insert a new item into the same SortableDataProvider which I use to populate my DataView
- I then call "target.add(wmc)" on the WebMarkupContainer surrounding my DataView
- my DataView.populateItem registers the change when I add trace code, but the change is not actually displayed ie the screen is apparently not being refreshed.
If I do the same thing from an AjaxFallbackButton.onSubmit() NOT inside a ModalWindow, but in the same WebPage as my DataView, then all is well and I see the change on the page immediately.
I started to upgrade to Wicket 8 but there is so much else to change that I'd rather not do this right now.
I can post code if needs be but I wondered if anyone had come across this problem. As I say, fine in Wicket 1.4.7. Next step would be to create a mini-app to demonstrate this, I guess, which might well lead me to a solution anyway but hoping for some good input from that Wicket community out there ;-)
You're holding a reference from one page to another:
public class TestBugInsertItemPage extends WebPage {
private TestBugPage parent;
This not allowed in Wicket, and I wonder how this has worked in 1.4.
Your trying to update components from another window, that cannot work:
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
TestBugInsertItemPage.this.parent.dp.addLine();
target.add(TestBugInsertItemPage.this.parent.wmc);
TestBugInsertItemPage.this.parent.modal.close(target);
}
An AjaxRequestTarget is valid for a single request for a single page only.
You should use a ModelWindow with a panel instead.
Update for your second example:
Passing a panel to a different page won't make a difference. Wicket serializes pages to disk, thus you cannot share any state between them.
You should use a modal dialog with a panel instead:
TestBugPage.this.modal.setContent(TestBugPage.this.myPanel);
Now TestBugPage and your panel reside in the same component hierarchy, they communicate with each other and both can be updated on the same Ajax request.

xamarin forms webview.eval return type is voide . How to retrieve user input data?

I am working on xamarin.forms. I have a content page which contains one webview which load 3rd party url(www.xyz.com) site and one button in shell.
On button click event I am trying to get user input data using
webview.eval(javascript: var data = document.getElementById('first-name').value;alert(data)).
It works fine but due to void return type I could not store data in local variable and I have a customrender(webviewrender) but don't know on shell button click event how can I get userinput data from webview
Please suggest me how do I achieve this functionality.I do not want XLab-Hybridwebview.
You'll probably need to have the JavaScript code call out to the external code when the result is available. You could then wrap that whole process in a TaskCompletionSource to make everything nice and easy to use.

How do I debug JQuery-BootGrid data api to NancyFX

Question edited:
I wrote a page with jquery-bootgrid data API.
Its should be calling with AJAX to my NancyFX REST API, but it isn't.
Client side:
I'm serving the bootgrid from a local repo:
<script src="~/scripts/jquery.bootgrid.min.js"></script>
Maybe I shouldn't be using the .min.js file but rather the open one for debugging? If so, could you walk me through what to do, or point me in the direction?
The page code is
...
data-toggle="bootgrid" data-ajax="true"
data-url="/cars/0" data-method="GET"
Server side:
I have the html page served by NancyFx and is seen ok, except for the grid which is empty. There's an API module with a breakpoint in Visual Studio (running on localhost), with the following:
Get["/cars/{status:int}?current={current}&rowCount={rowCount}"] = parameters => ...
This code is never called. How can I force the debugger to catch ANY call before the routing is checked, and show me what's coming into the server?
I'm using the chrome debugger.
The current URL is not valid by Nancy standards. We don't add query string params to the route.
You would want to write something along the lines of:
Get["/cars/{status:int}"] = parameters =>
{
var status = (int)parameters.status;
var current = (string)parameters.current.TryParse("");
var rowCount = (int)parameters.current.TryParse(10);
...
}
Along those lines. (written off the top of my head)
An alternative approach is to bind the request like so:
Get["/cars/{status:int}"] = parameters =>
{
var request = this.Bind<MyRequest>();
...
}
public class MyRequest
{
public MyRequest()
{
RowCount = 10;
}
public int Status {get;set;}
public string Current {get;set;}
public int RowCount {get;set;}
}
Changing the nancy to Get["/cars/{status:int}"] = parameters => did the trick of catching the request.
The ajax wasn't being called because I lost the JQuery first line...
$(document).ready(function() {
To get the current and rowCount you need to use
var current = (int)Request.Form["current"];
var rowCount = (int)Request.Form["rowCount];
By the way, the Get wasn't working (I think its a Bootgrid bug) so I changed it to POST.
The simplest way to debug any jQuery library is by using the in-built debugger, it's kinda difficult for me to use chrome for that , so I use Firefox but if you are habitual of chrome then use it, the functionality is almost the same, but with Firefox you can directly switch to the events associated with any element in the html (in the inspect section)
Once you get into the debugger, set the breakpoint and refresh the page either by F5 or Ctrl+F5 if you selected the valid breakpoint you can see all the values associated with every variable also with every function.
Secondly, use the step-in option in the debugger to see where the exact line is pointing, if it's refering to any other file it will pop open automatically in the debugger menu. Firefox's spider monkey is much good at debugging and relating codes (that's totally my opinion).
3- for the api calls, the reason for data not being processed or not displayed, very much lies within the structure of the library,(on what parameters the data is called/fetched/retrieved), for this try to use the "watch expressions" option in debugger and try implementing the code on loaded dom in console section with trigger on the node which you think is bugged or which should display the value.

Extjs MVC - setting up store events in controller

I have a requirement in my application where in I need to show the UI components(like text field, combo box) based on the values i get from the server side. To be precise, I have a combobox on the page, when the user changes the values i need to send the selected value to server to get information on what needs to be displayed. Without using MVC i implemented it as below
When the user changes the value in the combobox, i refresh(using load method) another store
When i get the data back from the server('datachanged' event) i read the data and create the UI components
Now I am trying to use ExtJS MVC, so i have two questions
How do I access a store which is associated to a controller but not necessarily to any UI components from the view
How can I setup the events of a store in the controller(in the control function) just like we setup events from view
Code i want to setup events from Store like 'datachanged' in controller like below -
this.control({
'viewport > #content-panel' : {
render : this.createMainTabs
}
});
In addition to sha's reply I can say that you may setup your store eventhandlers in your controller. For example you have a combobox with a store, so you could write like this:
this.control({
'#myCombo' : {
afterrender : this.setupStoreListeners
}
});
....
setupStoreListeners: function(combo){
var store = combo.store;
store.on('datachanged', //.....);
}
And one more thing, as sha wrote you could always get store by name, but I use this only when I need to share a store instance between multiple controllers. If I need this store only in one controller, I just save it inside this controller:
setupController: function(){
this.myStore = this.getCombo().store; // now you could use this.myStore anywhere you need
}
To get store object in the controller just use this.getStore('StoreName'), each store by default has its own instance and it doesn't really matter whether it's binded to any UI component you have.
After you get store object you can subscribe to any store events using any method you prefer. I usually like
store.on('load', {...})
Also I would not change anything in UI from the view code. I would put all this customization into controller code.

Resources