In Alloy Titanium, I can access XML elements with their id $.element_id but how do I get elements by their class ?
I have
<View id="main" layout="horizontal" horizontalWrap="true">
<Button left="4%" width="125dp" height="125dp" backgroundImage="menus/woodblock.png"></Button>
<Button left="13%" width="125dp" height="125dp" backgroundImage="menus/woodblock.png"></Button>
<Button class="top30" left="4%" width="125dp" height="125dp" backgroundImage="menus/woodblock.png"></Button>
<Button class="top30" left="13%" width="125dp" height="125dp" backgroundImage="menus/woodblock.png"></Button>
<Button class="top30" left="4%" width="125dp" height="125dp" backgroundImage="menus/woodblock.png"></Button>
<Button class="top30" left="13%" width="125dp" height="125dp" backgroundImage="menus/woodblock.png"></Button>
</View>
And I want to get all class="top30"
There is no way in Alloy to access views directly by using their class except by iterating over all possible views on the screen and checking their className value.
If all your views with class="top30" are children of the same view you can try using Titanium.UI.View.children property:
var i, view
for (i in $.main.children) {
view = $.main.children[i];
if (view.className === 'top30') {
/* Do your operation here */
}
}
I took the daninula posted and refactored it into a commonJS module. Untested but could be useful.
Find it here:
https://gist.github.com/shouse/06f447884fbc85ec122c
Or just try the code:
/**
* #method getViewByClass
* This will take a class and an optional parent and find children with that class
* Untested but will likely work
* #param {String} _class Class name
* #param {Object} _parent Optional param to specify parent to iterate through
*/
exports.getViewByClass = function(_class, _parent) {
_parent = _parent || $.main;
var classArray = [];
_.each(_parent.children, function(child){
if (child.className === _class) {
classArray.push(child);
}
});
return classArray;
};
Related
hey guys I am using multiple selector in my app..the thing I want t show is that I want to generate num from 1 to 69 through loop..but when I tried to generate number by loop it gives me error like undefined is not a function ...
I tried a loop as globally and in my render function but every time I have same error...
export default class Createottery extends Component {
static navigationOptions = {
header: null
}
state = { selectedFruits: [],mynum:[] }
onSelectionsChange = (selectedFruits) => {
//alert(JSON.stringify(selectedFruits))
// selectedFruits is array of { label, value }
this.setState({ selectedFruits:selectedFruits })
alert(JSON.stringify(this.state.selectedFruits))
}
componentDidMount(){
for(let mylottery=0; mylottery<=69;mylottery++)
{
this.setState({mynum:mylottery})
//alert(mylottery)
}
}
render () {
let comeon=0
for(comeon=0;comeon<=5;comeon++){
comeon=comeon }
return (
<Container style={styles.Containerstyle}>
<Header searchBar rounded style={styles.headerstyle}>
<Item style={{backgroundColor:'#000'}}>
<Input placeholder="Lottery" placeholderttextSize={22} placeholderTextColor={'#fff'}/>
<Icon name="search" style={{color:'#fff'}} size={22}/>
</Item>
</Header>
<Content>
<View >
<Text style={{color:'#000',alignItems: 'center',fontSize:22}}>select any 5 number or quick pick</Text>
<SelectMultiple
style={{backgroundColor:'black'}}
items={comeon}
//selectedItems={this.state.selectedFruits}
// onSelectionsChange={this.onSelectionsChange}
/>
</View>
</Content>
</Container>
)
I want when my app starts It gives my all number which I want to generate through loop
1) Because you are sending number to items of SelectMultiple Component. items should be array of object.
<SelectMultiple
style={{backgroundColor:'black'}}
items={comeon} {//this should be array instead of number}
selectedItems={this.state.selectedFruits}
onSelectionsChange={this.onSelectionsChange}
/>
2) You are doing the same mistake while creating array in componentDidMount. You are setting every looped number to mynum
Is there a way to set or disable the OverflowDocumentCount of DocumentCard? Currently it is defaulted to 3 and I can't seem to change it:
I would want to display all files basically.
Unfortunately neither via DocumentCardPreview component methods nor via properties (IDocumentCardPreviewProps), the limit for the items in preview mode could not be modified.
But you could consider to introduce a custom DocumentCardPreview component to display all the items, for example:
const MyDocumentCardPreview = (props: IDocumentCardPreviewProps) => {
const { previewImages } = props;
const fileListItems = previewImages.map((file, fileIndex) => (
<li key={fileIndex}>
<Image
className={css(
"ms-DocumentCardPreview-fileListIcon",
styles.fileListIcon
)}
src={file.iconSrc}
role="presentation"
alt=""
width="16px"
height="16px"
/>
<Link {...file.linkProps}>{file.name}</Link>
</li>
));
return (
<div
className={css(
"ms-DocumentCardPreview",
styles.preview,
"is-fileList " + styles.previewIsFileList
)}
>
<ul className={css("ms-DocumentCardPreview-fileList", styles.fileList)}>
{fileListItems}
</ul>
</div>
);
}
Demo
You can use the getOverflowDocumentCountText prop on the DocumentCardPreview component to customize the overflow text.
<DocumentCard>
<DocumentCardPreview
previewImages={previewImages}
getOverflowDocumentCountText={getOverflowDocumentCountText}
/>
</DocumentCard>
It takes a function, which (optionally) takes the overflow count and returns a string:
const getOverflowDocumentCountText = (overflowCount) => "+ 315 more";
Here is a CodeSandbox demo of it in action.
I'm passing a render to the Accordion element in native-base using the renderContent prop. The render contains two buttons, which, when pressed, run functions that are local to the current component. Unfortunately those functions are not available once it has been actually rendered.
How do I bind the functions properly so that when pressed, the correct functions are referenced?
I'm using the most modern stable releases of react-native, native-base, and I'm running this through expo for testing.
Here's the documentation on native-base:
http://docs.nativebase.io/Components.html#accordion-custom-header-content-headref
Accordion:
<Accordion
dataArray={ this.state.websites }
renderContent={ this._renderAccordionContent }
/>
renderContent:
_renderAccordionContent(content) {
return (
<Button
onPress={() => this.openSite(content.path)}
>
<Text>Open</Text>
</Button>
<Button
onPress={() => this.editSite(content.key)}
>
<Text>Edit</Text>
</Button>
)
}
When the buttons are pressed, the expected results are that the functions are run.
The actual results are that when the buttons are pressed, these errors are populated:
_this2.openSite is not a function.
_this2.editSite is not a function.
Thank you for any help.
Check out this excellent article that shows several different ways of binding your functions https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56
Here is an example of binding it in the constructor of your component that uses the Accordion component. It is by no means the only way of binding the functions. The above article gives 5 different ways of doing it.
class MyComponent extends Component {
constructor(props) {
super(props);
this.openSite = this.openSite.bind(this);
this.editSite = this.editSite.bind(this);
}
// I am assuming you have written your functions like this and not as arrow functions
openSite (path) {
...
}
editSite (key) {
...
}
_renderAccordionContent(content) {
return (
<Button
onPress={() => this.openSite(content.path)}
>
<Text>Open</Text>
</Button>
<Button
onPress={() => this.editSite(content.key)}
>
<Text>Edit</Text>
</Button>
)
}
render() {
...
<Accordion
dataArray={ this.state.websites }
renderContent={ this._renderAccordionContent }
/>
...
}
}
I want to have two tab buttons on top and some content underneath.
After that, the content I need a View like this :
<Form style={styles.form}>
<Label style={styles.label}>
data 1
</Label>
<Item >
<Input/>
</Item>
<Label style={styles.label}>
Data2
</Label>
<Item>
<Input/>
</Item>
</Form>
When I clicking on the first button, it is active. I need that form to appear.
After that, when I clicking on the second button, I need that form change to:
<Form style={styles.form}>
<Label style={styles.label}>
data 3
</Label>
<Item >
<Input />
</Item>
</Form>
What I'm understanding is that I need a state variable.
state = {showFirst : true, showSecond:false }
and have somewhere a conditional:
if showFirst true, display FORM1
if showSecond true, display FORM2
And
onPress {() => {this.setState{{the state = true)}}
But I am not sure how to bind this together as I'm using React Native for the first time.
Currently what I'm using now is it a good practice?
I set separate states variables for both forms, because another button may be added later.
So I can't only one button:
state = { showForm: true}
showForm?Form1:Form2
onPress={() => {this.setState{{showForm:false)}}
How can I get this to work?
This is a minimum example Component for what you said you were trying to achieve:
import React, {Component} from ‘react’;
import {Button, View} from ‘react-native’;
export default class ExampleComponent extends Component {
constructor(props) {
super(props);
this.state = {
showForm: 0
};
}
render() {
var form;
if (this.state.showForm === 0) {
form = (
<View> INSERT_FORM1 </View>
);
} else if (this.state.showForm === 1) {
form = (
<View> INSERT_FORM2 </View>
);
}
return (
<View>
<Button title=‘Show Form 1’ onPress={() => this.setState({showForm: 0})}/>
<Button title=‘Show Form 2’ onPress{() => this.setState({showForm: 1})}/>
{form}
</View>
);
}
}
You can dynamically choose what content to show based on the Component props and state.
In the example above I used a numerical value to determine what form to show to minimize the amount of state values you would have to track later if the form count expanded.
A switch statement would be a better choice in the event of more available form choices, but I used if-else here for easy of typing for now.
Hi i'm a beginner with titanium and i would like to get the value from textfields
in a tablerow
my view
<Alloy>
<Collection src="field"/>
<Window id="addWin" title="Add Name" class="container" modal="true">
<TableView id="textfield" dataCollection="field">
<TableViewRow>
<TextField class="insertField" hintText="{field_description}"/>
</TableViewRow>
</TableView>
<Button onClick="addForm">Add form</Button>
</Window>
And my controller
function addForm() {
while (fieldlist.isValidRow())
{
var field_description = fieldlist.fieldByName('field_description');
if(field_description == 'name') {
var contact = Alloy.createModel('contact', {
name : $.insertField.value,
});
}
fieldlist.next();
}
contacts.add(contact, {silent:true});
contact.save();
closeWindow();
}
I need to filter my insertField.value to get just one textfield from my form but i don't know how to do it. It return something like Cannot read property 'value' of undefined.
I think i need to loop it but i don't how.
Thanks if you help me
Well if you have the view file static ( as pasted by you ) , I will suggest to add an id to the TextField.
Something like :
<TextField class="insertField" id="myTextField" hintText="{field_description}"/>
Then get the value of TextField as :
var myTextFieldValue = $.myTextField.getValue();