I have a form with a grid of a tempTable. One of the columns in the grid displays the 'existsAlready' property:
FM_MovieTemp movie = ds.getFirst(1);
while (movie)
{
if (movie.existsAlready)
{
existingMovies = true;
}
info(movie.Title);
movie = ds.getNext();
}
if (existingMovies)
{
DialogButton Button;
Button = Box::okCancel("Test",DialogButton::No);
if (Button == DialogButton::Ok)
{
FM_MovieTemp movieBuffer = ds.getFirst(1);
FM_MoviePersistLogic::PersistToDatabase(movieBuffer);
}
}
Called function:
public static boolean PersistToDatabase(FM_MovieTemp fM_MovieTemp)
{
}
The problem with this code is that, while the movieBuffer variable is filled with the data of the selected grid rowswhen it is created before the call to PersistToDatabase, it is empty in when received in the PersistToDatabase function. Could someone explain why this is and how I should correctly supply my selected grid rows to the other class?
Related
I have a text field that I want to limit to integers only. See the code below.
When the view containing the field starts, and if the model is constructed with an initial default value for someInteger, the view displays the number correctly, without extra formatting. It also filters new typed input as expected.
A problem arises when refactoring the model not to have a default value. Being an integer property, it defaults to 0. When I later assign a new value to the property, the controlNewText passed contains punctuation, such as 1,234. That causes the check to fail and the newly assigned value to be filtered out of the view.
Why is the controlNewText getting formatted in the first place? Is there a way to prevent that?
textfield(model.someInteger) {
required()
textFormatter = TextFormatter(IntegerStringConverter(), model.item.someInteger)
stripNonInteger()
filterInput { it.controlNewText.isInt() }
}
class SomeData {
val someIntegerProperty = SimpleIntegerProperty(this, "someInteger")
var someInteger by someIntegerProperty
}
class SomeDataModel : ItemViewModel<SomeData>(SomeData()) {
val someInteger = bind(SomeData::someIntegerProperty)
}
The formatting is performed by the TextFormatter you specified. Make sure to specify one that doesn't add thousand separators. Here is a complete runnable application that configures a NumberStringConverter inside the formatter. Notice that I've removed the filterInput statement, as that's already covered by stripNonInteger.
class MainView : View("Main view") {
val model = SomeDataModel()
override val root = borderpane {
center {
form {
fieldset {
field("Some integer") {
textfield(model.someInteger) {
required()
textFormatter = TextFormatter(NumberStringConverter("########"), model.someInteger.value)
stripNonInteger()
}
}
button("Set some value").action {
model.someInteger.value = 1234
}
}
}
}
}
}
class SomeData {
val someIntegerProperty = SimpleIntegerProperty(this, "someInteger")
var someInteger by someIntegerProperty
}
class SomeDataModel : ItemViewModel<SomeData>(SomeData()) {
val someInteger = bind(SomeData::someIntegerProperty)
}
I currently have two tableviews in one screen, which results in both TableViews have rows which the user can select.
Now I want only one row to be selected at the same time (doesn't matter which TableView it is selected from). I was thinking about some kind of listener which deselects the other row when a row is selected. This is my initial setup:
Step 1
Search for a way to bind a method to the selection of a row (there is not something like tableview.setOnRowSelected(method))
Step 2
Create the method which acts like a kind of listener: when a row is selected, deselect the other row (I know how to do this part)
Class1 selectedObject1 = (Class1)tableview1.getSelectionModel().getSelectedItem();
Class2 selectedObject2 = (Class2)tableview2.getSelectionModel().getSelectedItem();
if(selectedObject1 != null && selectedObject2 != null) {
tableview1.getSelectionModel().clearSelection();
}
So, step one is the problem. I was thinking of an observable list on which a listener can be created, and then add the selected row to the list. When this happens, the listener can call the method.
Anyone any clue how to make this?
Any help is greatly appreciated.
The selectedItem in the selection model is an observable property, so you should be able to achieve this with:
tableview1.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
tableview2.getSelectionModel().clearSelection();
}
});
tableview2.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
tableview1.getSelectionModel().clearSelection();
}
});
My solution would be creating custom cell factory for table and set it for each table columns.
Callback<TableColumn<..., ...>, TableCell<..., ...>> value = param -> {
TextFieldTableCell cell = new TextFieldTableCell<>();
cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
//your code
}
);
return cell;
};
packageName.setCellFactory(value);
table1.column1.setCellFactory();
table2.column1.setCellFactory();
...
I use it for deleting the chosen row.
public void ButtonClicked()
{
ObservableList<Names> row , allRows;
allRows = table.getItems();
row = table.getSelectionModel().getSelectedItems();
row.forEach(allRows::remove);
}
This question helped me but during experiment in javafx and jfoenix this also works for me.
deleteSingle.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
StringProperty selectedItem = table.getSelectionModel().getSelectedItem().getValue().link1;
System.out.println("That is selected item : "+selectedItem);
if (selectedItem.equals(null)) {
System.out.println(" No item selected");
} else {
System.out.println("Index to be deleted:" + selectedItem.getValue());
//Here was my database data retrieving and selectd
// item deleted and then table refresh
table.refresh();
return;
}
});
In case you need not only the row, but the x|y position of the table cell, do this:
table.getFocusModel().focusedCellProperty().addListener(
new ChangeListener<TablePosition>() {
#Override
public void changed(ObservableValue<? extends TablePosition> observable,
TablePosition oldPos, TablePosition pos) {
int row = pos.getRow();
int column = pos.getColumn();
String selectedValue = "";
if (table.getItems().size() > row
&& table.getItems().get(row).size() > column) {
selectedValue = table.getItems().get(row).get(column);
}
label.setText(selectedValue);
}
});
In this example, I am using a "classic" TableView with List<String> as column model. And, of course, that label is just an example from my code.
I am developing a custom control that needs to display a dropdownlist as a composite control.
The drop down list gets populated from a Rest web service. The problem I am facing is that the dropdownlist only has DataTextField and DataValueField but I need a way of storing more values in the control i.e. I have a couple of other properties I need to access for the selected item.
What is the best way of going about this?
Here is the code I have so far:
[ValidationProperty("SelectedValue")]
public class SelectSurveyControl : Panel
{
private DropDownList ddlSurveys;
public string SelectedSurveyId
{
get
{
return SelectedValue;
}
}
public string SelectedSurveyJavascriptEmbedCode
{
get
{
return this.ddlSurveys.SelectedItem.Attributes[""];
}
}
public string SelectedValue
{
get
{
return ddlSurveys.SelectedValue;
}
set
{
if (ddlSurveys == null)
{
ddlSurveys = new DropDownList();
}
ddlSurveys.SelectedValue = value;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnInit(e);
if (ddlSurveys == null)
{
ddlSurveys = new DropDownList();
}
IList<Survey> surveys = GetSurveys();
this.ddlSurveys.DataSource = surveys;
this.ddlSurveys.DataTextField = "title";
this.ddlSurveys.DataValueField = "id";
this.ddlSurveys.DataBind();
ddlSurveys.SelectedValue = this.SelectedValue;
ddlSurveys.CssClass = "umbEditorTextFieldMultiple charlimit";
ddlSurveys.Attributes.Add("SurveyId", SelectedSurveyId);
ddlSurveys.Attributes.Add("JavascriptEmbedingCode", SelectedSurveyId);
this.Controls.Add(ddlSurveys);
}
public IList<Survey> GetSurveys()
{
...
}
}
Try using a string join/split to store and retrieve the various values, then you don't have to customize your dropdown list very much.
For Example:
Text: Some Title
Value: 1|testing test|2/12/2010
This will let you store as many values as you want, so long as you choose an appropriate character to join and split on. I usually use the bar, as in my example above.
Side Note: I was looking at your selected value set handler and it needs some tweaking. You shouldn't check for a null drop down list, instead you should call EnsureChildControls() before each get and set instead. Make sure you override the CreateChildControls() method and create your controls there.
You could use a hidden field and iterate thru a copy of the returned Surveys like this:
foreach(Survey s in Surveys){
string val = s.id + ":" + s.<property1> + ":" + s.<property2>;
hiddenField.Value += val +",";
}
When you need to read from the hidden field, you use String.Split to separate the values into arrays using ',' as the separator and in each array, you split again using ':'.
In the first split Array1[0] who be the survey id and Array1[n!=0] would be the properties of the Survey with the id = Array1[0]. Array[n!=0] would then be split into Array2.
I would suggest handling empty property values with an empty string or something or else you might end up with unequal lengths especially if you specify StringSplitOptions.RemoveEmptyEntries.
Agricfowl
I have a complex object. For example a SCHOOL object that contains a collection of PERSON object. How can I use the ObjectDataSource control with a FormView and flatten the complex object? An example display would be to display the school name and comma separate the students on the page. Is this possible?
I.E.
public string Id
{
get { return m_id; }
set { m_id = value; }
}
public string SchoolName
{
get { return m_schoolName; }
set { m_schoolName = value; }
}
public List(Person> Students
{
get { return m_students; }
set { m_cast = students; }
}
Found the solution here:
Displaying an IGrouping<> with nested ListViews.
I nested a DataList control inside my FormView control to get it working.
In Flex I'm using the following code to allow sorting in a DataGrid (the data is paged and sorted serverside).
private function headerReleaseHandler(event:DataGridEvent):void
{
var column:DataGridColumn = DataGridColumn(event.currentTarget.columns[event.columnIndex]);
if(this.count>0)
{
if(this.query.SortField == column.dataField)
{
this.query.SortAscending = !this.query.SortAscending;
}
else
{
this.query.SortField = column.dataField;
this.query.SortAscending = true;
}
this.fill();
}
event.preventDefault();
}
This works perfectly, except that the arrows that indicate sorting isn't shown. How can I accomplish that?
Thanks!
/Niels
There is an example here if this is what you are looking for:
http://blog.flexexamples.com/2008/02/28/displaying-the-sort-arrow-in-a-flex-datagrid-control-without-having-to-click-a-column/
It looks like you need to refresh the collection used by your dataprovider.
I have encountered the same problem and the only solution I found was to override the DataGrid and create a custom one.
Here is the class:
public class DataGridCustomSort extends DataGrid
{
public function DataGridCustomSort()
{
super();
addEventListener(DataGridEvent.HEADER_RELEASE,
headerReleaseHandlerCustomSort,
false, EventPriority.DEFAULT_HANDLER);
}
public function headerReleaseHandlerCustomSort(event:DataGridEvent):void {
mx_internal::sortIndex = event.columnIndex;
if (mx_internal::sortDirection == null || mx_internal::sortDirection == "DESC")
mx_internal::sortDirection = "ASC";
else
mx_internal::sortDirection = "DESC";
placeSortArrow();
}
}
You have to specifically call the placeSortArrow() method when you get the HEADER_RELEASE event and set the column index and direction information.
in the above code what does "this" refer to is it the datagrid because I am confused by this.query.SortField , I am assuming 'this' and "query' are your own custom objects. and why are you checking for count. what count is that.
Regards
-Mohan