I have a component with a section tag with an id and ref of map. The id is used to load a Google Map, don't worry about this.
<section
id="map"
ref="map"
>
</section>
I have a function called showUserLocationOnTheMap() with a button called Map that's invoked when a User clicks on it. This function shows a marker on the map based on an address, that is stored in the db from a previous step.
showUserLocationOnTheMap(latitude, longitude) {
let map = new google.maps.Map(document.getElementById("map"), {
zoom:15,
center: new google.maps.LatLng(latitude, longitude),
mapTypeId:google.maps.MapTypeId.ROADMAP
});
const marker = new google.maps.Marker({
position: new google.maps.LatLng(latitude, longitude),
map: map
});
google.maps.event.addListener(marker, "click", () => {
const infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(
`<div class="ui header">
<h6>company name</h6>
</div>
`
);
infoWindow.open(map, marker);
});
this.$refs.map.scrollToTop();
},
<button
#click="showUserLocationOnTheMap(item.profile.latitude,item.profile.longitude)"
class="apply-job-btn btn btn-radius btn-primary apply-it"
>
Map
</button>
What I'm trying to do is, I have a bunch of search results, so when someone is scrolling far down the page and they click the map button from the record, it will do two things.
It shows a marker on the map (This is working)
It scrolls back up to the top of the page so the User can see the Map with the marker on it.
WHAT I TRIED:
I created this function below:
scrollToTop() {
this.$el.scrollTop = 0;
}
I added a ref attribute called map to my Section tag and then at the end of my showUserLocationOnTheMap() function I called this line (as you can also see above).
this.$refs.map.scrollToTop();
The problem is I'm getting this error:
Cannot read property 'scrollToTop' of undefined"
Does anyone know how it would be possible to conditional render a view in the list view template based on the passed in bindId ?
I have a template which should show a view only if the value if the label that is passed in is not empty.
<View class="productBannerLabelWrapper productBanner1">
<Label class="productBannerLabel" bindId="productBanner1" />
</View>
The label has a view around it, because the label needs a collared background which is larger than the label itself.
Thank for helping out
When you fill you item array you can set the visible property like this:
var prop = {
productBanner1: {
text: "Text",
visible: (checkValue)?1:0
}
}
items.push(prop);
$.list_section.items = items;
with Alloy:
add a databinding to the visible parameter like productBanner:visible="{isVisible}" and use a dataTransform to change the module before assigning it:
function transformFnc(model) {
return {
otherStuff: model.attributes.otherStuff
isVisible: (checkValue)?1:0
}
}
i fill data in the textfield when i press done on android keyboard it will enter the data in the tableviewrow but i dont know how?
i did it on button click
and second question is : i want to delete the data on button click whose
row has
hasCheck=true
i mean to say these rows on button click
index.xml
<TableView id="table">
<TableViewRow title="Capsicum" onClick="select"></TableViewRow>
<TableViewRow title="Beans" onClick="select"></TableViewRow>
<TableViewRow title="Spinach" onClick="select"></TableViewRow>
<TableViewRow title="Pizza" onClick="select"></TableViewRow>
<TableViewRow title="Burger" onClick="select"></TableViewRow>
</TableView>
<TextField id="textfield" class="insertField" hintText="Add ingredients"></TextField>
<Button id="addButton" title="Add" onClick="addRow" ></Button>
<Button id="removeButton" title="Remove" onClick="removeRow" ></Button>
</Window>
index.js file
function addRow(){
var myTextFieldValue = $.textfield.getValue();
var row=Ti.UI.createTableViewRow({title:myTextFieldValue});
$.table.appendRow(row);
}
function select(e) {
if (e.row.hasCheck) {
e.row.hasCheck = false;
} else {
e.row.hasCheck= true;
}
}
It's pretty simple if you properly follow the Appc Docs:
Answer for Query 1:
There's an event called return for TextField proxies which is called when you press Done button or Return button on iOS or Android. But the title of this Return button can be anything as specified here: Return Key Title
So, you have to make below changes in TextField node to make it work on pressing enter on keyboard, like this:
<TextField id="textfield" returnKeyType="Ti.UI.RETURNKEY_DONE" onReturn="addRow" class="insertField" hintText="Add ingredients" />
Answer for Query 2:
You will have to fetch all rows from table which is a bit lengthy because you cannot directly fetch rows from TableView, rather you will first need to fetch the first section of TableView & then rows from section.
Note: If you do not add any section in TableView, then by default Titanium adds a single section in TableView and add rows in this section. This is why you need to take care of getting the first section first.
Here's the code to delete all checked-rows on Remove button click.
function removeRow() {
// first get all sections of table which will be first section in your case
var sections = $.table.sections;
// perform this check to make your code error free when there are no rows added to tableview.
if (sections.length !== 0) {
var rows = sections[0].rows;
var totalRows = rows.length;
if (totalRows !== 0) {
// now delete all rows which has uncheck=true
for (var i=0; i<totalRows; i++) {
var tempCurrentRow = rows[i];
if (tempCurrentRow.hasCheck) {
$.table.deleteRow(tempCurrentRow);
}
}
}
}
}
Just a minor change in your adding code so that you don't accidentally add empty title rows:
function addRow(){
var myTextFieldValue = $.textfield.value.trim();
if (myTextFieldValue != "") {
$.table.appendRow( Ti.UI.createTableViewRow({title:myTextFieldValue}) );
}
}
I have buttons I want to center horizontally in a view. There are three, and all I can seem to get is:
[button1-button2-button3------------------------------]
What I really want is
[--------button1--------button2--------button3--------]
These buttons are dynamic widths too. The amount of buttons will change, some views have 1, others have 2 or 3. Depending on an action, the number of buttons can change. I need this support both iOS and android.
Try splitting the screen into n different columns using percentage layout. Then add your buttons to their respective invisible container.
var n = // Your number of buttons horizontal
var container = Ti.UI.createView({width : "100%", layout: "horizontal" });
for(var i=0;i<n;i++) {
var column = Ti.UI.createView({
width : (100/n)+"%",
});
// Create your button here
// .....
// .....
// Now add it to the column
column.add(yourNthButton);
// Now add the column to the container
container.add(column);
}
How about wrapping your buttons in a view with layout set to 'horizontal'?
var wrapperView = Ti.UI.createView({
layout : 'horizontal',
...
});
// In a view with horizontal layout,
// the positioning is relative to the preceding element
var buttonOne = Ti.UI.createButton({
right : 10,
...
});
wrapperView.add(buttonOne);
Untested, but give it a try!
UPDATE
Ok, the above code alone won't do what you wanted. I wrote a more complete example here.
Seems a bit clumsy, so if someone has a better solution, please let us know!
// Create our window
var win = Ti.UI.createWindow();
// Our wrapper view
var wrapperView = Ti.UI.createView({
width : Ti.UI.FILL,
height : 40,
top : 0,
layout : 'horizontal',
});
// Add some test buttons to our wrapper
for(var i=0; i<3; i++) {
wrapperView.add(Ti.UI.createButton({
title : 'Test ' + i,
height : 30,
}));
}
// Add wrapperView to our window and open it
win.add(wrapperView);
win.open();
// Wait until "size" becomes available
win.addEventListener('postlayout', distributeButtons);
// Distribute buttons evenly
function distributeButtons() {
if(wrapperView.children) {
// Get the width of the wrapper view
var wrapperWidth = wrapperView.size.width;
var buttonWidths = 0;
var buttonSpacer;
var childrenLength = wrapperView.children.length;
// Get the button sizes
for(var i=0; i<childrenLength; i++) {
buttonWidths += wrapperView.children[i].size.width;
};
// Calculate the spaces between the buttons
buttonSpacer = (wrapperWidth - buttonWidths) / (childrenLength + 2);
// Set the buttons left value
for(var i=0; i<childrenLength; i++) {
wrapperView.children[i].left = buttonSpacer;
};
}
}
If you can put a toolbar, you can use the "flexspace" button, which will create a space necessary to fill the gap between other buttons. Here's the syntax from simple toolbar example in titanium docs:
var send = Titanium.UI.createButton({
title: 'Send',
style: Titanium.UI.iPhone.SystemButtonStyle.DONE,
});
var camera = Titanium.UI.createButton({
systemButton: Titanium.UI.iPhone.SystemButton.CAMERA,
});
var cancel = Titanium.UI.createButton({
systemButton: Titanium.UI.iPhone.SystemButton.CANCEL
});
flexSpace = Titanium.UI.createButton({
systemButton:Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
});
var toolbar = Titanium.UI.iOS.createToolbar({
items:[send, flexSpace, camera, flexSpace, cancel],
bottom:0,
borderTop:true,
borderBottom:false
});
win.add(toolbar)
try this
var yourView = Ti.UI.createView({ layout:"horizontal"});
var buttonsHolder = Ti.UI.createView({ width:"100%" });
// this view will hold the buttons
var button1 = Ti.UI.createButton({title:"button1 , left:0"}); // the left button
var button2 = Ti.UI.createButton({title:"button2"}); // the middle button
var button3 = Ti.UI.createButton({title:"button3",right:0}); // the right button
buttonsHolder(button1);
buttonsHolder(button2);
buttonsHolder(button3);
yourView.add(buttonsHolder);
Hieyy bro
If you are want achieve this using titanium alloy in xml. in that case you can use %.
Container ------------width 100%-----layout horizontal---------
first child--------left 10%------- width 20%
second child--------left 10%------- width 20%
third child--------left 10%------- width 20%-----right 10%
if you don't get your answer please let me know
Spartacus Thanks:)
If using Alloy, then I recommend using percentages to control width and position. Here's an example that centers three small images below a larger image, also centered:
<TableViewRow selectionStyle="Ti.UI.iPhone.TableViewCellSelectionStyle.NONE" backgroundColor="white" layout="vertical">
<ImageView id="detailsFeaturedImage" top="10"/>
<View height="60">
<View layout="horizontal">
<View left="25%" width="10%"><ImageView image="images/thumb-up-7#2x.png" onClick="thumb_up" /></View>
<View left="10%" width="10%"><ImageView image="images/thumb-down-7#2x.png" onClick="thumb_down"/></View>
<View left="10%" width="10%"><ImageView image="images/flag-7#2x.png" onClick="flag_for_review"/></View>
</View>
</View>
</TableViewRow>
I want to to send data from one window to another.
Example:
I have a text field and a button on first window. When click on window I need to send text field value to the second window?
I found a tutorial, but it's not in MVC.
I have created a new alloy controller (left click in your project and then new) and here is how i am passing parameters to the next view.
The new controller is called CallBack and the first controller is called index.
In CallBack.xml i have:
<Alloy>
<View class="container">
</View>
</Alloy>
In CallBack.tss i have:
".container": {
backgroundColor: "black"
}
In CallBack.js i have:
var args = arguments[0] || {};
//here you can do whatever you want to your parameter, i just show the value.
alert(args.textField);
And finally in index.js this is how i am passing the parameters of my textField:
//with a button i can open a new view in my current window
$.btnNext.addEventListener('click',function(e){
//tfInsert is the id of my textfield in index.xml file and with .value i can access to whatever it contains
//the "?" operator is like an if
var textField = $.tfInsert.value != "" ? textField = $.tfInsert.value : textField = "Hello";
var nextView = Alloy.createController('/CallBack', {
textField: textField
}).getView();
//this is how i add a new view to my current window
$.window.add(nextView);
});
Hope this helps.
In controller.js (from where we are passing Data)
function createController(win)
{
//title is the data to pass
var platform = Ti.Platform.osname;
var calledWindow = require('/ui/' + platform + '/addProductWindow').createCalledWindow(title);
calledWindow.open();
};
In calledWindowController.js
function createController(win){
//Do whatever control you want
};
In calledWindow.js
exports.createCalledWindow = function(title)
{
//Do whatever UI you want
Ti.include('/Controllers/calledWindowController.js');
var controller = createController(win);
return win;
};