How to use controller content into view.js in SAPUI5 - sapui5

I am trying to pass input value from one view to another like this
Firstview
oFooter.addContent(new sap.m.Button("b1", {
text : "Execute",
icon : "sap-icon://display",
styled : false,
press : function() {
var In_obj = sap.ui.getCore().byId('inobj').getValue();
var Ins_obj = sap.ui.getCore().byId('insobj').getValue();
var In_exid = sap.ui.getCore().byId('exid').getValue();
var In_dp1 = sap.ui.getCore().byId('DP1').getValue();
var In_dp2 = sap.ui.getCore().byId('DP2').getValue();
var In_usr = sap.ui.getCore().byId('User').getValue();
var In_tcd = sap.ui.getCore().byId('tcode').getValue();
var In_prg = sap.ui.getCore().byId('prog').getValue();
app.to("page2", {
Input_obj : In_obj,
Input_sobj : Ins_obj,
Input_exid : In_exid,
Input_dp1 : In_dp1,
Input_dp2 : In_dp2,
Input_usr : In_usr,
Input_tcd : In_tcd,
Input_prg : In_prg,
});
}
}));
Secondview.controller.js
onInit : function() {
alert("second page init" );
view.addEventDelegate({
onBeforeShow: function(evt) {
var idToRetrieve = evt.data.Input_obj;
Input_obj = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_sobj;
Input_sobj = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_exid;
Input_exid = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_dp1;
Input_dp1 = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_dp2;
Input_dp2 = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_usr;
Input_usr = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_tcd;
Input_tcd = idToRetrieve.getValue();
var idToRetrieve = evt.data.Input_prg;
Input_prg = idToRetrieve.getValue();
alert( Input_obj );
console.log( Input_obj);
}});
},
Now, I don't know how to use variables (Input_obj, Input_sobj, ...) in Secondview.js(view). Can I have some guidance about this ?

As far as i can see in your code idToRetrieve should have the value(text) of the the element with ID inobj.
You are passing the dataobj while calling the app.to method and therefore in the onbeforeshow method the data should be available.
There is a concept of routes in SAPUI5 specifically which can also be used here
Routing
But with the current approach as well i can see the data should be available in the onbeforeshow method
For Example
app.to("detailPage", {id:"42"}); // trigger navigation and hand over a data object
// this data object could also be a binding context when dealing with data binding
...
// and where the detail page is implemented:
myDetailPage.addEventDelegate({
onBeforeShow: function(evt) {
var idToRetrieve = evt.data.id;
// ...now retrieve the data element with the given ID and update the page UI
}
});

Related

How to generate leaflet control from database

I wish to generate a custom dropdown filter, based on categories from a database.
How is this achieved?
In my example, this is (poorly) implemented with some hard coding and duplication.
var serviceOverlays = [
{name:"Cardiology", value:"cardiology"},
{name:"Opthamology", value:"opthamology"}
];
var oSelect = L.control({position : 'topright'});
oSelect.onAdd = function (map) {
var overlayParent = document.getElementById('new-parent'); // overlays div
var node = L.DomUtil.create('select', 'leaflet-control');
node.innerHTML = '<option value="cardiologist">Cardioligist</option><option value="opthamology">Opthamology</option>';
overlayParent.appendChild(node);
L.DomEvent.disableClickPropagation(node);
L.DomEvent.on(node,'change',function(e){
var select = e.target;
for(var name in serviceOverlays){
serviceOverlays[name].removeFrom(map);
}
serviceOverlays[select.value].addTo(map);
});
Fiddle
I created a Control for you:
L.Control.Select = L.Control.extend({
options: {
position : 'topright'
},
initialize(layers,options) {
L.setOptions(this,options);
this.layers = layers;
},
onAdd(map) {
this.overlayParent = L.DomUtil.create('div', 'leaflet-control select-control');
this.node = L.DomUtil.create('select', 'leaflet-control',this.overlayParent);
L.DomEvent.disableClickPropagation(this.node);
this.updateSelectOptions();
L.DomEvent.on(this.node,'change',(e)=>{
var select = e.target;
for(var value in this.layers){
this.layers[value].layer.removeFrom(map);
}
this.layers[select.value].layer.addTo(map);
});
return this.overlayParent;
},
updateSelectOptions(){
var options = "";
if(this.layers){
for(var value in this.layers){
var layer = this.layers[value];
options += '<option value="'+value+'">'+layer.name+'</option>';
}
}
this.node.innerHTML = options;
},
changeLayerData(layers){
this.layers = layers;
this.updateSelectOptions();
}
});
var oSelect = new L.Control.Select(serviceOverlays,{position : 'topright'}).addTo(map);
The data structure have to be:
var serviceOverlays = {
"cardiology": {name:"Cardiology", layer: cities},
"opthamology": {name:"Opthamology", layer: badCities}
};
Demo: https://jsfiddle.net/falkedesign/1rLntbo5/
You can also change the data dynamicl< with oSelect.changeLayerData(serviceOverlays2)

How to add an img to L.control.layers?

Is there a way to add an icon/img before the input checkbox inside the layer control?
And is there a way to add a value(or id) prop to the checkbox?
For now I can add an icon with this, but that is not exacltly what I want. Thanks.
L.control.layers({
null
}, {
'<img src="/img/fish.png">Some text':new L.layerGroup(),
}).addTo(map);
This will add an img after the checkbox. Maybe somehow override the _addItem method in the Control.Layers.js, but I don't know how.
Update: Is there a way to add a value prop to the checkbox on this stage?
var layers = L.control.layers({}, {
'name':new L.layerGroup(), // how to add val?
}).addTo(map);
So I can add a value and name(span, label) to the checkbox to get the
<div>
<input type="checkbox" value="some val" class="leaflet-control-layers-selector"><span>name</span>
</div>
Might want to do this with custom JavaScript. I don't believe there is any built-in way to accomplish this. Try something like this:
Save the control layers to a variable:
var layers = L.control.layers({}, {'name' : new L.layerGroup()}).addTo(map);
Get the _overlaysList property (unless you're altering a base map):
var list = layers._overlaysList;
Iterate the input tags:
var inputs = list.getElementsByTagName('input');
Find the one you want to alter, and prepend an image to it.
Well, here is my solution, if someone is interested
//---------------- OVERRIDING THE LAYERS -------------------
L.Control.IconLayers = L.Control.Layers.extend({
initialize: function (baseLayers, overlays, options) {
L.Control.Layers.prototype.initialize.call(this, baseLayers, overlays, options);
},
_addItem: function (obj) {
//console.log("Layer Control:",obj)
var label = document.createElement('label'),
input, icon = false,
checked = this._map.hasLayer(obj.layer);
if (obj.overlay) {
input = document.createElement('input');
input.type = 'checkbox';
input.className = 'leaflet-control-layers-selector';
input.defaultChecked = checked;
input.value = obj.name; // add
console.log(obj)
if ('getIcon' in obj.layer) {
icon = obj.layer.getIcon();
}
} else {
input = this._createRadioElement('leaflet-base-layers', checked);
}
var layer_name = obj.name
if (obj.layer.hasOwnProperty('_options')){
layer_name = obj.layer._options.name
input.id = obj.layer._options.id
}
input.layerId = L.stamp(obj.layer);
L.DomEvent.on(input, 'click', this._onInputClick, this);
var name = document.createElement('span');
name.innerHTML = ' ' + layer_name;
label.appendChild(input);
if (icon) {
var i = document.createElement('span');
i.innerHTML = icon;
label.appendChild(i);
}
label.appendChild(name);
var container = obj.overlay ? this._overlaysList : this._baseLayersList;
container.appendChild(label);
return label;
}
});
L.control.iconLayers = function(baseLayers, overlays, options) {
return new L.Control.IconLayers(baseLayers, overlays, options);
}
L.customLayerGroup = L.LayerGroup.extend({
initialize: function (layers) {
console.log("LAYERS:",layers)
L.LayerGroup.prototype.initialize.call(this, layers);
this._options = layers;
},
});
//---------------- OVERRIDING THE LAYERS -------------------
var layers = L.control.iconLayers({
'Mapbox Streets': L.mapbox.tileLayer('mapbox.streets').addTo(map),
'Mapbox Light': L.mapbox.tileLayer('mapbox.light')
}, {
'1':new L.layerGroup(),
'2':new L.layerGroup(),
'3':new L.customLayerGroup({name:"Boats",id:"3", value:"3"}),
}).addTo(map);

Custome Formatter within a Controller - SAPUI5

I'm trying to format gender field (in SAP table field: CHAR1 to 0(F) and 1(M) to fit the selectedIndex property of RadioButtonGroup.
This is my view : (DetailDialog.fragment.xml )
<RadioButtonGroup width="100%" columns="2" selectedIndex="{path: 'Gendr', formatter:'.formatter' }" id="__group1">
The above XML Fragment is called by the main view controller:
ItemPress: function(oEvent) {
var detailDialog = this.getView().byId("DetailDialog");
var that = this;
var view = this.getView();
var path = oEvent.getParameter("listItem").getBindingContext().getPath();
var oDummyController = {
formatter: function(gendr) {
switch (gendr) {
case "M":
return 0;
case "F":
return 1;
}
},
closeDialog: function() {
detailDialog.close();
}
};
if (!detailDialog) {
detailDialog = sap.ui.xmlfragment(view.getId(), "Demo1.view.DetailDialog", oDummyController);
}
var jSonModel = new sap.ui.model.json.JSONModel();
function fnSuccess(oData, oResponse) {
jSonModel.setData(oData);
}
var oModel = view.getModel();
oModel.read(path, {
success: fnSuccess
})
//Set data for dialog
this.getView().byId("__formDetail").setModel(jSonModel);
detailDialog.open();
}
My problem is that the formatter is not working at all.
Any suggestion?
Option one: (not sure if it works for fragments too)
Change formatter:'.formatter' to formatter:'Demo1.view.DetailDialog.formatter'.
Option two: Format the data since anyway you are binding data from controller. (And surely will work.)
function fnSuccess(oData, oResponse) {
oData.GendrValue = oData.Gendr == "M"?1:0;
jSonModel.setData(oData);
}
and also change the binding: selectedIndex="{path: 'GendrValue'}"

get values from XML file in my Titanium Project

I am having the following .xml which i used in my android project.now,am trying to create the same in iPhone using titanium.Can some one tell me how to get this values from the xml file and show them in a table view.? if i give MainCategories the 3 values in it should appear in the table view.Also can some one tell me is there any other better option to achieve this?or can we use plist??thank you.
<string-array name="MainCategories">
<item>Acceleration</item>
<item>Angle</item>
<item>Area</item>
</string-array>
<string-array name="Acceleration_array">
<item>meter/sq sec</item>
<item>km/sq sec</item>
<item>mile/sq sec</item>
<item>yard/sq sec</item>
</string-array>
<string-array name="Angle_array">
<item>degree</item>
<item>radian</item>
<item>grad</item>
<item>gon</item>
</string-array>
Try This.
var result = [];
var fileName = 'arrays1.xml'; //save xml file
var tableView = Ti.UI.createTableView({ data : result, width : '100%', height : '100%' });
function readXML(fileName)
{
var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, fileName);
var xmltext = file.read().text;
var doc = Ti.XML.parseString(xmltext);
var parentNodeLength = doc.documentElement.getElementsByTagName('string-array').length;
for (var i = 0; i < parentNodeLength; i++) {
var attrValue = doc.documentElement.getElementsByTagName('string-array').item(i).attributes.getNamedItem('name').nodeValue;
if (attrValue === 'Angle_array') {
var parentNode = doc.documentElement.getElementsByTagName('string-array').item(i);
var subNodeLength = parentNode.getElementsByTagName('item').length;
for (var j = 0; j < subNodeLength; j++) {
var title = parentNode.getElementsByTagName('item').item(j).text;
var row = Ti.UI.createTableViewRow({
height : 110
});
var label = Ti.UI.createLabel({
height : Ti.UI.SIZE,
width : Ti.UI.SIZE,
text : title
});
row.add(label);
result.push(row);
}
}
}
}
readXML(fileName);
tableView.setData(result);
win1.add(tableView);
win1.open();
i am not familiar with titanium but maybe this should help you out:
var result = this.responseText;
var xml = Ti.XML.parseString(result);
var params = xml.documentElement.getElementsByTagName("member");
var name = xml.documentElement.getElementsByTagName("name");
var value = xml.documentElement.getElementsByTagName("string");
var data = [];
for (var i=0;i<params.item.length;i++) {
Ti.API.log('Param '+i+': Name: '+n.item(i).text);
Ti.API.log('Param '+i+': Value: '+v.item(i).text);
// Add to array
data.push({"name":n.item(i).text,"value":v.item(i).text});
}
copied from this link
for displaying it in uitableview, save your values in nsarray and display your array in tableview. here is a tutorial for UITableView.

window opens twice or more on single click in dynamic tableview - appcelerator

So i have a dynamic tableview.
when i click on one of the rows i got a new screen. It works, but on the top left the back button shows the title of the current window, so i have to click min 2 times on, to get back to the tableviews tab. Any idea why?
var win = Titanium.UI.currentWindow;
Titanium.include('strip_tags.js');
var tab = Titanium.UI.currentTab;
var tableView = Titanium.UI.createTableView({top:43,
separatorStyle: 'none',
backgroundColor:'transparent'});
win.add(tableView);
Ti.UI.currentWindow.addEventListener('focus', function() {
loadTweets();
});
function loadTweets()
{
var rowData = [];
var loader = Titanium.Network.createHTTPClient();
loader.open("GET","url", true);
loader.onload = function()
{
var tweets =JSON.parse(this.responseText);
for (var i = 0; i < tweets.length; i++)
{
var id = tweets[i].id;
var title = tweets[i].name; // The tweet message
var special=tweets[i].special;
if(special>0) {
var price=tweets[i].special;
var color2='#4C6B22';
} else {
var color2='#fff';
var price=tweets[i].price;
}
var thumb = tweets[i].thumb; // The profile image
title=title.replace('®', '');
title=title.replace('™', '');
var row = Titanium.UI.createTableViewRow({height:'auto',top:20 , backgroundImage:Ti.Filesystem.resourcesDirectory + '/images/row_bg.png', borderWidth:0, separatorStyle: 'none'});
var post_view = Titanium.UI.createView({
height:'auto',
layout:'vertical',
top:0,
right:5,
bottom:0,
left:5,
borderWidth:0,
height:49
});
var av_thumb = Titanium.UI.createImageView({
url:thumb, // the image for the image view
top:0,
left:0,
height:48,
width:48
});
post_view.add(av_thumb);
var av_title = Titanium.UI.createLabel({
text:title,
left:54,
width:210,
top:-30,
bottom:2,
height:16,
textAlign:'left',
color:'#fff',
font:{fontFamily:'Trebuchet MS',fontSize:14,fontWeight:'bold'}
});
post_view.add(av_title);
var av_desc = Titanium.UI.createLabel({
text:special,
left:270,
top:-20,
color:'#fff',
bottom:2,
height:'auto',
width:236,
textAlign:'left',
font:{fontSize:14}
});
post_view.add(av_desc);
row.add(post_view);
row.className = "item"+i;
row.thisTitle = title;
row.thisId = id;
rowData[i] = row;
}
var winCount = Titanium.UI.createLabel({
text:tweets.length+' blalba',
height:43,
top:0,
left:0,
width:320,
height:50,
textAlign:'center',
color:'#fff',
backgroundImage:Ti.Filesystem.resourcesDirectory + '/images/row_bg.png',
font:{fontFamily:'Trebuchet MS',fontSize:14,fontWeight:'bold'}
});
win.add(winCount);
tableView.setData(rowData);
tableView.addEventListener('click', function(e){
var w2 = Titanium.UI.createWindow({
title:e.rowData.thisTitle,
url:'cikk.js',
barColor:'#000',
backgroundImage:Ti.Filesystem.resourcesDirectory + '/images/winbg.png'
});
w2.stringProp1 = strip_tags(e.rowData.thisId);
tab.open(w2, {
animated:true
});
}
)};
loader.send();
}
my hunch is the that the eventListener focus is getting called twice and that is causing the tweets to get loaded twice which then cause the tableView eventListener to get loaded twice.
if you are going to use focus to add the eventListener, then I would suggest using blur to remove the eventListener.