Trying to build some simple app with rikulo framework and have a question:
Is it possible to find View inside hierarchical layout ? and how ? (in Dart)
There's some documentation on Rikulo site about IdSpace but I didn't quite understand how to use it. Should I extend View with IdSpace ? Or View will auto-generate the Id ?
Update (add code example)
/*
* Function will actualy build View
*/
void _buildUi(Element tagElement)
{
View mainView = new View();
mainView.profile.width = '100%';
mainView.profile.height = '100%';
mainView.layout.type = 'linear';
mainView.layout.orient = 'vertical';
mainView.style.cssText = "background: yellow;";
View vWorkSpace = new View();
vWorkSpace.profile.width = 'flex';
vWorkSpace.profile.height = 'flex';
vWorkSpace.layout.type = 'linear';
vWorkSpace.layout.orient = 'horizontal';
vWorkSpace.style.cssText = "background: red;";
//
// Left menu
View vLeftBar = new View();
vLeftBar.profile.width = "10%";
vLeftBar.profile.height = "10%";
vLeftBar.layout.type = 'linear';
vLeftBar.layout.orient = 'vertical';
vLeftBar.layout.spacing = '10';
View vLogo = new View();
vLogo.addChild(new Image('images/google_chrome.png'));
vLeftBar.addChild(vLogo);
Button vButton = new Button();
vButton.text = 'Sign in with Google';
vLeftBar.addChild(vButton);
vButton.on.click.add((e){ // Somehow I get an error here: Method 'add' not defined for class 'Stream'
broadcaster.send(new ViewEvent('foo'));
});
vWorkSpace.addChild(vLeftBar);
mainView.addChild(vWorkSpace);
mainView.addToDocument(ref: tagElement, layout: true);
}
In another place in dart.app when handling the vButton click event. How I could find (in code) the vLogo View ?
The easiest way to retrieve a View in the code is to give it an id:
View vLogo = new View();
vLogo.id = "vLogo";
Then, in your event listener, use query to access it:
button.query("#vLogo"); // returns vLogo
However, in your case, you will be able to directly access the vLogo instance within the event listener closure.
Sure, like Element, View provides CSS selector based retrieval called query and queryAll. You can use them to retrieve the view as you retrieve the DOM elements.
In general, you don't have to worry about IDSpace, unless you want to use the same ID in different views. A hierarchy tree itself is an ID space. If a view implements IDSpace, it forms another ID space.
Related
this.grid = new Grid<>(Person.class);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.removeAllColumns();
this.grid.setColumns("firstname");
this.editButton = new Button(null, ImageIcons.EDIT.create());
this.editButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.editButton);
this.deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create());
this.deleteButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.deleteButton);
this.addComponentAsFirst(this.grid);
I have a personList with several entries. The grid shows all these entries with their first name. But it only shows the buttons in the last row. What is the problem?
You use the very same Button instance for each row. You should create a new Button within the componentRenderer, so each row will have its own Button.
Try it like this:
this.grid = new Grid<>(Person.class, false);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.setColumns("firstname");
this.grid.addComponentColumn(person -> {
// edit: added click listener for inline-editing of the person. Editor must be configured for this to work. See https://vaadin.com/components/vaadin-grid/java-examples/grid-editor
// You don't have to use inline-editing if you don't want. you can also edit the item in a separate Layout with Input fields and a Binder.
Button editButton = new Button(ImageIcons.EDIT.create(), click -> {
this.grid.getEditor().editItem(person);
});
editButton.getStyle().set("color", "#000000");
return editButton;
});
this.grid.addComponentColumn(person -> {
// edit: added click listener for person removal
Button deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create(), click -> {
this.personDao.remove(person);
// TODO: when using an in-memory dataprovider, fetch all items again from service/dao and set them with grid.setItems(this.personDao.findAll());
// but that is not necessary when using a callback dataprovider, which I belive OP is using
this.grid.getDataProvider().refresh();
});
deleteButton.getStyle().set("color", "#000000");
return deleteButton;
}
this.addComponentAsFirst(this.grid);
Edit: a minor thing but I still wanted to mention it - You do some unnecessary creation of columns, only to remove them all again later. Instead of this you could tell the grid not to create these columns in the first place, by passing false as second parameter of the Grid constructor.
this.grid = new Grid(Person.class, false);
// instead of
this.grid = new Grid(Person.class);
this.grid.removeAllColumns();
I am using Nativescript Angular, (NS version 4.1) I am trying to implement a requirement for users to swipe up twice to go home on
new IOS devices. Many mobile games have this functionality.
I know this has to do with prefersHomeIndicatorAutoHidden and
preferredScreenEdgesDeferringSystemGestures in the ViewController
Is there a way I can access these methods in Nativescript Angular?
Or just set a home indicator to require two swipes to go home?
Any help would be greatly appreciated thanks!
There is an open feature request to allow iOS root view controller properties to be overridden. You have to actually override the preferredScreenEdgesDeferringSystemGestures to UIRectEdge.All and as per Apple documentation you have to update setneedsupdateofhomeindicator as well.
But if you try to access the these properties directly (e.g. this.page.ios.prefersHomeIndicatorAutoHidden = true), it will give you error TypeError: Attempted to assign to readonly property.
These is workaround discussed here where to you have copy the controller, modify the property and assign it back to owner.
const UIViewControllerImpl = new page.Page().ios.constructor as typeof UIViewController;
const MyCustumUIViewController = UIViewController['extend'](Object.assign(
{},
// merge in the original methods
...UIViewControllerImpl.prototype,
// add additional instance method / property overrides here, such as ...
{
preferredScreenEdgesDeferringSystemGestures() {
console.log("This will be called from native!");
return UIRectEdge.All;
}
}
));
const performNavigation = frame.Frame.prototype['performNavigation'];
frame.Frame.prototype['performNavigation'] = function(navigationContext:{entry:frame.BackstackEntry}) {
const page = navigationContext.entry.resolvedPage;
const controller = (<typeof UIViewController>MyCustumUIViewController).new();
controller['_owner'] = new WeakRef(page);
controller.automaticallyAdjustsScrollViewInsets = false;
controller.view.backgroundColor = new color.Color("white").ios;
page['_ios'] = controller;
page.setNativeView(controller.view);
performNavigation.call(this, navigationContext);
}
I have a controller create and return content where it triggers an alert.
The problem it load an empty page. How can I prevent it to load an empty page and stays in the current view and do nothing just pop the alert.
What I really wanted here is before the user can create new data, it will validate first if the diseaseID is already existing for specific assessmentID, and when the result is null, it will just pop an alert and do nothing. But here I'm just trying make alert() work properly.
Controller:
public ActionResult CreateDisease(int? diseaseID,int? assessmentID, DiseaseList diseaselist)
{
diseaselist.DiseaseID = diseaseID;
diseaselist.AssessmentID = assessmentID;
db.DiseaseLists.Add(diseaselist);
db.SaveChanges();
return Content("<script language='javascript' type='text/javascript'>alert('Item already exist');</script>");
}
You dont need to return the script as content from the controller, just return the values as json that will tell you that the item already exist and based on that true or false value show an alert from the client side js.
your controller code will look something like this
diseaseModel.DiseaseID = diseaseID;
diseaseModel.AssessmentID = assessmentID;
diseaseModel.AlreadyExist = true;
return Json(diseaseModel);
I am new on Vaadin.
How to pass Table component to new popup screen in Vaadin 7? Assume I already created table using com.vaadin.ui.Table.
Table aaa = new Table();
Currently Vaadin tutorial just show how to create print popup without pass component/data.
Based on below code
public static class PrintUI extends UI {
#Override
protected void init(VaadinRequest request) {
// Have some content to print
setContent(new Label(
"<h1>Here's some dynamic content</h1>\n" +
"<p>This is to be printed.</p>",
ContentMode.HTML));
// Print automatically when the window opens
JavaScript.getCurrent().execute(
"setTimeout(function() {" +
" print(); self.close();}, 0);");
}
}
...
// Create an opener extension
BrowserWindowOpener opener =
new BrowserWindowOpener(PrintUI.class);
opener.setFeatures("height=200,width=400,resizable");
// A button to open the printer-friendly page.
Button print = new Button("Click to Print");
opener.extend(print);
Appreciated if someone could show me how to pass Table aaa into PrintUI class.
Window window = new Window("my test table popup");
window.setContent(table);
window.setModal(true);
getUI().addWindow(window);
The only way that I have found to pass objects to the UI class in popup window is to store them in session:
Table table = new Table();
VaadinSession.getCurrent().setAttribute("table", table);
In the popup window:
Table t = (Table) VaadinSession.getCurrent().getAttribute("table");
You can also initialize your Table in your PrintUI class. If you need to initialize a specific Table instance, you can pass, let's say, your table id parameter to the UI via .getParameter("idTable") (which, in the end, works as adding a GET parameter to the URL) and then retrieve it in your PrintUI's init() method via the request parameter with .getParameter("idTable").
It seems like this should be very easy, but I'm missing something. I have a custom Element:
public class PostSummaryElement:StyledMultilineElement,IElementSizing
When the element's accessory is clicked on, I want to push a view onto the stack. I.e. something like this:
this.AccessoryTapped += () => {
Console.WriteLine ("Tapped");
if (MyParent != null) {
MyParent.PresentViewController(new MyDemoController("Details"),false,null);
}
};
Where MyDemoController's gui is created with monotouch.dialog.
I'm just trying to break up the gui into Views and Controlls, where a control can push a view onto the stack, wiat for something to happen, and then the user navigates back to the previous view wich contains the control.
Any thought?
Thanks.
I'd recommend you not to hardcode behavior in AccessoryTapped method, because the day when you'll want to use that component in another place of your project is very close. And probably in nearest future you'll need some another behavior or for example it will be another project without MyDemoController at all.
So I propose you to create the following property:
public Action accessoryTapped;
in your element and its view, and then modify your AccessoryTapped is that way:
this.AccessoryTapped += () => {
Console.WriteLine ("Tapped");
if (accessoryTapped != null) {
accessoryTapped();
}
};
So you'll need to create PostSummaryElement objects in following way:
var myElement = new PostSummaryElement() {
accessoryTapped = someFunction,
}
...
void someFunction()
{
NavigationController.PushViewController (new MyDemoController("Details"), true);
}