How to refresh the Table View Data in Titanium Studio - ios

I've created an app using tabBar. I've created a separate search Window Containing a searchBar and a TableView to display the recent search items. Whenever the return event is fired a new window called searchresult.js opens up displaying the data searched. When I click on the back button it goes from searchresult.js-->searchpage.js, but the problem is the table for recent data gets updated in the database but it isn't showing on the table and I've to go to the main page and open the searchpage.js again to see the correct data... Pls help...Thanx in advance
I've used the following code: searchpage.js
//*** Search Field ***
var search = Titanium.UI.createSearchBar({
barColor:'#000',
showCancel:true,
height:43,
hintText:'Name of the part you want to search',
autocorrect:true,
top:0,
});
content.add(search);
//*** Table For Recent Search ***
var db = Titanium.Database.install('car.db','dbversion1');
var sql = db.execute ('SELECT * FROM search_history ORDER BY id DESC LIMIT 0, 10');
var data = [];
while (sql.isValidRow()){
var searchQuery = sql.fieldByName('search_query');
var selectedCategory = sql.fieldByName('selected_category');
var searchID = sql.fieldByName ('id');
data.push({title: searchQuery});
sql.next();
}
var searchTable = Titanium.UI.createTableView({
headerTitle:'RECENT SEARCH',
data: data,
});
Ti.API.info(searchTable.title);
content.add(searchTable);
//Search Action
search.addEventListener('blur', function(e) {
Titanium.API.info('search bar:blur received');
});
search.addEventListener('cancel', function(e) {
Titanium.API.info('search bar:cancel received');
search.blur();
});
search.addEventListener('return', function(e){
var insertSql = db.execute('INSERT INTO search_history (search_query, selected_category) VALUES ("' + search.value + '", 1)');
var win = Titanium.UI.createWindow({
backgroundColor:'#ffffff',
url:'searchresult.js',
title: 'Search Result',
searchValue: search.value
});
Ti.API.info(search.value);
search.blur();
Titanium.UI.currentTab.open(win, {animation:true});
});
// Back Button Action
bckButton.addEventListener('click', function(e){
if (Ti.Android){
win.close();
}else{
win.close({animated:true});
}
});
and searchresult.js
// *** Content ***
var content = Titanium.UI.createView({
backgroundColor:'#fff',
height:'100%',
width:'100%',
layout:'vertical'
});
wrapper.add(content);
var searchQuery = win.searchValue;
var db = Titanium.Database.install('car.db', 'dbversion1');
var sql = db.execute ("SELECT * FROM part_category WHERE part_name LIKE \'%"+ searchQuery +"%\'");
var data = [];
while(sql.isValidRow()){
var partName = sql.fieldByName ('part_name');
var partID = sql.fieldByName ('id');
data.push({title: partName, hasChild:true, id:partID, url:'partsubcategory.js'});
sql.next()
};
var resultTable = Titanium.UI.createTableView({
data : data,
});
content.add(resultTable);
// Back Button Action
bckButton.addEventListener('click', function(e){
if (Ti.Android){
win.close();
}else{
win.close({animated:true});
}
});

you should save the search results in a data structure and fire an event after the search is complete. Any other tables that you want to update should be listening for that event and update when it recieves the event.
I believe there is an example of this in the training documentation for tiBountyHunter
http://docs.appcelerator.com/titanium/latest/#!/guide/Event_Handling

Related

SAPUI5: MERGE instead of POST after DELETE

I'm testing a simple sample CRUD app. Everything works well...until I perform a DELETE (omodel.remove()) operation. If the next operation I do is an Insert (create entry, bind to view and submit changes) the app will perform MERGE (with the data of the deleted record) instead of POST and fail. Everything will work afterwards until I repeat this DELETE-INSERT sequence. If following the deletion, try to update an existing record, everything will work as well. Adding an omodel.refresh() at the beginning didn't work. Any ideas?
Starting with empty recordset, adding first record, model before submit changes
Record added, post performed
Ready to add 2nd record, all good in model, one existing and one new entry
2nd record added, another POST, all well
Ready to delete 1st record, situation right before the model.remove() operation, 2 recs, first one pending deletion
Record deleted, DELETE action triggered as expected
Last step, about to enter another record, see the existing and the pending new entry
BAMMM! Record NOT added, app instead of adding the new entry, performed a MERGE with the data of the deleted record!
Code for creating the new entry and passing it to the object page
onActionAdd: function() {
var oModel = this.getView().getModel();
var oParamModel = this.getView().getModel("Params");
oParamModel.setProperty("/ObjectMode", "Add");
oModel.refresh();
//var oNewObject = "{\"Curr\": \"GBP\"}";
var oNewObject = "{\"Pernr\": \"1023912\",\"Begda\":\"" + new Date('2021', '05', '01').toString()
+ "\",\"Endda\":\"" + new Date('2021', '06', '01').toString()
//+ "\",\"ActionDate\":\"" + new Date('2021', '07', '01').toString()
+ "\"}";
oNewObject = JSON.parse(oNewObject);
var oEntry = oModel.createEntry("/Industrial_ActionSet", {
properties: oNewObject
});
oParamModel.setProperty("/EntryId", oEntry.sPath.toString());
this.getRouter().navTo("object", {
objectId: oNewObject.Pernr,
dateFromId: oNewObject.Begda,
dateToId: oNewObject.Endda
});
}
Code for save (insert/update)
onActionSave: function() {
var oModel = this.getView().getModel();
var oParamModel = this.getView().getModel("Params");
var objectMode = oParamModel.getProperty("/ObjectMode");
var self = this;
// abort if the model has not been changed
if (!oModel.hasPendingChanges()) {
MessageBox.information(
this.getResourceBundle().getText("noChangesMessage"), {
id: "noChangesInfoMessageBox",
styleClass: self.getOwnerComponent().getContentDensityClass()
}
);
return;
}
if (objectMode === "Add") {
var sDateFrom = new Date(this.getView().byId("idDateFrom").getDateValue());
var sObjectPath = oParamModel.getProperty("/EntryId") + "/Begda";
oModel.setProperty(sObjectPath, sDateFrom);
var sDateTo = new Date(this.getView().byId("idDateTo").getDateValue());
sObjectPath = oParamModel.getProperty("/EntryId") + "/Endda";
oModel.setProperty(sObjectPath, sDateTo);
var sActionDate = new Date(this.getView().byId("idActionDate").getDateValue());
sObjectPath = oParamModel.getProperty("/EntryId") + "/ActionDate";
oModel.setProperty(sObjectPath, sActionDate);
var sMethod = "POST";
} else {
sMethod = "PUT";
}
oModel.submitChanges({
method: sMethod,
success: function(oData, sResponse) {
MessageToast.show("Record Updated");
self.onNavBack();
},
error: function(oError) {
jQuery.sap.log.error("Action Save oData Failure", oError);
}
});
},
Code for delete
onActionDelete: function() {
var oModel = this.getView().getModel();
var msgText = this.getModel("i18n").getResourceBundle().getText("confirmDelete");
var sPath = this.getView().getBindingContext().sPath;
var self = this;
// Opens the confirmation dialog
MessageBox.confirm(msgText, {
title: "Exit Confirmation",
initialFocus: sap.m.MessageBox.Action.CANCEL,
onClose: function(sButton) {
if (sButton === MessageBox.Action.OK) {
oModel.remove(sPath, {
method: "DELETE",
success: function(data) {
MessageToast.show("Record Deleted");
self.onNavBack();
},
error: function(e) {
jQuery.sap.log.error("Delete Action oData Failure", e);
}
});
} else if (sButton === MessageBox.Action.CANCEL) {
MessageToast.show("Deletion aborted");
return;
}
}
});
},
Thanks, cheers!
This is not the most elaborate way to solve this but problem is related with dates as keys. There are 3 date fields in the entity, 2 of them keys. As soon as I converted the entity date keys to string (still DATS on the backend) everything started working fine...

SAPUI5 oData.V2 How to invoke a function after everything in a batch request is done?

I have an issue while making an SAPUI5 odata V2 batch request :
var that = this;
var oServiceModel = that.getModel("oServiceModel");
odataMod = this.getModel("Service");
odataMod.setUseBatch(true);
var aData = oServiceModel.getData();
var stupidService = _.filter(aData, function (ae) {
return ae.Info === "-N/A";
});
var i = 0 ;
_.forEach(stupidService, function (sap) {
oGlobalBusyDialog.setText("Deleting service :" + sap.ObjectID);
oGlobalBusyDialog.setTitle("Deleting Service");
oGlobalBusyDialog.open();
that.removeService(sap).then(function () {
if (i === 615) {
oGlobalBusyDialog.close();
}
}).catch(function () {});
});
my Delete function is like this:
removeService: function (service) {
var that = this;
return new Promise(
function (resolve, reject) {
odataMod.remove('/ProjectTaskServiceCollection(\'' + service.ObjectID + '\')/', {
success: function (oData) {
resolve(oData);
},
error: function (oResult) {
that.handleError(oResult);
oGlobalBusyDialog.close();
reject(oResult);
}
});
});
What's happening ,is that if I'm trying to delete 500 entry, and if 200 entry cannot be deleted, the error message gets displayed 200 times
How to make it in a way to only display the error message once ?
Also, I want to turn off the batch request once everything is done odataMod.setUseBatch(false); how to do it ?
*EDIT: *
I've manage to do :
var aDeffGroup = odataMod.getDeferredGroups();
//add your deffered group
aDeffGroup.push("deletionGroup");
for (var s = 0; s < 5; s++) {
odataMod.remove('/ProjectTaskServiceCollection(\'' + stupidService[s].ObjectID + '\')/', {
//pass groupid to remove method.
groupId: "deletionGroup"
});
}
odataMod.submitChanges({
// your deffered group id
groupId: "deletionGroup",
success: function() {
//Get message model data from Core and it contains all errors
// Use this data to show in dialog or in a popover or set this to your local model see below code
var aErrorData = sap.ui.getCore().getMessageManager().getMessageModel();
console.log(aErrorData);
}
});
yet stills my console.log(aErrorData); still prints multiple error message
Instead of doing individual deletion odata calls. Add these all remove methods in a single group, then call odatamod.submitChanges() method.
Example:
//get all deffered groups
var aDeffGroup = odataMod.getDeferredGroups();
//add your deffered group
aDeffGroup.push("deletionGroup");
//set it back again to odatamodel
odataMod.setDeferredGroups(aDeffGroup);
odataMod.remove('/ProjectTaskServiceCollection(\'' + service.ObjectID + '\')/', {
//pass groupid to remove method.
groupId: "deletionGroup"});
odataMod.submitChanges({
// your deffered group id
groupId:"deletionGroup",
success: function() {
//Get message model data from Core and it contains all errors
// Use this data to show in dialog or in a popover or set this to your local model see below code
var aErrorData = sap.ui.getCore().getMessageManager().getMessageModel();
});

openlayers 3 featureKey exists in featureChangeKeys

I have an ol.interaction.Select acting on an ol.source.Vector which is within an ol.layer.Vector. I can select and unselect individual countries fine. I am using a dragbox to select multiple countries. If I select anywhere outside of the multiply selected countries, the currently selected get unselected. Excellent!
However, the problem is that if I select a currently selected country within the multiple, I get the AssertionError: Assertion failed: featureKey exists in featureChangeKeys
Here's my Vector layer:
_countrySelectSource = new ol.source.Vector({
url: 'vendor/openlayers/geojson/countries.json',
format: new ol.format.GeoJSON()
});
var countryLayer = new ol.layer.Vector({
title: 'Country Select',
visible: true,
type: 'interactive-layers',
source: _countrySelectSource
});
I add countryLayer to my map, _map.
I then create a _CountrySelect object that allows me to setActive(true|false) on the interactions related to my country selection.
_CountrySelect = {
init : function(){
this.select = new ol.interaction.Select();
_map.addInteraction(this.select);
this.dragbox = new ol.interaction.DragBox({
condition: ol.events.condition.platformModifierKeyOnly
});
_map.addInteraction(this.dragbox);
this.setEvents();
},
setEvents: function(){
var selectedFeatures = this.select.getFeatures();
var infoBox = document.getElementById('info');
var selfDragbox = this.dragbox;
selfDragbox.on('boxend', function() {
// features that intersect the box are added to the collection of
// selected features, and their names are displayed in the "info"
// div
var extent = selfDragbox.getGeometry().getExtent();
_countrySelectSource.forEachFeatureIntersectingExtent(extent, function(feature) {
selectedFeatures.push(feature);
_countryCodes.push(feature.getId());
});
infoBox.innerHTML = _countryCodes.join(', ');
});
// clear selection when drawing a new box and when clicking on the map
selfDragbox.on('boxstart', function() {
selectedFeatures.clear();
infoBox.innerHTML = ' ';
});
_map.on('singleclick', function(event) {
selectedFeatures.clear();
_countryCodes = [];
_map.forEachFeatureAtPixel(event.pixel,function(feature){
selectedFeatures.push(feature);
var id = feature.getId();
var index = _countryCodes.indexOf(id);
if ( index === -1 ) {
_countryCodes.push(feature.getId());
}
});
infoBox.innerHTML = _countryCodes.join(', ');
});
},
setActive: function(active){
this.select.setActive(active);
this.dragbox.setActive(active);
}
};
_CountrySelect.init();
I am not sure if this is an issue with OL3 or my code. Maybe there's an event I'm not handling? Maybe it's the ol.interaction.DragBox (no luck researching on the DragBox). Let me know what further information I can provide.

Invalid Property on Extended FIORI Application

We are implementing an extended My Quotations Fiori application. Basically we added a new field Sales Order to the UI. The field fetches data from the backend so we also extended our OData service. On the first view, we can successfully call the data. But whenever we navigate to the next view via clicking Edit button, we get this error
Property 'SalesOrder' is invalid. Choose "Refresh" to update pricing information.
Anyone has an idea on how to solve this?
Here is our custom code for S3 view controller. We used WEB IDE to create the extension btw. The second function is for the creation of the Sales Order whenever the quotation has no associated SO tied to it.
manageSalesOrderFields: function() {
alert("manageSalesOrderFields");
var salesOrderId = "";
// hide all fields
view.byId("salesOrderLabel").setVisible(false);
view.byId("salesOrderText").setVisible(false);
view.byId("triggerSalesOrderLabel").setVisible(false);
view.byId("triggerSalesOrderButton").setVisible(false);
$.getJSON("/sap/opu/odata/sap/zlord_my_quotation_srv/QuotationHeaderSet('" + quotationId + "')",
function(data) {
alert("enterHere");
salesOrderId = data.d.SalesOrder;
alert(salesOrderId);
if (salesOrderId !== "" ){
view.byId("salesOrderLabel").setVisible(true);
view.byId("salesOrderText").setVisible(true);
}else{
view.byId("triggerSalesOrderLabel").setVisible(true);
view.byId("triggerSalesOrderButton").setVisible(true);
view.byId("triggerSalesOrderButton").detachPress(sap.ui.controller("...").createSalesOrder);
view.byId("triggerSalesOrderButton").attachPress(sap.ui.controller("...").createSalesOrder);
}
});
},
createSalesOrder: function () {
var createSalesOrderDialog = new sap.m.Dialog("createSoDialog", {
title: "Create Sales Order",
icon: "sap-icon://sales-order",
content: [
new sap.ui.core.HTML({content:"<p style='margin:0;padding: 16px;'>Do want to create a sales order?</p>"})
],
buttons:[
new sap.m.Button({
text: "Yes",
press : function() {
var oModel = new sap.ui.model.odata.ODataModel('/sap/opu/odata/sap/zlord_my_quotation_srv/');
var oParameter = {
"QuotationID" : quotationId
};
oModel.callFunction('/CreateSalesOrder', 'GET', oParameter, 'null',
function (oData, oResponse) {
var responseMessage = JSON.stringify(oResponse.body);
var responseMessageStart = responseMessage.search('<d:Message>');
var responseMessageEnd = responseMessage.search('</d:Message>');
responseMessage = responseMessage.substring(responseMessageStart + 11, responseMessageEnd);
//show MessageToast
sap.m.MessageToast.show(responseMessage);
view.byId("triggerSalesOrderLabel").setVisible(false);
view.byId("triggerSalesOrderButton").setVisible(false);
console.log(responseMessage);
},
function (oError) {
sap.m.MessageToast.show('Error - see log');
console.log(oError);
}
);
createSalesOrderDialog.close();
createSalesOrderDialog.destroy();
}
}),
new sap.m.Button({
text: "No",
press : function() {
createSalesOrderDialog.close();
createSalesOrderDialog.destroy();
}
})
]
});
createSalesOrderDialog.open();
}
We didn't edit anything on the next view controller (CreateQuotations.view.controller.js) since it is not relevant for us to show the SO number on that view.
The error is because of this line:
salesOrderId = data.d.SalesOrder;
How to fix?
Step 1 : Check results first in network tab for the call:
/sap/opu/odata/sap/zlord_my_quotation_srv/QuotationHeaderSet('quotationIdId');
Sample:
Step 2: Check the results hierarchy . How?
console.log(data); //in success call
Step 3: Then restructure your statement to something like this
salesOrderId = data.d.results[0].SalesOrder;
Hope this helps!

JQuery Autocomplete Problem

I am using JQuery UI Autocomplete in my JSP. Whenever user keys character, i made the request to server and get the data as JSON and load with the pulgin.
It's working fine. But Whenever i typed the same character as previous term. It's not populating any values.
For eg., First i typed p, it lists the p starting elements. I have the button to reset the text content of autocompleter. After reset, if i am typing same character p, it doesn't show anything.
my code as follows,
var cache = {};
$("#Name").autocomplete({
source: function(req, add){
if (req.term in cache) {
add(cache[req.term]);
return;
}
$.getJSON("/store/StockManagement?action=getMedicinesStock",req, function(data) {
var medicines = [];
$.each(data, function(i, val){
medicines.push(val.name + "," + val.code);
});
cache[req.term] = medicines;
add(medicines);
});
},select: function(e, ui) {
var medicine = ui.item.value;
$('#Code').val(medicine.split(",")[1]);
setTimeout(function(){
var med = $('#Name').val();
$('#Name').val(med.split(",")[0]);
},500);
}
});
// Taken from jquery-ui-1.8.4.custom.min.js
if (a.term != a.element.val()) { // *** THE MATCH IS HERE
//console.log("a.term != a.element.val(): "+a.term+", "+a.element.val());
a.selectedItem = null;
a.search(null, c) // *** SEARCH IS TRIGGERED HERE
}
I just commented the condition. now it's works fine.

Resources