Setting busy indicator after button press - sapui5

I have a simple scenario, a button is pressed and the function onSearchExisting is executed. In the function I open a dialog which contains a table. The data for the table I fetch in the onSearchExisting function. Since the data fetching takes some time, I would like to set the button which triggers this function to busy.
The code looks like this in the function:
onSearchExisting : function() {
var oButton = this.getView().byId("searchButton");
oButton.setBusy(true);
oButton.setBusyIndicatorDelay(0);
var oView = this.getView();
var oDialog = oView.byId("dialog2ID");
if (!oDialog) {
oDialog = sap.ui.xmlfragment(oView.getId(),"xxx.view.fragment.SearchExisting",this);
oView.addDependent(oDialog);
}
var oDataModel = new
sap.ui.model.odata.ODataModel("/sap/opu/odata/xxxx", true);
this.getView().byId("tableSearchFrgId").getBinding("items");
oButton.setBusy(false);
oDialog.open();
},
The button is not set to busy, when I press it, what am I doing wrong?

Binding happens asynchronously, so oButton.setBusy(false); will get executed immediately after oButton.setBusy(true);.
I would suggest you use 'dataReceived' event of the binding and write the oButton.setBusy(false); inside the event handler of this event.
Read more here. https://help.sap.com/saphelp_nw751abap/helpdata/en/1a/010d3b92c34226a96f202ec27e9217/content.htm

By the time the setBusy(false) statement is executed, only few milliseconds have passed. You should put this statement in a success function of the oData call.
An oData call is async, so next line is immediatly executed even if the data is not retrieved yet.

Related

Why local Unique IDs inconsistent with IDs in HCP?

I have inspect the element in app that run local in HCP, the id is application-MaintainMasterData-display-component---addRoute--form, but when I deploy to cloud, the id changed to application-MaintainFleet-Display-component---addRoute--form
The app name changed, and the display in the upper class way, which makes my sap.ui.getCore().byId() failed in cloud. I was confussing why this happens.
I've read the ref, I was in a Event handler, I need the oEvent scope, so this.getView().byId() and this.createId() won't works for me.
Ref:
sap.ui.getCore().byId() returns no element
https://sapui5.netweaver.ondemand.com/sdk/#docs/guide/91f28be26f4d1014b6dd926db0e91070.html
=========UPDATE=========
I also tried sap.ui.getCore().byId("application-MaintainMasterData-display-component---addRoute").byId("form") , but the same issue , view id is application-MaintainFleet-Display-component---addRoute in cloud.
The IDs are dynamically generated. So you cannot rely on them. That's why you should not use sap.ui.getCore().byId(). Even the separators -- and --- may change in the future.
You should always use the byId() method of the nearest view or component to resolve local ids. You can chain the calls: component.byId("myView").byId("myControl")
In your eventhandler this should refer to the controller. For XMLViews this should be the case without further doing.
So i guess you are using JSViews? If you attach an eventhandler in code you can always supply a second argument to the attachWhatever() functions: The Object that becomes this in the event handler.
Controller.extend("myView", {
onInit:function(){
var button = this.byId("button1");
button.attachPress(this.onButtonPress, this); //The second parameter will become 'this' in the onButtonPress function
},
onButtonPress: function(oEvent){
console.log(this); //this is the controller
var buttonPressed = oEvent.getSource(); //get the control that triggered the event.
var otherControl = this.byId("table"); //access other controls by id
var view = this.getView(); //access the view
}
});
If you are using the settings-object-syntax you can supply an array for the events. It should contain the handler function and the object that should become this:
createContent:function(oController){
return new Button({
text: "Hello World",
press: [
function(oEvent){ console.log(this); }, //the event handler
oController //oController will be 'this' in the function above
]
});
If you are attaching to a non-UI5-event you can always use a closure to supply the view or controller to the handler function:
onInit:function(){
var that = this; //save controller reference in local variable
something.on("event", function(){ console.log(that); });
//you can use that local variable inside the eventhandler functions code.
}

Initializing input data

Where, and how do I clear out the input date on a view....
E.g. when the data is saved, and I access my page from the menu, the old data is still displayed in the input boxes.
I've tried the onInit() function but that only fires the first time into the view.
The navto call is in the BaseController which calls the defaultTimes page (view/controller).
onNavToDefaultTimes : function(oEvent) {
this.getRouter().navTo("defaultTimes");
}
My clear code was in the _onRouteMatched function of detaultTimes.....
_onRouteMatched : function(oEvent) {
var view = this.getView();
view.byId("shopInput").setValue("");
view.byId("effectiveDateFrom").setValue("");
view.byId("shop24Hrs").setSelected(false);
view.byId("shopClosed").setSelected(false);
},
The problem is though, _onRouteMatched is also callled from navBack of the page following default times. And I don't want to clear the fields in this case.
How do I implement the clear from the onNavToDefaultTimes function of the base Controller only?
Can you give an example.
Let's say the name of the view in which your input field is created is test.js, then whenever you are navigating to the view or navigating from the view, you can use invalidate view like below
sap.ui.getCore().byId("test").invalidate();
this makes the view to be rendered again when you are coming back to the view and onBeforeRendering() is triggered
You can choose one of the following options, and put one of them, after the code to save is executed:
Option 1:
var yourInput = this.getView().byId("yourInputID");
yourInput.setValue("");
Options 2 (Try someone):
var yourInput = this.getView().byId("yourInputID");
yourInput.unbindValue();
yourInput.unbindElement();
yourInput.unbindObject();
Or put the code in the following method, which is executed every time the view is displayed:
onAfterRendering: function(){
//Option choosed
}

Delay or make callback when binding data in UI5

i want to show message after binding data but message always shown before binding complete and show the result on the bound table. I want to delay or make callback when binding data is finished.
Thanks for help.
var oModel = new sap.ui.model.odata.ODataModel("sap/opu/odata/sap/*SRV/");
var oSummaryTable = sap.ui.getCore().byId("oSummaryTable");
oSummaryTable.setModel(oModel);
sap.ui.commons.MessageBox.alert("Succeed");
oModel.attachRequestCompleted(function() {
sap.ui.commons.MessageBox.alert("Succeed");
});

Ignore multiple button taps after first one on iPhone webapp using jQuery Mobile?

Assume button A in an HTML5 webapp built with jQuery Mobile.
If someone taps button A, we call foo(). Foo() should get called once even if the user double taps button A.
We tried using event.preventDefault(), but that didn't stop the second tap from invoking foo(). event.stopImmediatePropagation() might work, but it also stops other methods further up the stack and may not lead to clean code maintenance.
Other suggestions? Maintaining a tracking variable seems like an awfully ugly solution and is undesirable.
You can set a flag and check if it's OK to run the foo() function or unbind the event for the time you don't want the user to be able to use it and then re-bind the event handler after a delay (just a couple options).
Here's what I would do. I would use a timeout to exclude the subsequent events:
$(document).delegate('#my-page-id', 'pageinit', function () {
//setup a flag to determine if it's OK to run the event handler
var okFlag = true;
//bind event handler to the element in question for the `click` event
$('#my-button-id').bind('click', function () {
//check to see if the flag is set to `true`, do nothing if it's not
if (okFlag) {
//set the flag to `false` so the event handler will be disabled until the timeout resolves
okFlag = false;
//set a timeout to set the flag back to `true` which enables the event handler once again
//you can change the delay for the timeout to whatever you may need, note that units are in milliseconds
setTimeout(function () {
okFlag = true;
}, 300);
//and now, finally, run your original event handler
foo();
}
});
});
I've created a sample here http://jsfiddle.net/kiliman/kH924/
If you're using <a data-role="button"> type buttons, there is no 'disabled' status, but you can add the appropriate class to give it the disabled look.
In your event handler, check to see if the button has the ui-disabled class, and if so, you can return right away. If it doesn't, add the ui-disabled class, then call foo()
If you want to re-enable the button, simply remove the class.
$(function() {
$('#page').bind('pageinit', function(e, data) {
// initialize page
$('#dofoo').click(function() {
var $btn = $(this),
isDisabled = $btn.hasClass('ui-disabled');
if (isDisabled) {
e.preventDefault();
return;
}
$btn.addClass('ui-disabled');
foo();
});
});
function foo() {
alert('I did foo');
}
});

How to identify the ID or value of when the submit button is clicked

I am having trouble identifying the particular value or ID of a submit button after it has been clicked and submitted using AJAX.
If I place the following code as a global function, it properly alerts the value of the button clicked:
$(":submit").live('click', function() {
alert($(this).val());
})
However, when I attempt to define the variable, I am unable to use that variable from within the success callback function:
$(":submit").live('click', function() {
var whichButton = $(this).val();
})
...
$("#applicant-form").validate({
function(form) {
$(form).ajaxSubmit({
...
success: alert(whichButton);
I have also tried placing the code in the submitHandler, but that doesn't work either.
In a somewhat related post, a user had suggested I place the following code:
$("#accordion .edit").click(function(){
window.lastButtonClicked = this;
});
...
submitHandler: function(){
var index_origin = $(window.lastButtonClicked).attr("name");
}
But I was not able to get that to get the value of the button clicked (it said that the value was undefined).
Any suggestions?
UPDATE: It might help if I provide more information about why I need to know which button is pressed. I have two kinds of submit buttons for each form in a multi-part form. I would like to do different things based on which button was clicked.
$(":submit").live('click', function() {
var whichButton = $(this).val();
})
The scope of whichbutton is inside of this anonymous function; you can't access it from elsewhere. A quick fix might be to declare whichbutton as a global variable but there's probably very few cases where you should do that. More context as to what it is you're trying to do would help, right now it just looks like you're trying to alert the button text on success after an ajax form submit.