I've a Tree with checkbox with dataprovider as an xmlList. Now I need to get the item renderer of the list item without click on item and by search the from outside.
protected function btnSearch_clickHandler():void
{
var searchString:String = txtInputSearch.text;
if(searchString != "")
{
StyleItemsArray.removeAll();
var conaintList:XMLList = (treeSource.node.(#label.search(searchString) > -1) as XMLList);
for each(var xmlItem:XML in conaintList)
{
// trigger the checkbox click event here
}
}
}
Sorry for delayed:
I tried the solution given but it seems datagroup is used in Flex 4 but I'm still in flex 3 version.
I tried couple of other way (e.g. itemToItemRenderer())but no luck.
Could someone please help me out?
you can retrieve all item-render of list by just using for getElementAt.
for(var i:int=0; i < youListVariable.dataProvider.length; i++)
{
var render:CustomFieldRenderer = youListVariable.dataGroup.getElementAt(i) as CustomFieldRenderer
//put Your comparison condition and if condition matched then break
}
CustomFieldRenderer is your itemRender.
youListVariable is your list's id i.e. list's variable.
Related
My Angular page has two items of import here. One is a list of skills that are added in by the user and the other is a chart of skills that are acquired based on a job title.
When the user enters a skill into the ng-select list it works perfectly. The skill is entered, it goes to the array that is set as the [(ngModel)] and everything that requires it runs perfectly. However I want the user to be able to click on a skill in the chart that I mentioned and have it show up on the ng-select list as well.
I have tried this before with ng-selects that were not populated asynchronously and at that point I was able to add an item to it by doing .push(...) on the [(ngModel)] item. However possibly because there are is no list of items unless someone is typing in the ng-select it will not appear on the page if I do that here. It will still get added to the array, but the next time I type in the ng-select the manually added item will be erased.
ng-select:
<ng-select
class="m-1 ml-2 bg-white d-inline-block"
multiple="true"
[(ngModel)]="selectedSkills"
[items]="skillItems | async"
[typeahead]="skillSubject"
(change)="populateTitleList()"
placeholder="Key Skill(s)"
style="max-width:70%">
</ng-select>
Chart:
<ngx-charts-bar-horizontal
[view]="view"
[scheme]="colorScheme"
[results]="multi"
[gradient]="gradient"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel"
(select)="onSkillBarSelect($event)">
</ngx-charts-bar-horizontal>
Creating Items:
this.skillItems = concat(
observableOf([]),
this.skillSubject.pipe(
debounceTime(200),
distinctUntilChanged(),
switchMap(text => this.courseService.searchCourseSkills(text, 20).pipe(
catchError(() => observableOf([])), // empty list on error
map(skills => skills.map(s => s.name))
))
)
).pipe(share());
When an item on the chart is clicked:
onSkillBarSelect(event){
this.courseService.searchCourseSkills(event['name'], 20).subscribe(val => {
var i:number = 0;
for(i = 0;i < val.length; i++){
if(event['name'].toUpperCase() == val[i]['name'].toUpperCase()){
if(!this.selectedSkills.includes(val[i]['name'])) {
this.selectedSkills.push(val[i]['name']);
this.populateTitleList();
}
}
}
});
}
Populate List:
populateTitleList() {
this.searchParams.keySkills = this.selectedSkills;
this.suggestedTitleList = [];
this.skillsService.getJobCloud(this.searchParams).subscribe(data => {
var i:number = 0;
for(i=0;i<5;i++){
if(data['job_names'][i] != undefined)
this.suggestedTitleList.push(data['job_names'][i], data['job_counts'][i]);
}
});
}
The 'Populate List' bit is likely unimportant to the issue but I figured people would ask for it if I didn't include it. The issues is in the onSkillBarSelect() function which uses the observable to find a match for the item on the chart that was just selected and if it finds one pushes that value to the selectedSkills array which should be controlling what is displayed on the ng-select on the page. Yet when an item is clicked and a match is found it is added to the array without showing up on the page.
I'm kind of stumped here, any advice would be appreciated.
That's a pretty long winded statement.
I'm building a faceted search which implements WebAPI in .Net and utilizes Knockout on the front end. My search response includes two lists of objects, the Resources (object with data for presentation) and Resource Facets (array of strings).
\"ResourceFacets\": [\r\n \"Book\",\r\n \"Video\",\r\n \"DVD\",\r\n \"eBook\",\r\n \"Audio\"\r\n ]\r\n}"
My ViewModel contains both the facets and the resources along with a presentation object to handle a custom row count:
function ViewModel() {
this.facets = ko.observableArray(results.ResourceFacets);
this.resources = ko.observableArray(results.ResourceResults);
this.resourceRows = ko.computed(function() {
var rows = [],
rowIndex = 0,
itemsPerRow = 2;
var resourceList = this.resources();
for (var index = 0; index < resourceList.length; index++) {
if (!rows[rowIndex]) {
rows[rowIndex] = [];
}
rows[rowIndex].push(resourceList[index]);
if (rows[rowIndex].length == itemsPerRow) {
rowIndex++;
}
}
return rows;
});
};
This allowed me to create a dynamic list of checkboxes to handle the facets and also display the resource results. What I'm trying to do now is add a Select All checkbox which will, by default, select all the boxes. From other examples I've seen, my understanding is that I need an observable property, something like "Selected", on that ResourceFacet. I just feel like that is too much that the API needs to know about my presentation.
So my question is how can I avoid having to add a "selected" bool value to the ResourceFacets but still be able to select all checkboxes or deselect the "All" checkbox when a user deselects a facet?
You can keep the list of booleans necessary to track the selection on a separate member of your view model, in addition to facets and resources. Just create a new observableArray of booleans of the same size of facets and bind those values to the checkboxes.
Another solution is to create the objects necessary to bind the checkboxes on the fly, based on results.ResourceFacets, keeping your API clean. For example:
var realModel = [];
for (var i = 0; i < results.ResourceFacets; i++) {
realModel.push({ name: results.ResourceFacets[i], chkBoxVal: ko.observable(false) });
}
this.facets = ko.observableArray(realModel);
i have a class (TheList.as). in which i have an array "Data" and it has a couple of values. Then i have a loop through which i am creating a scrollable list which uses the values from "Data" array. [I am trying make a unit converter]
Then i have another class "Units.as". In that class i have created three instances of "TheList". A main list ("myList"), and to sublists "ListFrom" and "ListTo". They are using values from "Data" array. Now i have text field whose value changes to whatever item is clicked. When i click "Angle" in the main list, i want the sublists to get populated with ("Degree", "Radian" etc)..
Here is what i tried
if(myList._TextLabel.text == "Angle")
{
ListFrom.Data = ["Degree", "Radian"];
}
But nothing happens, i do not get any error either. When i do this in an "ENTER_FRAME" event and trace (ListFrom.Data), i can see that the values change, but they do not get assigned to the list items in the list. I would really appreciate the help. Thanks!
Here are complete Classes for understanding the situation better(the code is pretty messy, as i am a newbie to OOP)
TheList.as: http://pastebin.com/FLy5QV9i
Units.as : http://pastebin.com/z2CcHZzC
where you call ListFrom.Data = ["Degree","Radian"], make sure when the data changed, the renders in the ListFrom have been set new data. for example, you may use MyRender in ListFrom for show, you should debug in the set data method in MyRender.
you should call the code below after you call ListFrom.Data = ["Degree","Radian"];
for (var i:int = 0; i < Data.legnth;i++) {
var render:MyRender = ListFrom[i] as MyRender;
if (render) {
render.data = Data[i];
} else {
var render:MyRender = new MyRender();
render.data = Data[i];
ListFrom.addChild(render);
}
}
You can use event listeners, singleton classes or reference one class to another, depending on the style you want. All are equally valid and fast / efficient.
I have some drag and drop function where there are 8 items (dragArray) that can be dropped onto 2 big 'landing zones' (matchArray). But since I don't want them lie on top of each other, I've made an array where they are given positions (posArray).
var dragArray:Array = [drag_1, drag_2, drag_3, drag_4, drag_5, drag_6, drag_7, drag_8];
var matchArray:Array = [drop_1, drop_1, drop_1, drop_1, drop_2, drop_2, drop_2, drop_2];
var posArray:Array = [{x:412,y:246},{x:530,y:218},{x:431,y:186},{x:470,y:152},{x:140,y:111},{x:108,y:162},{x:179,y:210},{x:113,y:254}];
When all 8 items are dropped, a check button appears and I want to check if they are dropped onto the correct big landing zone. I tried using the following:
if (posArray[i].x != dragArray[i].x || dragArray[i].y != posArray[i].y )
But then, not only the landing zone must match, but the positions must also match.
When I use
if (matchArray[i].x != dragArray[i].x || dragArray[i].y != matchArray[i].y )
it doesn't work, because the positions of the (dragArray) items don't match with the registration points of the (matchArray) landing zones.
Is there any way of checking if the first 4 (drag_1, drag_2, drag_3, drag_4) items match with ANY of the first 4 posArray positions and the last 4 (drag_5, drag_6, drag_7, drag_8) match with ANY of the last 4 posArray positions?
If the goal is to check each element of one set against all elements of another set then you'll need to have two loops, one "nested" within the other. The general form of this algorithm in AS3 looks like
var allMatched:Boolean = true;
for(var i:Number=0; i<array1.length; i++)
{
var matchFound:Boolean = false;
for(var j:Number=0; j<array2.length; j++)
{
if(array1[i]==array2[j])
{
matchFound=true;
break; //exit the inner loop we found a match
}
}
if(!matchFound)
{
allMatched=false;
break; //we found an element in one set not present in the other, we can stop searching
}
}
if(allMatched)
trace("Everything from array1 was found somewhere in array2"); //For an element a in the set A there exists an element b in set B such that a = b
Let me know if this helps
I'm making a dots and boxes game in flash using actionscript 3.
Currently I'm completely stuck as I want the player to click two buttons before a line is displayed. I planned to do something like this using the if statement
if button1 and button2 clicked
line1 visible = true
I've also tried adding eventlisteners with one function
function showLine(e:Event):void {
blue0001.visible = true
}
dot00.addEventListener(MouseEvent.CLICK, showLine);
But as far as I know this can only be used when you want to click one button. Is there anyway to have two eventlisteners satisfyed before the function is carried out?
Also how would I (if i can) use the if statements to carry out this?
You would probably do something like this, pseudo-code:
Assume all of the dots are in a dots array.
for (var i: Number = 0; i < dots.length; i++) {
dots.addEventListener(MouseEvent.CLICK, dotClicked, false, 0, true);
}
dotSelected = null;
function dotClicked(evt:MouseEvent):void {
if (dotSelected && isNeighbor(evt.target, dotSelected)) {
showLineConnecting(evt.target, dotSelected)
dotSelected = null;
} else if (!dotSelected) {
highlightDot(evt.target);
dotSelected = evt.target;
} else {
showError("You must click an adjacent dot");
}
}
At the request of the OP, this is what's going on.
for (var i: Number = 0; i < dots.length; i++) {
dots.addEventListener(MouseEvent.CLICK, dotClicked, false, 0, true);
}
Add an event listener to every dot. Here I am assuming you already have an array of dots defined. Each instance in the Array would be a MovieClip (likely), Sprite, or another DisplayObject.
dotSelected = null;
We will use a variable to keep track of any currently selected dot. Since no dot will be selected when the game starts, we set it to null.
function dotClicked(evt:MouseEvent):void {
if (dotSelected && isNeighbor(evt.target, dotSelected)) {
showLineConnecting(evt.target, dotSelected)
dotSelected = null;
} else if (!dotSelected) {
highlightDot(evt.target);
dotSelected = evt.target;
} else {
showError("You must click an adjacent dot");
}
}
This is the function that will get called when any dot is clicked. For explanation's sake, let's take the first click of the game. dotSelected is null, so the first if is false. The second if though is true, because (!dotSelected) is true. So, we run some function I called highlightDot with the dot as the argument. That function could look something like this:
function hightlightDot(dot:Dot):void {
dot.gotoAndStop("selected");
}
Now a second click is made. Now the first part of the first if, dotSelected, is true. The second part is now evaluated. Again I put in a made up function isNeighbor. The isNeighbor function takes two arguments, the dot that was just clicked and the dot that has already been clicked. This function needs to make sure the two dots are adjacent. This could be something like...
function isNeighbor(dot1:Dot, dot2:Dot):void {
return ((dot1.xGrid == dot2.xGrid && Math.abs(dot1.yGrid - dot2.yGrid) == 1) || (Math.abs(dot1.xGrid - dot2.xGrid) == 1) && dot1.yGrid == dot2.yGrid));
}
The above function assumes that the instances of Dot have some properties xGrid and yGrid which defines where in the playing board they sit. If they are in the same row and 1 column apart they are neighbors. If they are in the same column and 1 row apart they are neighbors.
The last thing that happens in a function showLineConnecting is called. That function will again take the two adjacent dots as arguments. It will then draw a line between them in whatever way you choose to do that. Finally, dotSelected is set back to null, allowing another set of dots to be selected.
One thing I just realized, it would probably be helpful to have an additional property that gets triggered on a Dot when it is connected to all of its neighbors so it could no longer be selected.
You will also need logic to handle knowing that a box has been created. For that you would likely just iterate the possibilities given the line that was just drawn. For each line drawn there are only two possible boxes that have been created. So check them both. Watch out for edges.