Users can do this in the Presto App Store. When they add an App to "My Apps", they can set specific values for inputs. When they run it from My Apps, they see the values they chose. They can change those values and it only affects their personal version of the App.
Sara, technical writer/jackbe
If you want end users to be able to save their inputs then the easiest way would be to use browser cookies, if the end user is an authenticated Presto user then another option would be to save the form inputs to presto as Presto User Attributes.
The following code can be used to extend a Presto.BasicApp, using the same technique described here http://www.jackbe.com/enterprise-mashup/forum/hidding-input-filters, to get/set App properties using cookies:
Presto.BasicApp.prototype.onLoad = function(app){
var props, cookie = app.id + '-props', cookies = new Presto.Util.CookieProvider(),
getProperties = function(){
props = cookies.get(cookie);
if(props){
var names = app.getPropertyNames();
names.each(function(name){
if(props[name]){
// update app with stored property value..
app.setPropertyValue(name, props[name]);
// and update input form with stored value..
jQuery(app.rootElement).find('.form-field[name='+name+']').val(props[name]);
}
});
}
return props;
},
setProperties = function(){
var prop, value, changed = false,
names = app.getPropertyNames();
names.each(function(name){
prop = app.getProperty(name);
// if property is visible and is an input property..
if(!prop.hidden && prop.isinput){
value = app.getPropertyValue(name);
// and if the property value has changed..
if(props[name] != value){
changed = true;
props[name] = value;
}
}
});
// if one or more properties have chnaged then save as cookie
if(changed){
cookies.set(cookie, props);
}
},
// onload we will check if properties are stored
props = getProperties() || {};
// each time input form apply button is clicked we will check to
// see if we need to store any input properties
jQuery(app.rootElement).find('button').click(setProperties);
}
Hi Jeremy
Let me put my requirement a bit in detail, here is the sample igoogle finance widget ,www.google.com/ig/adde
This is what i want to replicate in my apps , with the code you gave to hide and show the filters worked excellent , now i want to save the value i selected in the filters , could you please share me an App and App editor script which uses the above code including the code to show/hide input filters.
I am just a complete fresher to Java coding , all we want is to set up an app with these features(as in google finance widget) so that going ahead our team can use the same template for all our applications
Thank you
Radhika
Here is a link to an extended Presto.BasicApp which uses teh above code and teh code detailed on the earlier post.
Here it is in the editor:
http://prestocloud.jackbe.com/prestohub/app-editor.html?mid=Custom_Local_Search
and the app can be viewed here:
http://prestocloud.jackbe.com/prestohub/applauncher.html?mid=Custom_Local_Search
I'll also attached a downloadable copy of the app which you can then load into App Editor by clicking "New" and uploading the zip file from your local filesystem.
Here is the full javascript code used to extend the App :
var interval = setInterval(function(){
if(Presto && Presto.BasicApp && typeof Presto.BasicApp == 'function'){
clearInterval(interval);
Presto.BasicApp.prototype.onLoad = function(app){
var root = jQuery(app.getRootElement()),
cookie = app.id + '-props', cookies = new Presto.Util.CookieProvider(),
props,
getProperties = function(){
props = cookies.get(cookie);
if(props){
var names = app.getPropertyNames();
names.each(function(name){
if(props[name]){
// update app with stored property value..
app.setPropertyValue(name, props[name]);
// and update input form with stored value..
root.find('.form-field[name='+name+']').val(props[name]);
}
});
}
return props;
},
setProperties = function(){
var prop, value, changed = false,
names = app.getPropertyNames();
names.each(function(name){
prop = app.getProperty(name);
// if property is visible and is an input property..
if(!prop.hidden && prop.isinput){
value = app.getPropertyValue(name);
// and if the property value has changed..
if(props[name] != value){
changed = true;
props[name] = value;
}
}
});
// if one or more properties have chnaged then save as cookie
if(changed){
cookies.set(cookie, props);
}
},
// onload we will check if properties are stored
props = getProperties() || {},
basicAppInput = root.find('div.basic-app-input'),
inputForm = basicAppInput.find('div.form-fields'),
header = root.parentsUntil('div.app-main').parent().find('div.app-header'),
headerLeft = header.find('h2.left'),
headerRight = header.find('div.right'),
// arrange input form horizontally..
inputs = inputForm.find('div.fieldset');
inputForm.css({
'position':'relative',
'top':'0px',
'left':'0px'
});
inputs.each(function(index){
jQuery(this).css({
position: 'absolute',
top: '0',
left: (index * 200) + 'px'
});
});
inputForm.find('button').parent().css('padding', '60px 0 0 4px');
jQuery('<span/>').addClass('app-inputs').prependTo(headerRight);
jQuery('<span/>').addClass('app-input-info').css({
'font-style':'normal',
'font-size':'13px',
'padding-left': '20px'
}).appendTo(headerLeft);
jQuery('<a/>').addClass('action-app-embed app-action publish-link')
.attr({
'title':'Show/Hide Input Form',
'href':'javascript:void(0);'
}).css('background-position', '-120px 0')
.appendTo(headerRight.find('span.app-inputs')).click(function(e){
inputForm.toggle();
});
jQuery(root).find('.action-apply').click(function(){
var inputs = '';
inputForm.find('div.fieldset').each(function(index){
if(index > 0)inputs += ', ';
inputs += jQuery(this).find('div').first().html() + ' : ' + jQuery(this).find('.form-field').first().val();
});
headerLeft.find('span.app-input-info').html(inputs);
inputForm.hide();
// finally, each time input form apply button is clicked we will check to
// see if we need to store any input properties
setProperties();
});
// hide input form and submit form :
inputForm.hide();
root.find('form').submit();};
}
}, 100);
Hi Jeremy
This works pretty good for the saving of the input parameters , please take a look at the screen cast below , the igoogle widget has a small drop down where you can give the input parameter value and click on save , its not necessary that i should have the same functionality , as we already have the apply button and the code to save the input values , the only thing i would want to see now would be the default data when the app is opened, currently my app shows input parameters when opened , can we set to display the views first then allow the user to enter the input values ?
However i have set up some default values in the mashup for input parameters, so just wanted to show the data first as in the video below ...
http://screencast.com/t/uyxFyBSQ5tJ
Please advice
Thank you
Radhika
Hi Jeremy
I have created the mashboard app using the 2 column app , and unchecked the option of hiding the title bar , which is supposed to have the little toggle button you gave me to show/hide the input values , when i use the same app in the mashboard i am unable to see that option , could you please help me in figuring out this , Please let me know if i am missing something here , this is my first mashboard app,
here is the video of what i am seeing
http://screencast.com/t/nUCV7eSB
Thank you!
A composite App created in Mashboard is called a Workspace, or Workspace App. The App Header Area, to which we added the show/hide form toggle button icon, is not available in workspace apps, workspaces provide their own contained App header, as part of the APp container.
The custom code we've been using is not suitable if the App is to be used as part of a Workspace App, the button icon is not suitable and we need to handle the different type of header.
One way to do it would be to have a control which is rendered as part of the App rather than in the header area, so it wouldnt matter if the app is rendered standalone or as part of a workspace.
Probably easiest and best solution would be to take control of the collapse/expand button icon and use it to toggle the display the App input form. We could do this, but the solution is made slightly more complicated by the fact that when the Workspace is rendered in mashboard it is implemented using Sencha Ext-js framework, but when the Workspace is rendered outside Mashboard it is rendered without Ext-js, hence the slightly different look to the header.
If its complicated to use the Workspace App with the options i am looking for , then i will stick with the initial app itself , could you please let me know if i copied the code in the right place?
I could still see the input parameters first , i want to see the graph first and then when i click the options buttons should be able to see the input values , here is the video http://screencast.com/t/4i2g4444jQAW
Strange , but i lost all the earlier functionality after embedding the new code :-(
I have made sure that i cleared all the browser history,tried both FireFox and IE8
What's probably happening is that the onLoad method isnt being defined until after the app initializes.
To fix this, in the App.xml file, towards the end of the document find the following line:
<require src="js/Extension.js" type="script"/>
and change it to :
<require loadconfirmation="Presto.BasicApp.prototype.onLoad" src="js/Extension.js" type="script"/>
all I've done there is add the attribute loadconfirmation="Presto.BasicApp.prototype.onLoad" which will cause the app to wait until our new onLoad method has been created before initializing the App.
Hi Jeremy
I implemented the same above with another app which has additional filter values , the app works fine without the above modifications like adding .js file and changing the App.xml code as above , when i do the changes i get the error
"Failed to load app - There was an error while loading '/presto/files/system/mashlets/PendTimeDistribution_1/js/Extension.js - 20 second time out.
I have cleared the browser history ...Any advice on this please ?
Thanks
Radhika
The App has timed out waiting for the js/Extension.js load condition to be met, which in your case means Presto.BasicApp.prototype.onLoad does not exist.
You will see that error if the browser fails to parse the javascript contained in js/Extension.js. So it looks like you have a bug in your javascript.
Hi
I just copied the previous code to the app , could not figure out why it works in some apps and why it does not in some apps,
I just recreated the app again , and i did not find that error again , but i see the input parameters appear first and then the graph , it does not work as the earlier apps , i am attaching all the code and a screen shot of my mashup in wires , all i did is adding couple of extra input parameters to the mashup.
4 things i needed from the code were :
1. Arrange input parameters horizontally
2.Save the input parameter values
3.Hide/Show button
4.Graph should appear first then the input parameters ,
With the current code i attached i am able to achieve all the 4 in all apps where input parameters are cluster , startdate,enddate.
Now , in the newly created mashup i have included couple of extra input parameters which are of string and date datatypes,
above 3 mentions requirements works except the 4th one....
Thanks
The app is actually working as expected in the app editor now , but not when opened in browser , here is the video
You should just need to clear your browser cache.
If you make a change to an App resource file in App Editor and the App has previously been reviewed outside App Editor then any old versio of the resource file will already be cached, so you have a choice, either clear your cache or change the url of the resource by adding a url query parameter so the spec would say:
<require type='script' src='js/Extension.js?1' loadconfirmation="Presto.BasicApp.prototype.onLoad" />
Hi Jeremy
I have posted the App to the Life Ray portal , and i dont find an options to change the input filter values , does all the work we have done for show/hide options , saving input parameter values would not be able to reflect in Life Ray ?
The user may wanted to save the input values for their requirments , Is there an option to reflect the app same as when opend in the browser?
could you please take a look at the video ...
http://screencast.com/t/tzR8XULL
Thank you
This is the same problem we have using this App in Mashboard, we loose access to the input form toggle button, which is only rendered on the App header when viewed standalone. I'm not familiar with the Liferay container implementation, it may be possible to wire a menu option to the app to display the input form, and this would be the best solution. The best solution I can suggest is to add a simple button control to the App itself, an up/down arrow to toggle the display of the input form.
Using App Editor, in your Extension.js file, immediately after the lines:
inputForm.hide();
root.find('form').submit();
append the followng code:
// add input form display toggle
jQuery('<div/>').
css({ padding:'4px'}).
attr('title','Toggle Input Form Display').
addClass('app-form-toggle app-form-show').
prependTo(basicAppInput);
basicAppInput.find('.app-form-toggle').click(function(){
inputForm.toggle();
jQuery(this).toggleClass('app-form-show');
jQuery(this).toggleClass('app-form-hide');
});
Then add a new CSS resource file to the App by clicking Add and selecting CSS, call it something like Extension.css and paste in the following lines, replacing the default text "Blank Resource Created" :
.app-form-show {
background: url(/prestohub/images/arrow-more.png) no-repeat scroll 0 0 transparent;
background-position: left;
padding-left: 10px;
cursor:pointer;
}
.app-form-hide {
background: url(/prestohub/images/arrow-less.png) no-repeat scroll 0 0 transparent;
background-position: left;
padding-left: 10px;
cursor:pointer;
}
This will display an up/down arrow in the top left of the App. I've attached an updated copy of Extension.txt with this change. You can also see this code being used here:
http://prestocloud.jackbe.com/prestohub/applauncher.html?mid=Custom_Local_Search
Thank you Jeremy , this works pretty well for the hide and show option , is there a way so that we can display the text we had in the earlier app ? like the selected input filter values ?
Basically once the app is submitted user cannot view what values are selected in the app so a display text showing the selections would be helpful and also can we change the small arrow to the gear button , or anything else which is bit bigger , a button showing "showfilters" or "hidefilter" would also be nice if it does not invlove too much coding.
Thank you...
And also , i would want the input filter to display in 3 lines ,
i have 9 input filters in my final app , and when all are arranged horizontally , user have to scroll to the far right in order to select the filters,
could you please hint me how to specify the input filters to display 3 in each line ?
Here is the code currently in the app for arranging the input filters horizontally ,
// arrange input form horizontally..
inputs = inputForm.find('div.fieldset');
inputForm.css({
'position':'relative',
'top':'0px',
'left':'0px'
});
inputs.each(function(index){
jQuery(this).css({
position: 'absolute',
top: '0',
left: (index * 200) + 'px'
});
});
inputForm.find('button').parent().css('padding', '60px 0 0 4px');
jQuery('<span/>').addClass('app-inputs').prependTo(headerRight);
jQuery('<span/>').addClass('app-input-info').css({
'font-style':'normal',
'font-size':'13px',
'padding-left': '20px'
}).appendTo(headerLeft);
jQuery('<a/>').addClass('action-app-embed app-action publish-link')
.attr({
'title':'Show/Hide Input Form',
'href':'javascript:void(0);'
}).css('background-position', '-120px 0')
.appendTo(headerRight.find('span.app-inputs')).click(function(e){
inputForm.toggle();
});
jQuery(root).find('.action-apply').click(function(){
var inputs = '';
inputForm.find('div.fieldset').each(function(index){
if(index > 0)inputs += ', ';
inputs += jQuery(this).find('div').first().html() + ' : ' + jQuery(this).find('.form-field').first().val();
});
headerLeft.find('span.app-input-info').html(inputs);
inputForm.hide();
You could order the inputs into rows with 3 inputs by change the code:
inputs.each(function(index){
jQuery(this).css({
position: 'absolute',
top: '0',
left: (index * 200) + 'px'
});
});
inputForm.find('button').parent().css('padding', '60px 0 0 4px');
to something like:
var x, y;
inputs.each(function(index){
x = index % 3;
y = Math.floor(index / 3);
jQuery(this).css({
position: 'absolute',
top: (y * 60) + 'px',
left: (x * 200) + 'px'
});
});
inputForm.find('button').parent().css('padding', (++y * 60)+'px 0 0 4px');
What we previously displayed in the app header could be displayed along side the form display toggle button.
In the attached file I've updated the extension.js file to include the code for arranging inputs in rows of 3, I've moved the gear icon from the app header and replaced the hide/show arrows, the title is now displayed to the right of this icon rather than on the header.
here is the code setting the title:
setTitle = function(){
var inputs = 'Inputs : ';
inputForm.find('div.fieldset').each(function(index){
if(index > 0)inputs += ', ';
inputs += jQuery(this).find('div').first().html() + ' : ' +
jQuery(this).find('.form-field').first().val();
});
basicAppInput.find('span.app-input-info').html(inputs);
};
Also, if you are not using the up/down arrow control then the extenion.css file we added before is not needed, so that can be removed from the App. You can see this code being used here:
http://prestocloud.jackbe.com/prestohub/applauncher.html?mid=Custom_Local_Search
although it only has 3 inputs so I changed it to render 2 items per row.




Hi
Is there an option of saving the input values in the App?
I have 3 input parameters , when shared with the user , can he save the selected filter values so that each time he opens the app, he look at the same filter selections?
Mine is presto 3.1
Thank you
Radhika