I would like to know, how to save data from widget code (not configuration).
My goal is to remember some value and show an arrow (up: current value is higher than previous, down: it is lower than previous).
I'm loading data with ExtensionDataService:
// Get the data service
VSS.getService(VSS.ServiceIds.ExtensionData).then(function(dataService) {
// Load previous values
dataService.getValue("PrevValues", {scopeType: "Default", scopeValue: "Current", defaultValue: ""}).then(function(value) {
PreviousValues = value;
// do some calculations
});
});
And after calculations, I'm saving data:
// Get the data service
VSS.getService(VSS.ServiceIds.ExtensionData).then(function(dataService) {
// Save previous values
dataService.setValue("PrevValues", PreviousValues, {scopeType: "Default", scopeValue: "Current"}).then(function(value) {
});
});
Let's say the widget is called DoMyOwnCalculations
The problem is, that I have 2 (or more) widgets DoMyOwnCalculations on dashboard. Each of them is doing some calculations based on configuration and each of them should remember it's own result.
With the solution presented above, I'm always getting the same data.
An quick example:
First widget saved "1" as a result, second saved "2".
After this, when reading the value I always get "2".
Is it possible to store data with the same key ("PrevValues"), but separately for each widget placed on dashboard?
Thank you in advance
Slawek
No, it's impossible, as the key ("PrevValues") always point to the same value.
Related
Need to find way to add hyperlinks to components of an assembly in the a360 viewer such that, when clicked or touched with mobile device, will navigate to a web page for more information. Realize it requires Forge API but can't find any specific examples of such a solution. I think this can be done from a properties table but I want direct navigation from touching/clicking the object.
You could just subscribe to the object selection event and react to it by e.g. opening a given URL:
viewer.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
function (event) {
// Get id of first selected item
var dbId = event.dbIdArray[0];
if (dbId) {
// Maybe get the properties of the selected object
viewer.getProperties(dbId, function (props) {
// Depending on the properties you could open a website
// Just printing to the console the external id of
// the selected component as an example
console.log(props.externalId);
});
}
}
);
If you search for "Autodesk.Viewing.SELECTION_CHANGED_EVENT" you can find some articles and samples also using this event, e.g. https://forge.autodesk.com/blog/selection-override
I have 2 CustomTables with same column names. They are created using expandratio width.
I added resizecolumnlisteners to them so when user column in table1 resize also table2 and vice versa. Problem is when resizing with
List<Values> list;// list of objects in table;
table1.addresizeColumnListener(new resizeColumnListener(){
private void resizeColumn(Event)
{
for(int i=0; i<list.size(); i++)
{
table2.setColumnWidth(list.get(i), table1.getColumnWidth(list.get(i)));
}
}
in table changes only column where listener is fired all others dont change, only when i click any column again all column's widths in table2 is set from table1.
I have too low stackoverflow reputation level to add a comment - so I'm writing this answer.
First of all: Which version of Vaadin do you use? I can't find the function which you used:
table1.addresizeColumnListener(...)
In Vaadin latest documentation is addColumnResizeListener.
And I have doubt why you want change size of all column after notification that one column has been changed? I imagine that after each column size change the Table.ColumnResizeEvent should be emit.
I think the problem you are facing is that when you re-size something in the browser, it will not get sent to the server straight away. The update to the server is sent to the server along with the next update request. That is why you get the delayed update to the UI (if I understood it correctly).
To fix this you can try the code below. Notice the setImmediate(true). This will basically tells Vaadin that you want any update to the table to be sent to the server immediately when the user modifies the table properties.
Try this:
table1.setImmediate(true);
table1.addColumnResizeListener(new ColumnResizeListener(){
#Override
public void columnResize(ColumnResizeEvent event) {
table2.setColumnWidth(event.getPropertyId(), event.getCurrentWidth());
}
});
table2.setImmediate(true);
table2.addColumnResizeListener(new ColumnResizeListener(){
#Override
public void columnResize(ColumnResizeEvent event) {
table1.setColumnWidth(event.getPropertyId(), event.getCurrentWidth());
}
});
I have the following fragment in a web component:
<div id="mycodes">
<template iterate='code in codeList'>
{{code}}
</template>
</div>
And in a Dart file, codeList is populated when the user clicks on a button:
void onMyButtonClick(Event event) {
HttpRequest.getString('http://getData').then((response) {
mylist = json.parse(response);
for(var code in mylist){
codeList.add(code['c']);
}
}
The problem is that I don't see data on first click. I need to click the button twice to see data.
But if I fill codeList manually (not from network data) as shown below, then I see the data on first click:
void onMyButtonClick(Event event) {
codeList.add("data 1");
codeList.add("data 2");
}
}
I need the template to iterate after the network data is available. It appears that event loop has already done its job of painting a page before the network data becomes available through future object.
Is there a way to refresh the page after model is updated in dart?
The reason your codeList currently populates if you add it with the on-click event is because the current web_ui has 'watchers' which automatically are called when an event happens. You then populate the list synchronously. However one of the downfalls of watchers is exactly your use case, when the data is updated asynchronously then the watchers don't reflect changes in time.
As a result the watchers are being phased out and replaced with observables. Observables allow us to flag a variable to be watched for reassignment and when that happens it will cause the view to change. For example:
#observable int x = 0;
// ...
x = 1;
When the x = 1 is called later in the code it automatically triggers the views to update. This leaves us with one problem however. When you are adding to a list, you are not reassigning the value itself. As such, observables also offer a function to convert a list to an observable list (this also works for maps).
For instance if you changed your declaration of codeList to something like the following, then when you add to the list later it will update accordingly.
var codeList = toObservable([]); // Assuming it starts with an empty list
// or
var codeList = toObservable(_startCodeList); // if you already have a list
Also see the Dart Tutorial: Target 7 for more information on using #observable and toObservable.
For more in-depth information, check out the article on Observables and Data Binding
You need to mark the fields you want WebUi to monitor with the #observable annotation. Otherwise you only get the initial value not any subsequent updates.
You can do this either directly on the object declaration or you can make the entire class as observable and all its fields will then be observed.
For an example see http://www.dartlang.org/docs/tutorials/custom-elements/#using-two-way-data-binding
In the ASP MVC page I'm currently working on, the values of three input fields determine the value of a fourth. Zip code, state code, and something else called a Chanel Code will determine what the value of the fourth field, called the Territory Code, will be.
I just started learning jQuery a couple weeks ago, so I would first think you could put a .change event that checks for values in the other two fields and, if they exists, call a separate method that compares the three and determines the Territory code. However, I'm wondering if there is a more elegant way to approach this since it seems like writing a lot of the same code in different places.
You can bind a callback to multiple elements by specifying multiple selectors:
$(".field1, .field2, .field3").click(function() {
return field1 +
field2 +
field3;
});
If you need to perform specific actions depending on which element was clicked, another option would be to create a function which performs the actual computation and then invoke that from each callback.
var calculate = function() {
return field1 +
field2 +
field3;
};
And then invoke this function when on each click:
$(".field1").click(function() {
// Perform field1-specific logic
calculate();
});
$(".field2").click(function() {
// Perform field2-specific logic
calculate();
});
// etc..
This means that you do not repeat yourself.
This works for me
jQuery(document).on('scroll', ['body', window, 'html', document],
function(){
console.log('multiple')
}
);
Adding another possibility, just in cased this may help someone. This version should work on dynamically created fields.
$("#form").on('change', '#Field1, #Field2, #Field3', function (e) {
e.preventDefault();
console.log('something changed');
});
I have two g:textfields
in the first one I should write a number lets say 12 and in the g:textfield next to it it should load the predetermined name for number 12.
The first one is named 'shipper' and the other 'shipperName'
Whenever I write the code 12 in the 'shipper' txtfield, it should return the name of the shipper in the 'shipperName' box.
Thanks in advance!
Examples:
If I write the number 12 it should return USPS
http://i53.tinypic.com/2i90mc.jpg
And every number should have a different 'shipperName'
Thanks again!
That's quite easy if you'll use jQuery. Check out the event handlers ("blur" is the one you want which occurs when the user leaves the numerical box).
For example:
$("#shipper").blur(function() {
$("#shipperName").load(
"${createLink(controller: 'shipper', action: 'resolveShipper')}?id=" +
$("#shipper").val()
);
});
The $(this).val() at the end is the value of the input field the user just left.
And the "ShipperController.resolveShipper" action would look something like this:
def resolveShipper = {
render text: Shipper.get(params.id).name, contentType: "text/plain"
}
There are other things you might want to do, like automatically filling in the shipperName field as the user types without leaving the edit field, probably after a delay. However the event handler stays the same, just the event is changing (from "blur" to "change" or something like this)
To relate two strings, it's easiest to use an object to create a dictionary/ map, as shown below;
$('#input1').bind('keyup',function() {
var map = {
"1":"One",
"2":"Fish",
"3":"Bar"
};
$('#input2').val(map[$(this).val()]);
});
You can see this in action here: http://www.jsfiddle.net/dCy6f/
If you want the second value only to update when the user has finished typing into the first input field, change "keyup" to "change".