Silverstripe DropdownField does not respect default value argument - silverstripe

Pretty simple question, I'm creating a dropdown field and trying to set the selected value like so:
$tourField = DropdownField::create('Tour', 'Tour', Tour::get()->sort('TourName ASC')->map('ID', 'TourName')->toArray(), $currentTourID);
I have confirmed that $currentTourID contains the correct value (a numeric ID) and that value exists in the resulting dropdown. When rendered, no item in the dropdown is selected by default. So I assume I have something else wrong here.
Edit: Note that this field is a has_one relationship field with the object, and in the case of this object, the value of it is null. I am trying to override that and set it using something a bit smarter.

My edit made me realise that all I had to do was set the object representation of these fields rather than try to manually override the default value. The key here is that the dropdowns in question reference a relationship in the object.
So instead of:
$currentTourID = $mySmartFunction();
$tourField = DropdownField::create('TourID', 'Tour', Tour::get()->sort('TourName ASC')->map('ID', 'TourName')->toArray(), $currentTourID);
I did this:
$this->TourID = $mySmartFunction();
$tourField = DropdownField::create('TourID', 'Tour', Tour::get()->sort('TourName ASC')->map('ID', 'TourName')->toArray());

Related

Datasource Paging Issue (Revised Again)

See Datasource Paging Issue (Revised)
for the original question.
Markus, you were kind enough to help with out with the issue of incorporating a record count into a query using a calculated datasource. I have a search form with 15 widgets - a mix of date ranges, dropdowns, text values and ._contains, ._equals, ._greaterThanOrEquals, ._lessThanOrEquals, etc.
I have tested this extensively against mySQL SQL code and it works fine.
I have now added a 16th parameter PropertyNames, which is a list with binding #datasource.query.filters.Property.PropertyName._in and Options blank. The widget on the form is hidden because it is only used for additional filtering.
Logic such as the following is used, such that a particular logged-in user can only view their own properties. So if they perform a search and the Property is not specified we do:-
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = params.param_PropertyNames;
}
The record count (records.length) is correct, and if I for loop through the array of records the record set is correct.
However, on the results page the table displays a larger resultset which omits the PropertyNames filter. So if I was to search on Status 'Open' (mySQL results 50) and then I add a single value ['Property Name London SW45'] for params.param_PropertyNames the record count is 6, the records array is 6 but the datasource display is 50. So the datasource is not filtering on the property array.
Initially I tried without adding the additional parameter and form widget and just using code such as
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = properties; // an array of
properties to filter out
}
But this didn't work, hence the idea of adding a form widget and an additional parameter to the calculated recordcount datasource.
If I inspect at query.parameters then I see:-
"param_Status": "Open",
"param_PropertyNames": ["Property Name London SW45"],
If I inspect query.filters:-
name=param_Status, value=Open
name=param_PropertyNames, value=[]}]}
It looks as though the filter isn't set. Even hard coding
ds.filters.Property.PropertyName._in = ['Property Name London SW45'],
I get the same reuslt.
Have you got any idea what would be causing this issue and what I can do for a workaround ?
Using a server side solution I would suggest editing both your SQL datasource query script (server side) that is supposed to filter by this property list and including the same code in your server side script for your calculated Count datasource. The code would look something like this, not knowing your exact details:
var subquery = app.models.Directory.newQuery();
subquery.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
subquery.prefetch.Property._add();
var results = subquery.run();
if(!results[0].CanViewAllRecords) {
query.filters.Property.PropertyName._in = results[0].Property.map(function(i) {return i.PropertyName;});
}
By adding this code you are filtering your directory by your current user and prefetching the Property relation table, then you set the filter only if your user canviewallRecords is false and use JS map function to create an array of the PropertyName field in the Property table. As I stated, your code may not be exactly the same depending on how you have to retrieve your user canviewallrecords property and then of course I don't know your relation between user and Property table either, is it one-to-many or other. But this should give you an idea how to implement this on server side.

IBM Notes editable fields getting data from parent form

In Notes I have a form (Order) in which I have button "Create new OrderLine" which creates a new form(Orderline). The Order document has an embedded view on the design which gets orderlines documents. Each orderline document contains a hidden field with the ID of the order document, so that you know which orderline is connected with which order. Same goes for Orderline this has an embeddedview with Prices.
In the Order form I have 2 editable text fields: AdministrationNumber and DebtorNumber.
In the OrderlineForm I only got the debtorNumber
In Prices I have a editable number field called Fee.
So I did this on various ways:
In the postOpen of the form prices I have put this LotusScript code:
If( (Source.FieldGetText( "AdministrationNumber" ) = "1" ) And (Source.FieldGetText( "DebtorNumber" ) = "2") ) Then
Call Source.FieldSetText("FeePercentage", "4.235")
Call Source.Refresh()
End If
But did not work.
In Default Value of Fee I also tried this formula code:
#If((AdministrationNumber="1") & (DebtorNumber= "2");
"4,235";
"0"
)
But also of no use..
Is it possible for an editable field to be set when opening the subform based on conditional statement with data which is in the parent form?
Edit
2 ways to solve:
1.
When clicking "Add new Orderline" Button whic is on the Order form, I will call a function in the scriptlibrary, in this function I get values of debnr and admnr and then do the conditional statement.. If true then set FeePercentage
2.
Added new hidden field on the orderlline called admnr which gets the administratorNr field data when the New Orderline Button is clicked.. The field is set through a function in the scriptlibrary.
Eventually in the postOpen of the prices subform this works:
Dim doc As NotesDocument
Set doc = Source.Document
If doc.admnra(0) = "1" And doc.debnr(0) = "2" Then
doc.FeePercentage = 4.235
End If
Work with back-end classes instead:
Dim doc as NotesDocument
Set doc = Source.Document
If doc.AdministrationNumber(0) = "1" And doc.DebtorNumber(0) = "2" Then
doc.FeePercentage = 4.235
End If
It gives you easy access to all fields in document.
You say "subform" which has a special meaning in Notes design but it sounds like what you have is a form called "Order", a form called "OrderLine" and a subform called "Prices" that the OrderLine form uses?
In which case, make sure the OrderLine's the "Formulas inherit values from selected document" form property is checked.
That and your default formula should do it if the button is on the parent form (as opposed to view the Order form embeds).
P.S. You might want to change your default formula to
#If(
(AdministrationNumber="1") & (DebtorNumber= "2"); 4235;
0
)
so that it returns a number instead of text that looks like a number.

how to set datagrid numberbox prefix onchange combobox

I am using datagrid with inline editor which have validatebox, numberbox, and combobox. What I am try to do is when I select the combobox, I need to set numberbox prefix as currency symbol as I want. If I want to set the value to the numberbox, usually write like this:
var ed8 = $("#dg").datagrid("getEditor", {index:idx, field:'cost'});
$(ed8.target).numberbox('setValue',value);
but I am stack on case how to change/set the property "prefix" of numberbox.
One more thing that I want to ask, Is that possible to set multiple prefix in one field (one row one prefix) of datagrid?
I just found the solution by put the code like this.
var ed8 = $("#dg").datagrid("getEditor", {index:idx, field:'cost'});
var opts = $(ed8.target).numberbox('options');
opts.prefix = '$';
It is possible to set multiple prefix on a field
hope this can help others.

vb.net alternative to select case when dealing with object values

Hey all, I was able to do this via a SELECT CASE statement, however I'm always trying to improve my code writing and was wondering if there was a better approach. Here's the scenario:
Each document has x custom fields on it.
There's y number of documents
However there's only 21 distinct custom fields, but they can obviously have n different combinations of them depending on the form.
So here's what I did, I created an object called CustomFields like so:
Private Class CustomFields
Public agentaddress As String
Public agentattorney As String
Public agentcity As String
Public agentname As String
Public agentnumber As String
Public agentstate As String
Public agentzip As String
... more fields here ....
End Class`
Then I went ahead and assigned the values I get from the user to each of those fields like so:
Set All of Our Custom Fields Accordingly
Dim pcc As New CustomFields()
pcc.agentaddress = agent.address1
pcc.agentattorney = cplinfo.attorneyname
pcc.agentcity = agent.city
pcc.agentname = agent.agencyName
pcc.agentnumber = agent.agentNumber
pcc.agentstate = agent.state
pcc.agentzip = agent.zip ....other values set to fields etc.
Now the idea is based upon what combo of fields come back based upon the document, we need to assign the value which matches up with that custom field's value. So if the form only needed agentaddress and agentcity:
'Now Let's Loop Through the Custom Fields for This Document
For Each cf As vCustomField In cc
Dim customs As New tblCustomValue()
Select Case cf.fieldname
Case "agentaddress"
customs.customfieldid = cf.customfieldid
customs.icsid = cpl.icsID
customs.value = pcc.additionalinfo
Case "agentcity"
customs.customfieldid = cf.customfieldid
customs.icsid = cpl.icsID
customs.value = pcc.additionalinfo
End Select
_db.tblCustomValues.InsertOnSubmit(customs)
_db.SubmitChanges()
This works, however we may end up having 100's of fields in the future so there a way to somehow "EVAL" (yes I know that doesn't exist in vb.net) the cf.fieldname and find it's corresponding value in the CustomFields object?
Just trying to write more efficient code and looking for some brainstorming here. Hopefully my code and description makes sense. If it doesn't let me know and I'll go hit my head up against the wall and try writing it again.
If I am reading your question correctly, you are trying to avoid setting the value of fields, when the field isn't used. If so, I would recommend you just go ahead and set the field to nothing in that case.

dynamically generate ComboBox name

I have a script that parses some complex XML. When the XML element is of a certain type, it generates a comboBox using the XML element's children to populate the box. I then want to check all of the values of the all the generated ComboBoxes against their correct answers (which is also info stored in the XML file). When creating the ComboBoxes, I added an "id" property. However, it seems that I cannot them use:
dynamicQuestion.id.selectedItem.labelField
to check the answers. However, I am able to get the labelField if I know the variable name used to create the ComboBox.
dynamicQuestion.selectedItem.labelField
This indicates (to me) that I need to dynamically generate the variable name as I'm creating new instances of the ComboBox. But how do I dynamically generate a variable name? If I use
var thisBox:String = "box"+boxCount;
var newBox:ComboBox = thisBox as ComboBox;
I get an implicit coercion error. I also tried changing the creation statement to a function that accepted an argument, "thisBox," but this didn't work either. Conceptually, this seems quite simple, but I'm having a hard time putting it to practice. It seems that the comboBox's id is what is generated by created the box using script (e.g., var thisBox). How do I dynamically generate this name?
Use an array as Stefan suggested. If you must use string identifiers, you can create an object and use it as an associative array.
var combos:Object = {};
var boxCount:Number = 1;
var thisBox:String = "box"+boxCount;
//you can store comboboxes in the object using the following syntax
combos[thisBox] = new ComboBox();
//or
combos.box2 = new ComboBox();
//or
combos["box3"] = new ComboBox();
trace(combos.box1.selectedItem.labelField);
trace(combos.box2.selectedItem.labelField);
trace(combos.box3.selectedItem.labelField);
Why don't you store all your dynamically created combo boxes in an array? When you want to evaluate them you iterate over the array and access selectedItem.labelField.

Resources