I am using flex TabNavigator to display few datagrids. Each datagrid have same structure but populated with different dataProvider. Currently I am using following method to check which datagrid or an element from a tab was clicked.
if(TabNavigator.selectedIndex == 0){
}else if(TabNavigator.selectedIndex == 1){
}
...
else if(TabNavigator.selectedIndex == 4){
}
My question is is there an efficient way to check this? Is there anyway I can organize similar structure in to one property?
Thank you.
Add all your data providers into an array in the same sequence as the items in the tab navigator. Then simply do:
dataGrid.dataProvider = dataProviderArray[tabNavigator.selectedIndex];
Here 'dataProviderArray' is the array of all the data providers for the data grid.
Also, since you mentioned that the data grid has the same structure for all the tabs, I am assuming you are using one Data Grid and not multiple. If not, I would recommend you keep one data grid only and change its data provider when the tabs change.
Hope this solves your question.
Related
I have a mx.controls.DataGrid datagrid on a page, and the requirement I have is that some cells on that datagrid be editable dependent upon some condition in the state of the system.
So far as I can tell I can set the entire datagrid to be editable via the editable property, or all values in a column via the DataGridColumn's editable property, but I don't see a way to set this on the level of an individual cell within the datagrid.
Any suggestions?
A good example you can find here (Preventing a cell from being edited). It solves your problem completely. Just change the condition in the example to your own.
This works great:
// cell at the intersection of row 1 and column 2
dg.addEventListener(ListEvent.ITEM_CLICK, cellEditable);
function cellEditable(e:ListEvent):void {
e.target.editable = (e.rowIndex == 1 && e.columnIndex === 2) ? true : false;
}
This may be a little confusing to describe.
Basically, I am parsing multiple external JSON feeds that display in different views depending on the 'active tab' displayed. They both share the same partial template, so they both look exactly the same, just different content.
The problem that I am facing now is, that in some feeds, some keys are placed in an array and others are not.
For example, the feeds parses this kind of data:
JSON Feed 1 - One 'attributes' inside of 'link'
"link":{
"attributes":{
"href":"www.link1.com"
}
}
JSON Feed 2 - Two 'attributes' inside of 'link'
"link":[
{
"attributes":{
"href":"www.link1.com"
}
},
{
"attributes":{
"href":"www.link2.com"
}
}
]
The only way I am able to get the value "www.link1.com" is via:
For Feed 1:
link1
And for Feed 2:
link1
I am trying to figure out what would be the best way to do:
1) If link[0] exists - display it, else if [link] exists, display that instead.
2) Or if targeting the activeTab would be safer? For instance, if activeTab = view2 or view4, use [link][0], else if activeTab = view1 or view3 use [link], else if I do not want it to be displayed, do not display anything.
Also a relatable question, if I am on view2 can I only display [link][0] on that view?
Any feedback would be appreciated. Thanks!
In your model controller, you can reconstruct the JSON objects to make them similar. The value of link in both feeds should be an array.
Then in your template you can simply use ngRepeat to get the items from inside the array.
Okay - so I found a solution to one of the questions above: "How to only display [link][0] in a specific view"
Pro: It's a simple code that depends on the activeTab / view that is being displayed.
Con(?): Since I am really a newbie to AngularJS - not sure if this is the best solution.
Basically:
Depending on the ng-view that is currently displayed, than a specific JSON object will be displayed, such as:
<a ng-show="activeTab == 'view1' || activeTab == 'view3'" ng-href="{{item['link'][0]['attributes']['href']}}">
<h6>Link1 from Feed2</h6>
</a>
Although the primary question is still unresolved: How to swap/switch JSON objects (key,values) if one exists, and not the other. I am still definitely trying to find a solution, although any help is still appreciated.
Please let me know what you think, or how I can improve the solution to the problem!
Thanks!
Roc.
I have an ArrayCollection that is the dataProvider for a spark.components.List, which has allowMultipleSelection="true". There is a "Remove Selected Items" button which initiates the removal of all the selected items from the ArrayCollection upon being clicked.
I currently use the following method:
myList.selectedIndices.sort(ascendingSort);
// remove items, counting backwards
for (var i:uint = myList.selectedIndices.length; i > 0; i--) {
myArrayCollection.removeItemAt(myList.selectedIndices[i-1]);
}
where ascendingSort does what you expect ;). It works fine, and I know that it will always work.
However, I did take note that if I neglected the sort altogether, to my surprise the removal still worked. The reason for this turned out to be that, when the removeItemAt is called, the selectedIndices are correspondingly updated.
So my question is: Can one rely upon a removeItemAt call updating the values in the selectedIndices? or might that turn out to be different between runtimes and/or Flex SDK versions?
Obviously, if it is reliable then leaving out the sort would be a significant improvement.
Can one rely upon a removeItemAt call updating the values in the
selectedIndices?
Apparently in your use case, yes.
or might that turn out to be different between runtimes and/or Flex
SDK versions?
It may very well change at some future point, or may have changed before. I know that in my experience with list based classes, sometimes modifying the dataProvider may cause the list to go back into the "no selection" state. Removing a single selectedItem on a list that does not allow multiple selection is a good example of that.
Usually, in the apps I've worked on, I'm not removing items from a list based on the user's selection in a list; instead they are usually removed (or filtered) out based on some criteria in the actual object. And that criteria usually is a Boolean value that relates to a checkbox shown in a DataGrid column.
var indexes:Vector.<Object> = list.selectedItems;
while(indexes.length > 0 )
{
var item:* = indexes.pop();
var remindex:int = list.dataProvider.getItemIndex(item);
if (remindex != -1)
{
list.dataProvider.removeItemAt(remindex);
}
}
I'm trying to print a simple HTML tree structure, consisting of ul and li elements. I want to be able to pass the view an IEnumerable<T> where T has some hiearchy information (e.g. parent). Now I want the view to output the Tree control much like ASP.NET's Tree used to work. Is there any way to do this in MVC3 using Razor?
I've so far ended up doing it like this:
#PrintCategoryTree(Model.Where(x => !x.ParentCategoryID.HasValue))
#functions{
public IHtmlString PrintCategoryTree(IEnumerable<Aurora.Models.Category> levelCategories) {
if (levelCategories.Count() == 0) { return new HtmlString(String.Empty); }
System.Text.StringBuilder sb = new System.Text.StringBuilder();
TagBuilder childBuilder = new TagBuilder("li");
foreach(var item in levelCategories.OrderBy(x => x.Name)) {
childBuilder.Attributes.Clear();
childBuilder.Attributes.Add("id", item.CategoryID.ToString("N"))
var sub = PrintCategoryTree(Model.Where(x => x.ParentCategoryID == item.CategoryID));
childBuilder.InnerHtml = item.Name + sub.ToString();
sb.AppendLine(childBuilder.ToString());
}
TagBuilder tagBuilder = new TagBuilder("ul")
{
InnerHtml = sb.ToString()
};
return Html.Raw(tagBuilder.ToString());
}
}
The reason being, this is still in the Razor View. And I can keep my presentation logic in my view. It's not exactly what I'd hoped, but I thought I'd share it with you guys here anyway.
Sure it's possible. :) You can acctually go about this in a few ways.
Use something like jsTree and only output the first level of the tree. When a user expands a node, jsTree issues an AJAX callback to get more, and that's just a matter of loading the nodes underneath whatever they opened. I know that's not exactly what you asked, but I wanted to mention it.
If you can either modify the query or do a bit of pre-processing on the data before passing it to razor, change each item in the IEnumberable so that it also includes it's "level" in the tree (1 for a root node, 2 for it's child, 3 for a child of a child, etc). Outputting it at that point is pretty easy. Create a variable in the view holding the current level. When you go to the next row, check if the new level is the same as the old one. If it's not, either open or close enough <ul> tags that you get to the right one for that element.
If you can't do that either, you'll need to keep track of the nodes as you see them in razor. The reason why is that when you find a child from a node that isn't the last one you saw, you'll need to get that node back to figure out how many </ul> tags you need to add to get to the right level. Off the top of my head you could do that by having the view create a Hashtable with the row's key and level for each row you hit. Then when you hit an element and don't know where to put it, look up its parent in the hashtable (since you'll have already seen the parent assuming these are ordered correctly).
Far as I'm aware there's no "display this blob of stuff as a tree" command, so you need to write some logic to get the number of tags to build the levels correct. But hopefully that will help you get started. :)
I have a spark datagrid with selectionMode="multipleRows".
I have three columns in the datagrid.
I don't want the row selection to happen when the user's click falls on the third column of a row.
The row selection should happen only when one of the first two columns is clicked.
How do I achieve this? There is a selectionChanging event for the datagrid, but the GridSelectionEvent object received in the handler does not seem to provide any information about the column on which the click happened.
Thanks!
I figured this out myself. I am not sure if this is a bug in the spark DataGrid. The following is definitely a hack and not clean.
In the grid_mouseDownHandler function in the DataGrid.as file, there is a line:
const columnIndex:int = isCellSelection ? event.columnIndex : -1;
This line is causing the columnIndex to be set as -1 if the selectionMode of the DataGrid is anything other than GridSelectionMode.SINGLE_CELL or GridSelectionMode.MULTIPLE_CELLS. As I mentioned in the original question, I need my datagrid to have a selectionMode of GridSelectionMode.MULTIPLE_ROWS.
I sub-classed the DataGrid and re-implemented the grid_mouseDownHandler (basically copy-pasted the whole function). I changed only the above line to always assign the columnIndex to event.columnIndex.
(I also had to copy some more functions which were referenced by the grid_mouseDownHandler over to my sub-class because those functions were protected or mx_internal. (toggleSelection, extendSelection, isAnchorSet)
Then, in the selectionChanging event handler, I could just do the following:
if( 2 == event.selectionChange.columnIndex )
{
event.preventDefault();
}
I realize that this is not a clean solution, but it is the best I could think of. Maybe someone can suggest a better solution?