Flex Datagrid Query - apache-flex

Below is part of my code interacting with data grid...!
This lists the children of the particular node if i click on it after refreshing the datagrid..
But if i click on an empty space of the datagrid i get an error saying
"ReferenceError: Error #1069: Property data not found on mx.controls.listClasses.ListBaseContentHolder and there is no default value."
How to avoid that ?
if(event.target.data.children != null)
{
resultSet.removeAll();
var tempChildObj:ArrayCollection;
tempChildObj=event.target.data.children as ArrayCollection;
var childLength:int;
childLength=tempChildObj.length;
for(var i:int =0;i<childLength;i++)
{
resultSet.addItem(tempChildObj.getItemAt(i));
}
resultSet.addItem(tempChildObj);
}
}

What the error is telling you is that the event's target property doesn't have a property called data in your error case. This makes sense since you're clicking on a blank row - a blank row won't contain any data.
What you'll want to do first is check if the event's target contains a data property before you start accessing the child property of data. Either one of the following tests should work:
if( event.target.hasOwnProperty( "data" ) ) {
// rest of your code here
}
or
if( event.target.data ) {
// rest of your code here
}

Related

Default Value for Dropdown

Can't seem to find an answer to this issue easily.
Default values for fields you want to display and allow editing, the best place seems to be to set the widget.value in a draft record, so default date widget.value = new Date(), etc.
How do I reference a dropdown where the dropdown is a related table lookup, e.g., a list of Properties where the bindings are #datasources.Property.Items for the options and #datasource.Item.Property for the value.
If I do console.log(widget.value); I get object Object, which is what I would expect because it is of type object. But how can I set (and retrieve) its value?
Help appreciated.
I tested this for a similar situation in my own application. Do note that there is a minimal delay before the value in the dropdown actually populates. I'm not sure what your alternative solution could be due to the reason stated in my last comment above. I might suggest setting this in your form model onBeforeCreate event instead, but then you would loose the ability to change the relation in the form itself so that might not work for you.
Dropdown widget onAttach event:
var datasource = app.datasources.Property;
if(!datasource.loaded) {
datasource.load(function() {
var index = datasource.items.map(function(i){return i.Status;}).indexOf('Open');
if(index !== -1) {
widget.value = datasource.items[index];
}
});
} else {
var index = datasource.items.map(function(i){return i.Status;}).indexOf('Open');
if(index !== -1) {
widget.value = datasource.items[index];
}
}

Multiple OnSaving event in DevExpress XAF

Im working on a piece of code using DevExpress XAF, I noticed that if im using the event OnSaving that the code executes 2 times, how can i prevent that
protected override void OnSaving()
{
if (PrestamoP != null)
{
PrestamoP.Prestado -= Monto;
PrestamoP.Save();
}
else if (PrestamoG != null)
{
PrestamoG.Prestado -= Monto;
PrestamoG.Save();
}
base.OnSaving();
}
XPO does not guarantee that the OnSaving method is called once. See the corresponding note in the XPO Best Practices article.
I can see that you are changing the PrestamoP.Prestado property based on the value of the Monto property. This code is fine if you execute it only once and only when the Monto property is specified for the first time. This code is not fine if you:
Save this object without changing the Monto property;
Update the early specified Monto value.
So, it appears that a more complex logic is required for the PrestamoG.Prestado property. First, I would move it to the Monto property setter and take the previous value into account (do not forget to check the IsLoading property in this case). Second, I would consider calculating the Prestado value dynamically instead of storing its value. This will allow you to resolve issues with the duplicate business logic execution. See an example here: How to: Calculate a Property Value Based on Values from a Detail Collection.
I can offer different methods for CRUD functions on onSaving method.
IsNewObject, IsDeleted.
// insert
if (Session.IsNewObject(this))
{
a = new a(Session);
a.CreateReferencedProperties(this);
}
// delete
else if (IsDeleted)
{
a= Session.FindObject<A>(PersistentCriteriaEvaluationBehavior.InTransaction, CriteriaOperator.Parse("A=?", this));
if (a!= null)
a.Delete();
}
// update
else
{
a= Session.FindObject<A>(PersistentCriteriaEvaluationBehavior.InTransaction, CriteriaOperator.Parse("A=?", this));
if (a!= null)
a.CreateReferencedProperties(this);
}
You can use the code below to prevent xaf from entering on saving twice.
base.OnSaving();
SessionObjectLayer sessionObjectLayer = this.Session.ObjectLayer as SessionObjectLayer;
if (sessionObjectLayer == null || sessionObjectLayer.ParentSession == null)
{
//Enter only once
}

How to update content in Row after selection in dojo datagrid

I have created one dojo datagrid. Every column has a formatter attached to it. When grid is generated the formatter is called. Now I want it so that if a user selects any row the formatter will be called and some strings should be attached to the selected row's column element.
Like grid is like this :
COLUMN
-------
a
b
c
and now user selects the 2nd row, the grid should change to :
COLUMN
-------
a
b SELECTED
c
Currently I implemented it like this :
if(this.grid.selection.selectedIndex !== -1){
retrun value + "SELECTED";
}else{
return value;
}
Can you please suggest a some good way of doing this? Please note that "SELECTED" string should not be added to the grid store.
The formatted is not hooked into clicking / selection of rows. It is solely performed when the contents (value) of a cell is set. Instead you'd want to move focus over to onRowClicked - an event on the grid component. It works like this:
grid.onRowClick = onRowClickHandler;
I wouldnt know which of following samples would put you closest to your goal but onRowClickHandler could be setup as such:
function onRowClickHandler(evt) {
var rows = this.selection.getSelected();
// perform cell rendering here
dojo.forEach(rows, function(row) {
// this row is an item though.. you will have row._O as its index
});
}
OR
function onRowClickHandler(e) {
var cellClicked = this.focus.cell
cellClicked.formatter();
}
However you may find that there are not much references to the viewable data anywhere in the grid component.. You could use following query selectors to find cell data and update the viewed html by calling formatter on each value. You would need to capture a previous selection for 'teardown' of your custom setting of values though.
var prevSelectedRows = [];
function onRowClickHandler(evt) {
var idx = this.selection.selectedIndex,
rawRow = dojo.query(".dojoxGridRow:nth-child("+(idx+1)+")", this.domNode)[0],
self = this;
// perform resetting of viewable values
dojo.forEach(prevSelectedRows, function(raw) {
dojo.query('.dojoxGridCell', raw).forEach(function(cellDOM, i) {
cellDOM.innerHTML = cellDOM.innerHTML.replace("SELECTED", "");
});
});
prevSelectedRows = []; // reset prev selection
// look into grid.view.content for methods on this
// perform setting of viewable values (SELECTED)
dojo.query('.dojoxGridCell', rawRow).forEach(function(cellDOM, i) {
// this function might be of interest, lets see how it looks in console
console.log(self.layout.cells[i].formatter);
cellDOM.innerHTML = cellDOM.innerHTML + "SELECTED"
});
prevSelectedRows.push(rawRow);
}

Flex DropdownList CreationComplete error

I have a DropdownList that shows a list of providers & the Provider associated with that Patient must be selected.
The Dropdown list:
<s:DropDownList id="providerList"
width="80%"
fontSize="12"
fontWeight="bold"
selectionColor="white"
creationComplete="providerList_creationCompleteHandler(event)"
dataProvider="{model.practiceProviderList.practiceProviders}"/>
where practiceProviders is an ArrayCollection
The CreationCompleteHandler function:
protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
var firstN:String;
var lastN:String;
var providerObj:Provider = new Provider();
if (model.patientDetails.patientDetail.patientProviders != null && model.patientDetails.patientDetail.patientProviders.length > 0)
{
firstN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.firstName;
lastN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.lastName;
for (var count:int = 0; count < patientDetailsModel.practiceProviderList.practiceProviders.length; ++count)
{
providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;
if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
{
this.providerList.selectedIndex = count;
}
}
}
}
The issue is when I go to this page the first time, the error is :
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.newwavetechnologies.modules::demographics/providerList_creationCompleteHandler()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:166]
at com.newwavetechnologies.modules::demographics/__providerList_creationComplete()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:359]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:12266]
at mx.core::UIComponent/set initialized()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:1577]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:759]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]
where line 166 is:
if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
The providerObj is null the first time. But when hit back and come to the same page again, everything works fine and 1 of the providers in the list is selected correctly.
Probably I think the first time, the creationComplete handler method is called before the List is populated. The 2nd time when the call is made, the list is populated and the handler works fine. It would be great if someone can help me in this regard on how to go about this.
Thanks
Harish
It's hard to tell what's going on here, but the problem lies here:
providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;
There's a tonne of places in that line that Null pointer exceptions could occur.
Most likely - the practiceProvider returned at position count doesn't have a provider set. We can't see how this value is populated, but given this code works later, I'd say you've got a race condition happening - the data is being accessed before it's been set.
At very least, you should add a guardClause for this:
var practiceProviders:ArrayCollection = patientDetailsModel.practiceProviderList.practiceProviders;
for (var count:int = 0; count < practiceProviders.length; ++count)
{
providerObj = practiceProviders.getItemAt(count, 0).provider as Provider;
if (!providerObj)
continue;
// etc
}
The race condition is a little trickier, given the asyncronous natoure of flex server calls. (I'm assuming that you're loading the data from a remote server).
There's two approaches to solve this - either
defer execution of this method until the data has loaded - you could do this by adding an eventListener to the ResultEvent of the RemoteService
or
Don't worry about it the first time around, but re-execute the method whenever the data changes.
eg:
protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,onCollectionChange,false,0,true);
updateProviders();
// Rest of existing creationComplete code moved to updateProviders();
}
private function updateProviders()
{
// Code from existing creationComplete handler goes here
}
private function onCollectionChange(event:CollectionEvent):void
{
updateProviders();
}

Why are elements null in jquery, yet exist with document.getelementbyid()

I"m trying to attached some jquery to checkboxes in a gridview, using document.ready:
$(document).ready(function()
{
var chkBox= document.getElementById("gvTimeSheet_ctl01_chkAll1");
//I can alert chkBox.id, element exists
var name = $("input[name='gvTimeSheet$ctl01$chkAll1']");
//Here, when I alert the id, I get a null
var ID = $("#gvTimeSheet_ctl01_chkAll1");
//Here, when I alert the id, I get a null
var withClass = $(".chkAll1Class");
//Here, when I alert the id, I get a null
var withClass2 = $(".Bill1");
//Here, when I alert the id, I get a null
//This line causes the browswer to crash and gives me the following error
//Microsoft JScript runtime error: 'null' is null or not an object
$("#gvTimeSheet_ctl01_chkAll1").click(function()
{
var checked_status = this.checked;
$("input[class=Bill1]").each(function()
{
this.checked = checked_status;
});
});
});*/
So, why are any attempts at finding an object null in jquery, yet exist in regular javascript within the same method? What am I missing here. I have the jquery js files brought in in a script tag directly above this method. I just can't seem to find any objects on this page with jquery. On other pages, I can.
Objects that result from a jQuery selector are actually wrappers around a DOM object, so you don't access it the same as a DOM object.
If you're alerting just "name.id", from your first example above, there won't be any such property on the jQuery wrapper. Try alerting your ID as follows:
alert(name.attr("id"));
var val = $("input:radio[name$='rdoselect']:checked").val();
if (val == 1) {
$('[id$=divDate]').attr('disabled', true);
}else {
$('[id$=divDate]').attr('disabled', false);
}
var ID = $("#gvTimeSheet_ctl01_chkAll1");
This returns a jQuery object, not an ID. ID.id would also be undefined. To get the ID, you need:
var ID = $("#gvTimeSheet_ctl01_chkAll1").attr("id");
Does the page you're adding this code to already include the Prototype JavaScript library?
jQuery's "$" method never returns null, so this shouldn't be a problem:
// This line causes the browswer to crash and gives me the following error
// Microsoft JScript runtime error: 'null' is null or not an object
$("#gvTimeSheet_ctl01_chkAll1").click(function() { .... });
All the comments about needing to use .attr('id') still stand (though I prefer $('#whatever')[0].id myself.)

Resources