I am completely new to Nativescript, I am trying to add class Name dynamically to a gridlayout on tap.
I am not using Angular 2.
How to access the grid layout element and add class name to the same.
All that you need to do is search for the desired element in the UI tree for example by accessing the parent of the Button or by setting an id to the element and using the .getViewById() method of the root of the Page or the Page itself.
Finally in order to set the css class of that View simply set its className property, something like this:
export function onChangeCssClassButtonTap(args) {
var button = args.object as Button;
var parentGridLayout = button.parent as StackLayout;
parentGridLayout.className = "myGridCssClassName";
}
Here are some documentation articles that may be useful to you:
Finding View by its id
Styling in NativeScript
Related
I have a prefab which contains some buttons and I want to get the buttons and add specific onClick functions to them via script. I cant find the right way to get the buttons.
What I am trying is:
tempGo = Instantiate(prefabs[0]);
tempGo.transform.SetParent(transform, false);
tempGo.transform.localScale = Vector3.one;
tempGo.transform.localPosition = Vector3.zero;
Transform t = tempGo.GetComponentInChildren<Transform>().Find("AddGoals");
"AddGoals" Is my Buttons(Tag name)
So after this point how can I code it to add a specific function when the button gets clicked?
Any help would be appreciated thank you!
Get button component and add listener to it. Listener will call the function when that button is clicked. TaskOnClick is an example function that will be called when the button is clicked.
t.GetComponent<Button>().onClick.AddListener(TaskOnClick);
void TaskOnClick()
{
Debug.Log("You have clicked the button!");
}
Using .Find(""), you are looking for a gameobject with that name, not its tag. What you can do is after instantiating the object, use GameObject.FindGameObjectsWithTag("AddGoals"). This will return an array of all of the objects with that tag. Then with Linq you can do something like:
var items = GameObject.FindGameObjectsWithTag("AddGoals"); //This gives gameobject array
var itemTansforms = items.Select(x=>x.transfrom).ToList(); //gives you a list of the object tansforms
As for adding an event, you would need to grab the button component of the object and then add the onclick event.
items.ForEach(x=>x.GetComponent<Button>().AddListener(delegate {Debug.Log($"{x.name} has been clicked")}));
You would have to make sure it is actually a button, or the code will fail. This of course can be modified and is just an example. I hope this helps!
It seems Aurelia is not aware when I create and append an element in javascript and set a custom attribute (unless I am doing something wrong). For example,
const e = document.createElement('div');
e.setAttribute('custom-attr', 'some value');
body.appendChild(e);
Is there a way to make Aurelia aware of this custom attribute when it gets appended?
A little background: I am creating an app where the user can select their element type (e.g. input, select, checkbox etc.) and drag it around (the dragging is done in the custom attribute). I thought about creating a wrapper <div custom-attr repeat.for="e of elements"></div> and somehow render the elements array, but this seemed inefficient since the repeater will go through all the elements everytime I push a new one and I didn't not want to create a wrapper around something as simple as a text input that might be created.
You would have to manually trigger the Aurelia's enhance method for it to register the custom attributes or anything Aurelia related really. And you also have to pass in a ViewResources object containing the custom attribute.
Since this isn't as straight forward as you might think, I'll explain it a bit.
The enhance method requires the following parameters for this scenario:
Your HTML as plain text (string)
The binding context (in our scenario, it's just this)
A ViewResources object that has the required custom attribute
One way to get access to the ViewResources object that meets our requirements, is to require the custom attribute into your parent view and then use the parent view's ViewResources. To do that, require the view inside the parent view's HTML and then implement the created(owningView, thisView) callback in the controller. When it's fired, thisView will have a resources property, which is a ViewResources object that contains the require-d custom attribute.
Since I am HORRIBLE at explaining, please look into the example provided below.
Here is an example how to:
app.js
import { TemplatingEngine } from 'aurelia-framework';
export class App {
static inject = [TemplatingEngine];
message = 'Hello World!';
constructor(templatingEngine, viewResources) {
this._templatingEngine = templatingEngine;
}
created(owningView, thisView) {
this._viewResources = thisView.resources;
}
bind() {
this.createEnhanceAppend();
}
createEnhanceAppend() {
const span = document.createElement('span');
span.innerHTML = "<h5 example.bind=\"message\"></h5>";
this._templatingEngine.enhance({ element: span, bindingContext: this, resources: this._viewResources });
this.view.appendChild(span);
}
}
app.html
<template>
<require from="./example-custom-attribute"></require>
<div ref="view"></div>
</template>
Gist.run:
https://gist.run/?id=7b80d2498ed17bcb88f17b17c6f73fb9
Additional resources
Dwayne Charrington has written an excellent tutorial on this topic:
https://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templating-engine-enhance-api/
How can I get the current screen I'm working on? For example, I have a slidedrawer containing buttons to navigate to another page. When I'm on a certain page(About Page) and when I tap the button to navigate to the About Page, I want to just close the slidedrawer if it is on the same page.
My idea is that to get the current page and just compare it but I dont know how.
Note: The slidedrawer content menu is a custom component.
There are several ways to solve this problem. The easiest is to install the nativescript-dom plugin and then you can do this really simply:
// This will return an array of elements that are SlideDrawer's.
var slideDrawers = getElementsByTagName('SlideDrawer');
or even better is if you have assigned your SlideDrawer an id, you can do
<!-- Declarative XML -->
<SlideDrawer id="myId">...</SlideDrawer>
// JS: Will return a single element that matching the id.
var mySlideDrawer = getElementById('myId');
However, if you just want to not use any helpers and you want to get direct access to the currentPage the method is to do:
var frame = require('ui/frame');
var myPage = frame.topmost().currentPage;
Please note; the currentPage will reflect the old page while navigation is taking effect until the navigatedTo event is fired, at that point the currentPage is actually updated to be the currentPage. However, if you are looking for the current page during any of the navigation events (NavigatingTo, NavigatedTo, Loaded, Unloaded) each of those events are transferred a parameter with the current page as part of the object.
exports.onNavigatedTo = function(args) {
var page = args.object;
// do what you want with the current page variable
}
I can't figure out how to programatically add a view into a layout or page.
I need to add views at runtime without using static xml declaration since i need to fetch them from an http requested object... . I didn't find useful informations in the docs.
Anyone knows how to do?
I think you meant to dynamically add some view / controls to the page rather than to navigate into another page.
If so, you just need to add some controls into one of the layouts in your page (only containers [=layouts] can have multiple children.
so, your code (viewmodel/page controller) would look something like:
var layout = page.getViewById("Mycontainer");
// create dynamic content
var label = new Label();
label.text = "dynamic";
// connect to live view
layout.addChild(label)
In addition to having a page included inside your app (normal); you download the xml, css, & js to another directory and then navigate to it by then doing something like page.navigate('downloaded/page-name');
you can also do
var factoryFunc = function () {
var label = new labelModule.Label();
label.text = "Hello, world!";
var page = new pagesModule.Page();
page.content = label;
return page;
};
topmost.navigate(factoryFunc);
https://docs.nativescript.org/navigation#navigate-with-factory-function
You should check out this thread on the {N} forum.
The question is about dynamically loading a page and module from a remote server. The (possible) solution is given in this thread.
how can add new control from controller
// create a simple Input field
var oInput1 = new sap.m.Text('input1');
oInput1.setText("Some Text ");
oInput1.setTooltip("This is a tooltip ");
// attach it to some element in the page
oInput1.placeAt("sample1");
in view I add holder
try to add text from controller but it not display on screen.
var oLayout = this.getView().byId("idholder");
oLayout.addContent(oInput1);
is Run-time add new control is not possible. we have always render control in view and then update it is this good practice we have to follow ?
The placeAt() method is normally only used to place a View or App into the HTML.
If you want to add a UI5 control on your view, you can do it this way from the controller:
this.getView().addContent(oInput1);
But most likely you won't add controls directly to the view, but rather inside a layout or something inside your view. In that case, do it like this:
var oLayout = this.getView().byId("idOfYourSpecificLayoutFrame");
oLayout.addContent(oInput1);