Flex: create buttons dynamically and assign value from txt file - apache-flex

I made a basic text editor that lets users insert predefined strings into the document with button clicks. What I need to do now is let the user define their own buttons and string values.
For example I have a button that inserts "Hello" into the text. The user may want to create a button that adds "Goodbye".
To accomplish this I figured I would create a .txt file called buttons.txt or something. i would readutfbytee, loop through it to create the buttons. problem is I know what I want to do but not sure where to start. Can someone give me a kick start?

Please check the following code as the simple way to externalize your button settings:
/*
buttons.txt content sample:
Helo=Hello World&Test=Test Inserted
*/
protected function loadSettings():void
{
var varLoader:URLLoader = new URLLoader();
varLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
varLoader.addEventListener(Event.COMPLETE, onSettingsLoaded);
varLoader.load(new URLRequest("data/buttons.txt"));
}
protected function onSettingsLoaded(event:Event):void
{
var varLoader:URLLoader = URLLoader(event.target);
var varButtons:URLVariables = varLoader.data;
var buttons:Dictionary = new Dictionary();
for(var label:String in varButtons{
buttons[label]=varButtons[label].toString().split(",");
}
//use parsed buttons dictionary
}

For starters you need to decide how you are going to store that data that the user enters.
A flex web app can't save any files to the server, so if you want to save this across multiple computers, you'll need a server to do the data saving / retrieval.
If you want to store the buttons just temporarily, and unique to one computer, you can stuff them into a SharedObject.
After you decide this, then you can get more specific on a question of how to do exactly what you're wanting.

Related

JavaFX ComboBox store selected item in csv file

so I am using JavFX to create a form that stores all the answers in a csv file. I need to create a dropdown menu that allows the users to select an option, which is then recorded in the csv file. I have tried a lot of different options, however I think comboBox is the best option.
I have no problem creating the ComboBox, I only run into problems when it comes to the method to get the value of the box.
Can someone help me find a solution, or suggest what another JavaFX menu I can use?
This is the code I have right now:
public VBox setFamiliar(){
Button button = new Button();
button.setOnAction(e -> toString());
familiarComboBox = new ComboBox<>();
familiarVBox = new VBox();
familiarComboBox.getItems().addAll("Irmão", "Irmã", "Avó", "Avô", "Tio", "Tia", "Pai", "Mãe");
familiarVBox.getChildren().add(familiarComboBox);
familiarVBox.getChildren().add(button);
return familiarVBox;
}
Here I set the ComboBox, this part doesnt seem to have a problem because it appears and I can select an item. I created a separate void toString() method that sets the value of a variable to the current selected item
public void toString(ActionEvent e){
familiar = familiarComboBox.getSelectionModel().getSelectedItem().toString();
}
The problem is then in the get method to get the value that was selected.
public String getIrmao(){
if(familiar.equals("Irmão")){
return "2";
}
return "0";
I also tried to do familiarComboBox.getSelectionModel().getSelectedItem().equals(), and other variations of this combination.
If I understand your requirement -- that when a user makes a choice from the "Familiar" combo box, a value should be written immediately to a CSV file -- you don't need the getIrmao() method. You simply write the value out in the action which you are calling toString(...) (not a good choice of names), but which we will rename to handleFamiliarChange(...).
Now the method becomes
public void handleFamiliarChange(ActionEvent e){
final String familiar =
familiarComboBox.getSelectionModel().getSelectedItem().toString();
FileUtils.writeToCsvFile(familiar.equals("Irmão") ? 2 : 0);
}
where FileUtils.writeToCsvFile(...) is a method that does the file writing. Note that FileUtils is a class you have created to separate out file handling concerns -- your JavaFX view class should only concern itself with views.

Handling browser refresh with query filters from page parameters

I have two data sources
Assets
Locations
Assets has a One to Many relation with Locations
Assets has a query builder data source, AssetLocFiltered, that is set with the following:
ParentLocationKey =:ParentLocationKey
ParentLocationKey is the relation field for the locations table.
On the home page you select a location and then click a button that passes the location ID to a parameter on the ShopPageDemo page. with the following code
app.pages.ShopPageDemo.properties.ParentLocationKey =
widget.datasource.item.Id;
console.log(widget.datasource.item.Id);
app.showPage(app.pages.ShopPageDemo);
One the ShopPageDemo Page there is a table view of the AssetLocFiltered that sets the query parameter in the ondataload event with the following code:
widget.root.datasource.query.parameters.ParentLocationKey =
widget.root.properties.ParentLocationKey;
widget.root.datasource.load();
This works great. The problem is when i hit the browser refresh it seems like it clears the property in ShopPageDemo. How do I handle this browser refresh issue? I am not really sure where to start.
There is more than one way to do this; However, the approach I usually take involves deep linking. In your case, you'll need to do something like this:
1.) On the button that takes you to the next page, add this code:
var params = {
key: widget.datasource.item.Id
};
var page = app.pages.ShopPageDemo;
app.showPage(page);
google.script.history.replace(null, params, page.name);
2.) On the ShopPageDemo onAttach event handler, add the following:
google.script.url.getLocation(function(location) {
widget.root.properties.ParentLocationKey = location.parameter.key;
var ds = widget.datasource;
ds.query.parameters.ParentLocationKey = widget.root.properties.ParentLocationKey;
ds.load();
});
For better performance, I would set the ShopPageDemo datasource to NOT load automatically and also to unload its data on the onDetach event handler like this: widget.datasource.unload().
Reference:
1. https://developers.google.com/apps-script/guides/html/reference/history
2. https://developers.google.com/apps-script/guides/html/reference/url

Is it possible to create multiple draft items on createdatasource?

I am building an application that will have the ability to create agenda items to discuss in a meeting. The agenda item might include one or more attachments to discuss so there is a one to many relation between the AgendaItems and the AgendaDocs models. So far, I have an insert form that looks like this:
The "Select File" button is a drive picker and the code I have inside the onDocumentSelect event is the following:
var docs = result.docs;
var createDataSource = app.datasources.AgendaDocs.modes.create;
for(var i=0; i<docs.length-1; i++){
var uniqueDraft = createDataSource.item;
createDataSource.items.push(uniqueDraft);
}
for(var i=0; i<createDataSource.items.length-1; i++){
var draft = createDataSource.item;
createDataSource.items[i].DocTitle = docs[i].name;
createDataSource.items[i].DocURL = docs[i].url;
createDataSource.items[i].DriveID = docs[i].id;
}
console.log(createDataSource.items);
The code is supposed to fill out the the List widget below the "Select File" button, but as how you see, the three items are the same. The datasource of the List widget is "AgendaDocs.modes.create" and the datasource of the insert form is "AgendaItems.modes.create".
Reading the official documentation from appmaker, makes me think it is possible since the properties of "CreateDataSource" includes "items". I need help from an expert here. Is this possible? Am I using the wrong approach?
First things first, it seems that you are trying to create records from different models and relationship between them in a one call... at this time App Maker is not that smart to digest such a complex meal. Most likely you'll need to break your flow into multiple steps:
Create (persist) Agenda Item
Create AgendaDocs records and relation with AgendaItem
Similar flow is implemented in Travel Approval template app, but it is not exactly the same as yours, since it doesn't create associations in batches.
Going back to the original question. Yep, it is possible to have multiple drafts, but not with the Create Datasource. You are looking for Manual Save Mode. Somewhere in perfect world your code would look similar to this:
// AgendaItems in Manual Save mode
var agendaDs = app.datasources.AgendaItems;
// this line will create item on client and automatically push it
// to ds.items and set ds.item to it.
agendaDs.createItem();
var agendaDraft = agendaDs.item;
// Field values can be populated from UI via bindings...
agendaDraft.Type = 'X';
agendaDraft.Description = 'Y';
// onDocumentSelect Drive Picker's event handler
var docsDs = agendaDs.relations.AgendaDocs;
result.docs.forEach(function(doc) {
// this line will create item on client and automatically push it
// to ds.items and set ds.item to it...however it will throw an exception
// with this message:
// Cannot save a foreign key association for the 'AgendaItem'
// relation because the target record has not been persisted
// to the server. To fix this, call saveChanges()
// on the data source for that record's model: AgendaItem
docsDs.createItem();
var docDraft = docsDs.item;
docDraft.DocTitle = doc.name;
docDraft.DocURL = doc.url;
docDraft.DriveID = doc.id;
});
// submit button click
agendaDraft.saveChanges();

Allow user to copy data from TableView

I have a simple JavaFX app that allows the user to query a database and see the data in a table.
I'd like to allow the user to be able to click a table cell and copy text from that cell to the clipboard with the standard clipboard key stroke: ctrl-c for Win/Linux or cmd-c for Mac. FYI, the text entry controls support basic copy/paste by default.
I'm using the standard javafx.scene.control.TableView class. Is there a simple way to enable cell copy? I did some searches and I see other people create custom menu commands... I don't want to create a custom menu, I just want basic keyboard copy to work with single cells.
I'm using single selection mode, but I can change to something else if need be:
TableView<Document> tableView = new TableView<Document>();
tableView.getSelectionModel().setCellSelectionEnabled(true);
tableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
You just have to create a listener in the scene, something like:
scene.getAccelerators()
.put(new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY), new Runnable() {
#Override
public void run() {
int row = table.getSelectionModel().getSelectedIndex();
DataRow tmp = table.getItems().get(row);
final Clipboard clipboard = Clipboard.getSystemClipboard();
final ClipboardContent content = new ClipboardContent();
if(table.getSelectionModel().isSelected(row, numColumn)){
System.out.println(tmp.getNumSlices());
content.putString(tmp.getNumSlices().toString());
}
else{
System.out.println(tmp.getSelected());
content.putString(tmp.getSelected());
}
clipboard.setContent(content);
}
});
For a complete example, you can download it at the gist.
I recommended that you review this post, work for me
http://respostas.guj.com.br/47439-habilitar-copypaste-tableview-funcionando-duvida-editar-funcionalidade
The author use an aditional util java class for enable the cell content copy from a tableView

ASP.Net Auto-populate field based on other fields

I've just moved to web development and need to know how i can implement below requirement using asp.net and vb.net.
I have three fields in a form which are filled by users. Based on these three values, i need to auto-populate the 4th field. I have planned to implement this in the following way
Write a separate class file with a function to calculate the possible values for the 4th fields based on 1st 3 inputs. This function can return some where between 1-10 values. So I've decided to use drop-down for 4th field, and allow users to select the appropriate value.
Call the above function in onchange function of 3rd field and take and use the return values to populate the 4th field. I'm planning to get the return values in array field.(Does this need a post back?)
Please let me know how if there is better way to implement this.
Thanks.
You may want to consider doing this with Javascript. You could read and control the fields pretty easily with pure Javascript, or using a nice library like jQuery (my favorite). If you did it this way, no post-back would be required and the 4th field would update immediately. (Nice for your users)
You can also do it with ASP.NET for the most part. "onchange" in ASP.NET still requires Javascript as far as I know, it just does some of it for you. A post-back will definitely happen when you change something.
You need javascript or to set autopostback=true on your form elements.
From a user perspective the best thing is to use javascript to populate the field for display, BUT when the form is submitted use your backend function to validate it. This will make sure the user didn't change the value.
An easy way is to use jQuery for the UI (that way you don't have to worry about long winded javascript and deal with browser compatibility as it's already taken care of for you) and have it call to the server for the data. For the server, your easiest route is to return JSON for looping values.
Include your jQuery:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
Then add in a handle for the JavaScript:
<script type="text/javascript">
function autoPopulate() {
var value1 = $('#ddl1').val();
var value2 = $('#ddl2').val();
var value3 = $('#ddl3').val();
var url = 'path/to/your/file.aspx?value1=' + value1 + '&value2=' + value2 + '&value3=' + value3;
$.getJSON(url, function(data) {
data == null ? return false : data = eval(data);
var ddl = $('#ddl4')[0];
for (i = 0; i < data.length; i++) {
var option = new Option(data[i][0], data[i][1]);
if ($.browser.msie) {
ddl.add(option);
} else {
ddl.add(option, null);
}
}
}
}
</script>
(Yes, I know I used a native loop but I'm little lazy here today :) )
Now, for your server side code you'll want your code your page to return data in the format of:
[['value1','text1'],['value2','text2'],['value3','value3']]
so something like:
<script type="vb" runat="server">
Private Sub Page_Init()
// get your data
// loop through it and add in values
// ex.
Dim result As String = "[" //start multi-dimensional array
For Each Item As String In data
result += String.Format("['{0}','{1}'],", _value, _text)
Next
result = result.SubString(0, result.Length - 1) // removes trailing comma
result += "]" // closes off m-array
Response.Write(result)
Response.Flush()
End Sub
</script>

Resources