Get values from selected CustomTile SAPUI5 - tiles

I have a product catalog made with CustomTile Control. When I press one tile, I want to go to a details page. For that I need to know some of the values that are on the pressed tile, which I'm not able to.
Here is the code for the tile and the binding:
var sServiceUrl = "/sap/opu/odata/sap/ztestefardas_srv/"; //URL do serviço oDATA
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl);
sap.ui.getCore().setModel(oModel);
OData.read("/sap/opu/odata/sap/ztestefardas_srv/catalogo",
function (response){
for(var key in response.results) {
var value = response.results[key];
var oImg =new sap.ui.commons.Image({
width :"160px",
height :"160px"
}).setSrc(value["img"]);
oImg.addStyleClass("img_cat");
var oMatxt =new sap.ui.commons.TextView({
text: value["matxt"],
width: "200px"
}).addStyleClass("matxt");
var oAtr =new sap.ui.commons.TextView({
text: "Atribuídos: "+value["n_atr"],
width: "200px"
}).addStyleClass("second_line");
if (value["n_dis"] > 0){
var oDis =new sap.ui.commons.TextView({
text: "Disponíveis: "+value["n_dis"],
width: "200px"
}).addStyleClass("second_line_disp");
} else {
var oDis =new sap.ui.commons.TextView({
text: "Disponíveis: "+value["n_dis"],
width: "200px"
}).addStyleClass("second_line");
}
var oPtxt =new sap.ui.commons.TextView({
text: "Próximo levantamento:",
width: "200px"
}).addStyleClass("third_line");
var oPlev =new sap.ui.commons.TextView({
text: value["p_lev"],
width: "200px"
}).addStyleClass("third_line");
var oLayout = new sap.ui.commons.layout.VerticalLayout({
content: [oImg,oMatxt,oAtr,oDis,oPtxt,oPlev]
});
var oTile = new sap.m.CustomTile({
content:oLayout,
press: function(oEvento){
//missing code to get values from selected tile
oNavContainer.to(Page2);
}
}).addStyleClass('sapMTile');
oContainer.addTile(oTile);
}});
I've tried with the table attach row selection change way, but it's not working too.
Can you please help?
Thank you.

Add the following code in your function (response) method:
var valueModel = new sap.ui.model.json.JSONModel({
"Value": "##your value here##",
});
oLayout.setModel(valueModel);
Add the following code in the press function handler:
var oLayout = oEvento.getSource().getContent();
var value = oLayout .getModel().getProperty("/Value");
Then you can get values from the CustomTile by using data binding to get the value your want.
Hope it helps.

I found a way to make this work.
within the FOR that I used to read the data from the odata:
oTile.data("matnr", value["Matnr"]);
oTile.data("matxt", value["Itmfdx"]);
oTile.data("n_dis", value["n_dis"]);
oTile.data("n_atr", value["n_atr"]);
oTile.data("endda", value["Endda"]);
oTile.data("itmfd", value["Itmfd"]);
these value["xpto"] are the keys from the response results (OData.read("/sap/opu/odata/sap/zmm_fardamentos_srv/CatalogoSet?sap-ui-language=PT",
function (response){
for(var key in response.results) {
var value = response.results[key];)
Then, I created a function for the attachPress event of oTile with these:
oTile.attachPress( function(){
sap.ui.getCore().getControl("selimg").setSrc(this.data("img"));
sap.ui.getCore().getControl("bigpic").setSrc(this.data("img"));
sap.ui.getCore().getControl("nome_material").setText(this.data("matxt"));
sap.ui.getCore().getControl("itmfd_var").setText(this.data("itmfd"));
sap.ui.getCore().getControl("atr_det").setText(this.data("n_atr"));
sap.ui.getCore().getControl("disp_det").setText(this.data("n_dis"));
sap.ui.getCore().getControl("lev_data").setText(this.data("endda"));
the names within getControl are the id of the variables that will hold the values.
Maybe this is not the fanciest way, but it sure works :)

Related

There was an unexpected failure with this assessment, invalid type provided

I'm attempting to run the following code which is pretty much copied from the OoTheBox UI Action called "View User's Response".
function showRiskAssessment(){
var ra = new GlideRecord('asmt_assessment_instance');
ra.addQuery('task_id', '=', current.sys_id);
ra.orderByDesc('taken_on');
ra.setLimit(1);
ra.query();
// var id = g_form.getUniqueValue();
var id = ra.sys_id;
//var type = g_form.getValue('metric_type');
var type = '468aeff2db9357008aeba9f7059619ca';
var url = 'assessment_take2.do?sysparm_assessable_sysid=' + id + '&sysparm_assessable_type=' + type + '&sysparm_reader_view=true';
var d = new GlideOverlay({
title: "User's Response",
iframe: url,
width:'80%',
height: '100%',
onAfterLoad: function() {
var iframe = d.getIFrameElement();
setTimeout(function(){
iframe.height = parseInt(iframe.height)+1;
},0);
}
});
d.render();
}
If I hardcode it like this it works. All I'm trying to do is on the change record I want to look up the most recent Assessment Instance for that particular change and display in the overlay. Obviously I can't hardcode the id however it seems the query isn't recognizing that info at all anyways.
function showRiskAssessment(){
// var ra = new GlideRecord('asmt_assessment_instance');
// ra.addQuery('task_id', '=', current.sys_id);
// ra.orderByDesc('taken_on');
// ra.setLimit(1);
// ra.query();
// var id = g_form.getUniqueValue();
var id = '5c516eeddb87d090ebce60ab1396198a';
//var type = g_form.getValue('metric_type');
var type = '468aeff2db9357008aeba9f7059619ca';
var url = 'assessment_take2.do?sysparm_assessable_sysid=' + id + '&sysparm_assessable_type=' + type + '&sysparm_reader_view=true';
var d = new GlideOverlay({
title: "User's Response",
iframe: url,
width:'80%',
height: '100%',
onAfterLoad: function() {
var iframe = d.getIFrameElement();
setTimeout(function(){
iframe.height = parseInt(iframe.height)+1;
},0);
}
});
d.render();
}
You're trying to use current.sys_id in a client side script. It is recommended to use g_form for client side scripts. You're also trying a GlideRecord on a client script, which is also not recommended.
To fix, replace:
ra.addQuery('task_id', '=', current.sys_id);
with:
var sysId = g_form.getUniqueValue();
ra.addQuery('task_id', '=', sysId);
Also, for the difference between g_form and current have a look here.

Replicate event pinch from a div to openlayer map

Good afternoon,
I have a div over the ol3 map with one list of marker. When the user clic on a marker, the center's map is updated with the coordinate of this marker.
I tried that the user have the possibility to zoom on the map when he "pinch" on the layer on top.
I successed to intercept the event on the "layerOnTop" and replicate it to the map layer. With console.log, I saw that the job is correctly done but there is any reaction on the map.
You can see the code : http://jsfiddle.net/2ek4j3a4/
var center = ol.proj.transform([4.90756, 45.5172], 'EPSG:4326', 'EPSG:3857');
var map = new ol.Map({
layers: [new ol.layer.Tile({source: new ol.source.OSM()})],
target: 'map',
controls: ol.control.defaults({attributionOptions: ({ collapsible: false})}),
view: new ol.View({center: center,zoom: 12})
});
$('#layerOnTop').on("touchmove", function(event) {
var scale = event.originalEvent.touches;
if (scale.length==2) {
event.preventDefault();
var bottomEvent = new $.Event("touchmove");
bottomEvent.pageX = event.pageX;
bottomEvent.pageY = event.pageY;
$("#map").trigger(bottomEvent);
}
});
$('#map').on("touchmove", function(event) {console.log('ok')})
I did my test with an Android phone.
Somebody have an idea, please ?
I finally found :) There was 2 errors in my code :
1) target should be the canvas element in div#map and not #map himself
2) I fixed the touch identifier by Date.now() and add +1 for the second, it was certainely too big
See below the code if one day somebody search ...
$('#layerOnTop').on("touchstart touchmove touchend", function(event) {
view = document.getElementById('map').ownerDocument.defaultView;
if (event.originalEvent.touches.length==2) {
var target = document.getElementById('map').getElementsByTagName('canvas')[0];
var pageX1 = event.originalEvent.touches[0].pageX;
var pageY1 = event.originalEvent.touches[0].pageY;
var pageX2 = event.originalEvent.touches[1].pageX;
var pageY2 = event.originalEvent.touches[1].pageY;
var touch1 = document.createTouch(view, target, 0, pageX1, pageY1, 0, 0);
var touch2 = document.createTouch(view, target, 1, pageX2, pageY2, 0, 0);
var touchList = document.createTouchList(touch1, touch2);
var touchEvent = new TouchEvent(event.type, {cancelable: true, bubbles: true, touches: touchList, targetTouches: touchList, changedTouches: touchList})
target.dispatchEvent(touchEvent);
}
});
http://jsfiddle.net/2ek4j3a4/7/

Remote update cell content in kendo grid

Here I have a code to update a cell contet when pressing a button.
It works fine, but it doesn't set the flag, that indicates, that the cell has been changed.
It should look like this with the litle red triangle:
The code:
<a id="button" href="#">Click me</a>
<div id="grid"></div>
<script>
var dataSource, grid;
$(document).ready(function () {
dataSource = new kendo.data.DataSource({
data: [
{ category: "Beverages", name: "Chai", price: 18},
{ category: "Seafood", name: "Konbu", price: 6}
],
})
grid = $("#grid").kendoGrid({
dataSource: dataSource,
editable: true,
}).data("kendoGrid");
$('#button').click(function (e) {
var data = grid.dataItem("tr:eq(1)");
data.set('category', 'Merchandice');
});
});
</script>
Update:
Here is the update based on #tstancin: Kendo example.
Thank you for the answer - I had thought of it to.
I am wondering if it's possible to do the update in a more clean way with some binding through som MVVM perhaps?
Kind regards from Kenneth
If that's all you want then you should expand your button click code with the following:
$('#button').click(function (e) {
var data = grid.dataItem("tr:eq(1)");
data.set('category', 'Merchandice');
$("#grid tr:eq(1) td:eq(1)").addClass("k-dirty-cell");
$("#grid tr:eq(1) td:eq(0)").prepend("<span class='k-dirty'></span>");
});
But if you, for instance, manually change the value of name column from Chai to something else, and then click the click me button, the dirty marker in the name column will disappear.
You should use flags for every cell and set them before data.set(). Then, in the grid's dataBound event you should inspect every cell's value and assign the dirty marker if it's needed. For manual changes you should handle the save event and set flags there.
I wrote a script that makes it posible to use a call like this:
SetCellData(id, columnName, value);
So with an id, a columnName and a value, I can update a value in a grid and the flag will be set on the cell.
function SetCellData(id, columnName, value) {
var dataItem = grid.dataSource.get(id);
dataItem.set(columnName, value);
var columnIndex = GetColumnIndex(columnName);
if (columnIndex > -1) {
var cell = $('tr[data-uid*="' + dataItem.uid + '"] td:eq(' + columnIndex + ')')
if (!cell.hasClass("k-dirty-cell")){
cell.prepend("<span class='k-dirty'></span>");
cell.addClass("k-dirty-cell");
}
}
}
function GetColumnIndex(columnName) {
var columns = grid.columns;
for (var i = 0; i < columns.length; i++)
if (columns[i].field == columnName)
return i;
return -1;
};
I have the code here : example

Put info from google maps InfoWindow into HTML textbox

I have a map that has lots of markers pulled from a database. Each one displays an InfoWindow with a placename and the lat and lng of the location. I need to have the placename affiliated with a marker added to and HTML textbox on click. I can't seem to find any tutorials on this. Maybe someone can point me in the right direction. I am trying to learn this on my own so apologies if it is sloppily designed. Thanks for your help in advance.
function load() {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
center: new google.maps.LatLng(41.640078, -102.669433),
zoom: 3,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
downloadUrl("mymap.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + point;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
It needs to go into a simple textbox like this:
<input type = "text" id = "address_box" value = ""/>
To display that data in your HTML text box, change your bindInfoWindow function, add code in there to put the data in the text box:
function bindInfoWindow(marker, map, infoWindow, html, name) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
document.getElementById("address_box").value = name;
});
}
And add name in to the call to it:
bindInfoWindow(marker, map, infoWindow, html, name);
Do you mean, when the infoWindow opens, you want to display some information into the textbox?
If so, this code might help you(I hope).
var infoWindow = new google.maps.InfoWindow;
var address_box = document.getElementById("address_box");
google.maps.event.addListener(infoWindow, "domready", function() {
address_box.value = infoWindow.get("Content");
});

Sencha Touch refresh list after data in store has been changed

i want to do the following:
I have a store which gets JSON data from the server. The JSON looks like this:
{"id":"1","name":"Name1","address":"exampleaddress1","lat":"48.366268","lng":"10.892320","distance":"0"},{...}]
My model and store:
Ext.regModel('Filiale', {
fields: ['id', 'name', 'address', 'distance', 'lat', 'lng'],
});
var ListStore = new Ext.data.Store({
model: 'Filiale',
id: 'ListStore',
autoLoad: false,
fields:['name', 'address', 'distance'],
proxy: {
type: 'ajax',
url : 'http://example.com/getSomeJson.php',
reader: {
type: 'json'
}
},
listeners: {
load: function(){
ListStore.each(function(store){
var newData = getDistance(store.data); // this function calculates the distance from currentLocation to the received address
console.log(newData); // i see a object in the console, with the correct calculated distance
console.log(newData.distance); // this shows the old distance which is set to '0' in the databse
//at this point i want to update the received records with the new distance, but the list always shows the old distance
});
}
}
});
I don't understand, why the two console.logs show different values for the distance. Can anyone explain that to me ?
My List:
var listPanel = new Ext.List({
title: 'ListStore',
store: ListStore,
id: 'addresslist',
itemTpl: '<div class="contact">{name}, {address}, {distance}</div>',
rendered: false,
listeners: {
beforerender: function(){
ListStore.load();
}
}
});
my function to calculate the distance:
var getDistance = function(dataset){
navigator.geolocation.getCurrentPosition(function(position){
var start = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
//add current position marker to map
var marker = new google.maps.Marker({
map: mapPanel.map,
position: start
});
var end = new google.maps.LatLng(dataset.lat, dataset.lng);
var service = new google.maps.DirectionsService();
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
service.route(request, function(result, status){
if (status == google.maps.DirectionsStatus.OK) {
dataset.distance = result.routes[0].legs[0].distance.value / 1000;
}
});
});
return dataset;
};
And as i said, the distance is correctly calculated and the objects gets returned... but i'm unable to update the records in the store or the list...
I don't understand, why the two console.logs show different values for the distance. Can anyone explain that to me ?
Are You using Chrome? Chrome console sometimes has problems with up-to-date console data
And as i said, the distance is correctly calculated and the objects gets returned... but i'm unable to update the records in the store or the list...
Records in the store in Your script are always up-to-date - in JS obejcts are passed by reference, so You don't even have to return newData - store object will be updated automatically
Just after adding some values to store type:
listpanel.refresh()
to load current store to list

Resources