I'm trying to make a radiobutton component in AngularDart.
So it would be used as follows:
<radio_component currentIndex="0" selectedIndexZ="{{cmp.selectedIndexZ}}"
textLabel="Label A"></radio_component>
<radio_component currentIndex="1" selectedIndexZ="{{cmp.selectedIndexZ}}"
textLabel="Label B"></radio_component>
If someone clicks on one of the radio button components I want the other radio button components to change their state to change a CSS class.
When someone clicked on it, I changed selectedIndexZ inside one of these and it didn't update the other ones.
class RadioComponent extends AttachAware with ShadowRootAware {
#NgTwoWay('currentIndex')
int currentIndex = 0;
#NgTwoWay("selectedIndexZ")
String selectedIndexZ = "0";
If someone clicks on one radio button component, how can it cause the others to update ?
Since I have a lack of time, i.e., I have to get it working absolutely NOW, I just copied this method and this works Creating an Angular.Dart Cube component with 6 template arguments
If I get free time in future I'll get back to this question.
You need to use a controller on an ancestor element and bind the selectedIndexZ of both elements to this controller (in the future there will be only one root controller)
You can also embed both elements into another component (which is implicitly a controller) and bind to a field of this component.
#Component(selector: 'parent-element', publishAs: 'par', template: ...)
class ParentComponent {
#NgTwoWay("selectedIndexZ")
String selectedIndexZ = "0";
}
template
<parent-element>
<radio_component currentIndex="0" selectedIndexZ="{{par.selectedIndexZ}}"
textLabel="Label A"></radio_component>
<radio_component currentIndex="1" selectedIndexZ="{{par.selectedIndexZ}}"
textLabel="Label B"></radio_component>
</parent-element>
Related
I have a top level element <x-app> with nested modal dialogs
<x-app>
<material-content>
...
</material-content>
<x-alert-dialog></x-alert-dialog>
</x-app>
where <x-alert-dialog> contains
<modal [visible]="dlgVisible" dialog-id="alert-dialog-modal">
<material-dialog class="alert-dialog">
....
</material-dialog>
</modal>
Generated HTML contains <x-app> and overlay container div which contains modals as on the image
What I need is to access <div pane-id="default-1"...> to change z-index. and I don't know how. I cannot access it in CSS as any reference via :host is not possible.
I tried to access it programatically in x-app component. I have
class AppComponent implements AfterViewInit {
#override
void ngAfterViewInit() {
var doc = getDocument();
var alertDlg = doc.querySelector(".alert-dialog");
var alertPane = alertDlg.parent;
}
}
But alertDlg is always null. I also tried var alertDlg = querySelector(".alert-dialog");
Is there any way to access the element?
I solved it by adding *ngIf="dlgVisible" to <modal> tag, so it's now
<modal *ngIf="dlgVisible" [visible]="dlgVisible" dialog-id="alert-dialog-modal">
This way the dialog is injected to/removed from DOM by the visibility flag. The reason why I wanted to change z-index was to get the alert and other app wide dialogs above other dialogs created later in other components.
Altering DOM solves this as the dialogs are inserted after (and thus displayed above) other dialogs. Hope this will help someone.
I have a custom button component done in Polymer Dart:
<div id="buttonDiv">
<my-button id="traceButton"
mode="icon" faicon="fa-comment-o"
toolTip="Print a simple comment"
disabled="false" on-click="{{ traceSomething }}">
</my-button>
</div>
I'm trying to copy/paste this button somewhere else. So a user defines it somwhere, and I basically move it by way of getting $['buttonDiv'].children then inserting it somewhere else. The problem is that {{ traceSomething }} is now irrelevant since it's not part of the new parent. I get errors saying that the parent object, which is another polymer component doesn't have an instance getter "traceSomething".
My question is, is there a way to remove "traceSomething" before I insert it somwhere else? I tried removing the "onClick" event listeners, but the buttons still wants to call that function upon click. Also, I've tried adding a preventDefault, etc, like in: In Dart, if I listen to a click event with two listeners, how do I know which happens first?
But, no luck.
I'm not sure what you mean by copy/past. Do you clone the element, or do you just append it to some other elements children.
Anyway, I don't think you can remove the event listener if it was added declaratively. If you add it imperatively it is easy to remove and readd later.
import 'dart:async';
...
StreamSubscription subsc;
#override
attached() {
super.attached();
subscr = onClick.listen((e) => (this.parentNode as ShadowRoot).host.traceSomething(e));
}
#override
detached() {
super.detached();
if(subscr != null) {
subscr.cancel();
}
}
See also https://stackoverflow.com/a/22168745/217408 about accessing the parent of a Polymer element (for Dart Polymer <= 0.16.x)
I am very new to ZK framework and trying to customize few things and have struck at one point which I am not sure how to achieve that.
I have a predefined section where I need to show 2 drop down and a button and need to persist those drop down values on button click event.
This is how It has been define in Spring file
<bean id="mybean" parent="parentBean" class="WidgetRenderer">
<property name="detailRenderer">
<bean class="DetailsListRenderer" parent="abstractWidgetDetailRenderer"/>
</property>
</bean>
Here mybean is being used to show main section and I am adding my drop down using this bean while button are being added to detailRenderer.
Save button is bind to onClick event, but I am not sure how I can fetch values from my custom drop down?
I am aware about binding those Dropdown with onClick event but they have to be in same class.
Can any one suggest me how I can fetch values of those drop down.I am creating down down with following code
Listbox listbox = new Listbox();
listbox.appendItem("item1", "item1");
listbox.appendItem("item2", "item2");
This is my button code in another class
protected void createUpdateStatusButton(Widget widget,Div container)
{
Button button = new Button(LabelUtils.getLabel(widget, buttonLabelName, new Object[0]));
button.setParent(container);
button.addEventListener("onClick", new EventListener()
{
public void onEvent(Event event)throws Exception
{
MyClass.this.handleSaveStatusEvent(widget, event);
}
});
}
You may want to listen to the onSelect (I prefer to use Events.ON_SELECT rather than writing the strings) which is more specific to when the Listbox selection changes.
Either way, the key is to get the information you want from the Event passed to your EventListener, rather than going back to your Listbox itself. The basic Event usually carries useful information on getTarget and getData but using more specific events (SelectEvent in this case) will give you access to more relevant info.
button.addEventListener(Events.ON_SELECT, new EventListener<SelectEvent<Listitem, MyDataObject>() {
public void onEvent(SelectEvent<Listitem, MyDataObject> event) {
// Now you can access the details of the selection event..
List<Listitem> selectedItems = event.getSelectedItems();
List<MyDataObject> selectedObjects = event.getSelectedObjects();
}
});
You can find out what events are available for different ZK widgets in their Component Reference documentation.
If I understand the question (I don't think I did in my previous response) you want to gather information from the page (eg: Listbox selection state) when the user clicks a button. Your problem being that you are using disparate classes to compose the page and so don't have access to the various ZK Components when the button is clicked.
(Ignoring the multiple class issue for a minute)
From a high level, there are sort of two camps in the ZK community. The newer MVVM approach suggests the view should push the relevant state to the back end as the user interacts with the front end. This way, the back end never needs to ask for the client state, and when the button is clicked, the values/state are on the server ready to be used.
The other camp binds the client to the server such that the back end always has access to the client Components and when the button is clicked, the values/state can easily be retrieved by interacting with the components.
Another approach is more like what I was talking about in my previous answer, to not bind the back end to the client at all but to rely on event data as much as possible. I favor this approach where it is sufficient.
Now, you're free to choose your favored approach and ZK has lots of documentation on how to work in either of these camps. The question then is where is the client state stored on the server (either pushed there by the client in MVVM or bound there in MVC). I don't think that's a question that can be solved here, that's a software engineering challenge. I personally suggest you take on standard ZK patterns so as not to but heads with the framework. If you really want to go your route, you can grab a reference to the Listbox on the fly like so:
public class Foo {
public static final String LISTBOX_ID = "myListbox";
public void renderListbox(Component parent, MyItem items) {
Listbox listbox = new Listbox();
listbox.setId(LISTBOX_ID);
listbox.setParent(parent);
for (MyItem item : items) {
listbox.appendItem(item.getName(), item);
}
}
}
public class Bar {
#Listen(Events.ON_CLICK + " = #saveButton")
public void saveButtonClicked(Event event) {
Component saveButton = event.getTarget();
Listbox listbox = (Listbox) saveButton.getFellow(Foo.LISTBOX_ID);
Set<Listitem> selection = listbox.getSelectedItems();
// do something
}
I have the following fragment in a web component:
<div id="mycodes">
<template iterate='code in codeList'>
{{code}}
</template>
</div>
And in a Dart file, codeList is populated when the user clicks on a button:
void onMyButtonClick(Event event) {
HttpRequest.getString('http://getData').then((response) {
mylist = json.parse(response);
for(var code in mylist){
codeList.add(code['c']);
}
}
The problem is that I don't see data on first click. I need to click the button twice to see data.
But if I fill codeList manually (not from network data) as shown below, then I see the data on first click:
void onMyButtonClick(Event event) {
codeList.add("data 1");
codeList.add("data 2");
}
}
I need the template to iterate after the network data is available. It appears that event loop has already done its job of painting a page before the network data becomes available through future object.
Is there a way to refresh the page after model is updated in dart?
The reason your codeList currently populates if you add it with the on-click event is because the current web_ui has 'watchers' which automatically are called when an event happens. You then populate the list synchronously. However one of the downfalls of watchers is exactly your use case, when the data is updated asynchronously then the watchers don't reflect changes in time.
As a result the watchers are being phased out and replaced with observables. Observables allow us to flag a variable to be watched for reassignment and when that happens it will cause the view to change. For example:
#observable int x = 0;
// ...
x = 1;
When the x = 1 is called later in the code it automatically triggers the views to update. This leaves us with one problem however. When you are adding to a list, you are not reassigning the value itself. As such, observables also offer a function to convert a list to an observable list (this also works for maps).
For instance if you changed your declaration of codeList to something like the following, then when you add to the list later it will update accordingly.
var codeList = toObservable([]); // Assuming it starts with an empty list
// or
var codeList = toObservable(_startCodeList); // if you already have a list
Also see the Dart Tutorial: Target 7 for more information on using #observable and toObservable.
For more in-depth information, check out the article on Observables and Data Binding
You need to mark the fields you want WebUi to monitor with the #observable annotation. Otherwise you only get the initial value not any subsequent updates.
You can do this either directly on the object declaration or you can make the entire class as observable and all its fields will then be observed.
For an example see http://www.dartlang.org/docs/tutorials/custom-elements/#using-two-way-data-binding
I have a page made of custom components. In that page I have a button. If I click the button I have to call another page (page.mxml consisting of custom components). Then click event handler is written in Action-script, in a separate file.
How to make a object of an MXML class, in ActionScript? How to display the object (i.e. the page)?
My code:
page1.mxml
<comp:BackgroundButton x="947" y="12" width="61" height="22"
paddingLeft="2" paddingRight="2" label="logout" id="logout"
click="controllers.AdminSession.logout()"
/>
This page1.mxml has to call page2.mxml using ActionScript code in another class:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
}
Your Actionscript class needs a reference to the display list in order to add your component to the stage. MXML is simply declarative actionscript, so there is no difference between creating your instance in Actionscript or using the MXML notation.
your function:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
}
could be changed to:
static public function logout():StartSplashPage {
return new StartSplashPage();
}
or:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
myReferenceToDisplayListObject.addChild( startPage );
}
If your actionscript does not have a reference to the display list, than you cannot add the custom component to the display list. Adding an MXML based custom component is no different than adding ANY other DisplayObject to the display list:
var mySprite:Sprite = new Sprite();
addChild(mySprite)
is the same as:
var startPage:StartSplashPage = new StartSplashPage();
myReferenceToDisplayListObject.addChild( startPage );
Both the Sprite and the StartSplashPage are extensions of DisplayObject at their core.
You reference MVC in the comments to another answer. Without knowing the specific framework you've implemented, or providing us with more code in terms of the context you are trying to perform this action in, it is difficult to give a more specific answer.
I assume that you are on a page with a set of components and want to replace this set of components on the page with a different set of components. My apologies in advance if this is not what you are trying to do.
You can do this using ViewStacks and switching the selected index on selection -- this can be done either by databinding or by firing an event in controllers.AdminSession.logout() and listening for that event in the Main Page and switching the selectedIndex of the view stack in the handler function.
MainPage.mxml
<mx:ViewStack>
<views:Page1...>
...
<comp:BackgroundButton x="947" y="12" width="61" height="22"
paddingLeft="2" paddingRight="2" label="logout" id="logout"
click="controllers.AdminSession.logout()"/>
</views:Page1...>
<views:Page2 ...>
...
<comp:Comp1 .../>
<comp:Comp2 .../>
</views:Page2>
I think you may use state to do you work.
You may take a look at http://blog.flexexamples.com/2007/10/05/creating-view-states-in-a-flex-application/#more-221
Edit:
I am not sure I fully understand your case.
As I know, you may make a new state in page1.mxml, and name it, eg. secondPageState, and then put the custom component page2.mxml in the secondPageState.
In the controller, you need an import statement to import the page1 component and make a public var for the page1 component, eg. firstPage.
Then, the code will similar to:
public function logout():voild
{
firstPage.currentState = "secondPageState";
}
Another solution:
If you don't like the change state solution, you may try to use the addchild, to add the custom component to your application.