Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
Hello, I want to dynamically fill a list widget with some results from js code elaborations but I can't find how to properly set up the list (JSON?) and bind the app params to the list attributes. Is there some useful documentation on this widget? Thank you!
Solved! Go to Solution.
OK, but so far I know the working way should be similar or the same. So found in some old source something like this:
$scope.populateModelList = function() {
$scope.my_json = [
{
display: "Suspension Assembly",
value: "app/resources/Uploaded/Suspension_Low.pvz"
},
{
display: "Arm Assembly",
value: "app/resources/Uploaded/Arm_Assembly_Low.pvz"
},
{
display: "Front Hub Assembly",
value: "app/resources/Uploaded/Front_Hub_Low.pvz"
},
{
display: "Shocker Assembly",
value: "app/resources/Uploaded/Shock_Absorber_Low.pvz"
}
];
console.warn( $scope.my_json );
$scope.view.wdg['list-1']['list'] = $scope.my_json ;
$scope.view.wdg['list-1']['label'] = 'display' ;
twx.app.fn.addSnackbarMessage("assemblyList was populated","twLogo");
}
$scope.$on('$ionicView.afterEnter', function() {$scope.populateModelList();})
where the widget was a list
Hi @GianVal ,
could you clarify what means dynamically this case- is the list of widget should be selected dynamically or the data. so reading a json file and setting using a file e.g. json data is no problem . so far I know there is no general document how to do this but we can find any small example in the different help sources. I did in the past some similar issues in the past. E.g. setting from json file the value of repeater (mobile project test_repeater_dynamic-Elements.zip ) Here the list should be a dynamic value -received from json file. Ok here in this example the json file is fix but it could be also received form any where as json file form upload folder or form TWX repository.
In the second example here is shown how to read a json file and setting of values of components widget values (without explicit widget definitions) (HL attached project propSetComponetsHoloLensExamleCommunty.zip)
of course similar to this - it will work when we have already widgets e.g. the following code:
//
//Global Variables
var pjson ="properties.json"; //JSON File Name without extension
$scope.jsonData={}; //global $scope variable
gotJSON=function(data){
try{
$scope.jsonData=JSON.parse(data);
console.warn( JSON.stringify($scope.jsonData))
$scope.setMutipleProps($scope.jsonData)
}
catch(wrong){ console.warn(wrong);}
}
doRead=function (jsonFile){
fetch(jsonFile)
.then(response=>response.text())
.then(data=>gotJSON(data))
}
$scope.Init=function() {
doRead('app/resources/Uploaded/'+pjson);
}
/////
$scope.$on('$ionicView.afterEnter',function(){
console.log("$ionicView.afterEnter was called");
$scope.Init();}) //event: when 2d View loaded
//the code will read the complette JSON File and
//assignee it to a jsonData global variable
//func will set mutliple widget properties according JSON
$scope.setMutipleProps = function(obj){
Object.keys(obj).forEach(function (item) {
for(var prop in obj[item]) {
$scope.view.wdg[item][prop]=obj[item][prop];
//print the setting for debugging
console.log("==>$scope.view.wdg["+item+"]["+prop+"]="+obj[item][prop] )
}
})
};
This sample code will read a json file with widgets (explicit defined widgets) definition form json file (here example properties.json -attached /zip) and will try to set the properties of widget there
{"button-1":{"class":"button1"},"button-2":{"class":"button1"},"button-3":{"class":"button1"},"3DLabel-1":{"visible":false,"text":"This is PTC Remote Control Model"}}
sorry, let me clarify. I meant the LIST widget, the widget named LIST. In general, in my js code, I want to assign values to the list items of this widget deriving from some other data. I hope the question is clearer.
ok, please check $scope.populateModelList in the demo project (DynModelChangeUIcommunity.zip)
So it set on start the list property and do some other this but not relevant to the question
Sorry but in this example, you are populating the list of a SELECT WIDGET. As I said, I'm referring to the LIST widget
https://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FWidgetList.html
OK, but so far I know the working way should be similar or the same. So found in some old source something like this:
$scope.populateModelList = function() {
$scope.my_json = [
{
display: "Suspension Assembly",
value: "app/resources/Uploaded/Suspension_Low.pvz"
},
{
display: "Arm Assembly",
value: "app/resources/Uploaded/Arm_Assembly_Low.pvz"
},
{
display: "Front Hub Assembly",
value: "app/resources/Uploaded/Front_Hub_Low.pvz"
},
{
display: "Shocker Assembly",
value: "app/resources/Uploaded/Shock_Absorber_Low.pvz"
}
];
console.warn( $scope.my_json );
$scope.view.wdg['list-1']['list'] = $scope.my_json ;
$scope.view.wdg['list-1']['label'] = 'display' ;
twx.app.fn.addSnackbarMessage("assemblyList was populated","twLogo");
}
$scope.$on('$ionicView.afterEnter', function() {$scope.populateModelList();})
where the widget was a list
In case that you want to find what is clicked you can use this function (here example only with printings):
//==================================================================
twx.app.fn.clickItemInRepeater = function(item,list,isMultiSelect)
{
console.warn("called clickItemInRepeater() item= "+item);
console.log("twx.app.fn.clickItemInRepeater item"); console.warn(item);
console.log("twx.app.fn.clickItemInRepeater list"); console.warn(list);
console.log("twx.app.fn.clickItemInRepeater isMultiSelect"); console.warn(isMultiSelect);
};
I found a problem. In the same experience, I have a widget selected. If I choose one of the items in the select widget, the twx.app.fn.clickItemInRepeater function is triggered, but this function is set to be called by the clicked item in the list widget, thus generating a parameter passing error. How to solve this problem? thank you very much
I think the statement "this function is set to be called by the clicked item " is not correct. Possibly you intended to use this function only for specific click on items. But the function will fire on all selection (sometime it is == a click)
So I think you can check the result and decide if this is the correct event depending on the value what you will receive. So you will receive the item and the complete list and in the most cases this should be different so that when you test it you could find out what was clicked.
I think there is also another function which will be called for select list (widget select -$scope.app.fn.clickItemInSelect) - example:
//======================================================
function isThisAnObj(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
//======================================================
//this will not work for list item !!!
$scope.app.fn.clickItemInSelect= function()
{ console.log("$scope.app.fn.clickItemInSelect()");
const args = Array.from(arguments);console.log("function args.length="+args.length)
//console.log("arguments="+JSON.stringify(arguments));// this line causes an error in srtingify ??
for(i=0;i < args.length; i++)
{ if( isThisAnObj(args[i]) )
{console.log("Object::args["+i+"]=>>"); console.warn(JSON.stringify(args[i]));}
else
{console.log("primitive::args["+i+"]=>>"); console.warn(args[i]);}
}
}
//======================================================
I believe to remember that when this function is defined then it does not allow that the repeater will fire when slelect widget is clicked. Otherwise the clickItemInRepeater will be called. Therefore this could be useful to separate the selelect widget and others list. (only if you have on select and one other widget) When you have many different widget you need to check the item or list to understand the source.