sapui5 sap.m.popover won't open my control - javascript

I have a button:
var oButton = new sap.m.Button({
text: "Press me",
press: function (oEvent) {
if (! this._oPopover) {
this._oPopover = sap.ui.xmlfragment("sap.my.library.Popover", this);
this._oPopover.setModel(true);
}
var oButton = oEvent.getSource();
var oMyControl= this._oPopover.getAggregation('content')[0];
oMyControl.setPlaceholder("Hello World");
jQuery.sap.delayedCall(0, this, function () {
this._oPopover.openBy(oButton);
});
}
})
And i have my xml Fragment:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:d="sap.my.library">
<Popover>
<d:myControl value=""/>
<!--<Input></Input>-->
</Popover>
</core:FragmentDefinition>
Now, when I click the button, nothing happens, only if I click it many times, my control appears.
I can say that for every 10 quick buttons clicks, my control appears maybe once.
Any suggestions?
Thanks!

this._oPopover is defined within an anonymous function declared within the button declaration.
IT CANNOT refer to a view field as you probably expect it to.
My suggestion :
var onButtonPress = function (oEvent) {
if (! this._oPopover) {
this._oPopover = sap.ui.xmlfragment("sap.my.library.Popover", this);
this._oPopover.setModel(true);
}
var oButton = oEvent.getSource();
var oMyControl= this._oPopover.getAggregation('content')[0];
oMyControl.setPlaceholder("Hello World");
jQuery.sap.delayedCall(0, this, function () {
this._oPopover.openBy(oButton);
});
}
var oButton = new sap.m.Button({
text: "Press me",
press: this.onButtonPressed.bind(this)
});
[code not tested!]

Could it be that 'this' is not referring to what you expect because your object is created within an anonymous function? See this explanation (ahem)
I believe the preferred pattern is to have the button press call a function in the main view where 'this' refers to the view scope.
I have a working example as follows: in then main view I have a button...
<Button
press="showDialogue"
/>
and the code of the view controller...
showDialogue: function(){
if(!this._oConfirmDialog){
this._oConfirmDialog = sap.ui.xmlfragment("sapui5.muSample.view.ConfirmDialog", this);
this.getView().addDependent(this._oConfirmDialog);
}
this._oConfirmDialog.open();
},
Note the use of view.addDependent() which lets the dialogue fragment access the view model AND destroys the dialogue instance in line the main view lifecycle events (according to the docs).
Or...you could create a local variable to capture the 'this' you actually want to refer to...
var contextThis = this;
just before your line starting
var oButton = ...
then change references to this inside the anon function to contextThis if you can't change the pattern.

Related

How to inherit Odoo's POS buttons

I'm trying to add some functions in the POS buttons, specifically the button that shows up like "Validate". To test if the guide in this link https://odoo-development.readthedocs.io/en/latest/dev/pos/gui.html works, I'm just adding a console.log like the following:
odoo.define('my_module.js_file', function (require) {
"use strict";
var screens = require('point_of_sale.screens');
screens.PaymentScreenWidget.include({
init: function(parent, options) {
this._super(parent, options);
//My console log message
console.log('Hello world!')
this.pos.on('updateDebtHistory', function(partner_ids){
this.update_debt_history(partner_ids);
}, this);
},
});
But the message only shows up once when the POS ends loading the data and not when I push the button. What am I doing wrong here?
To add your code to the Validate button you will need to modify the payment screen widget via the include method (You already did that).
If you inspect the button from the browser you will find that it has a class next which is used to bind an event handler to the click JavaScript event.
Example:
var screens = require('point_of_sale.screens');
var PaymentScreenWidget = screens.PaymentScreenWidget;
PaymentScreenWidget.include({
validate_order: function(force_validation) {
console.log('Hello world!');
this._super(force_validation);
},
});

Javascript (Dojo): Is event-listener removed when object is destroyed

I create a dialog in which there are some buttons with events. When I destroy the dialog recursive programmatical or by pressing the X are there deleted all the created event-listener (hide, cancel, click1, click2)?
Because I call this part (here I posted only a simplified version of my code) very often (for different dialogs) and it seems that my code could have some memory leaks I want to eliminate them. So please tell me, is it necassary/make sense to remove the event-listener all by myself like eventHide.remove(); ?
Additional: I tried to use the on (like the eventHide) for the click- and cancel-events but it didn't work.
var myDialog = new Dialog({
content: 'Testdialog'
});
myDialog.show();
var btn1 = new dijit.form.Button({ label: "Ok" });
var btn2 = new dijit.form.Button({ label: "Help" });
myDialog.containerNode.appendChild(btn1.domNode);
myDialog.containerNode.appendChild(btn2.domNode);
var eventHide = on.once(myDialog, "hide", function(e){
console.log('hide');
myDialog.destroyRecursive();
});
dojo.connect(btn1, "onClick", function(){
console.log('click ok');
myDialog.destroyRecursive();
});
dojo.connect(btn2, "onClick", function(){
console.log('click help');
myDialog.destroyRecursive();
});
dojo.connect(myDialog, "onCancel", function(){
console.log('cancel');
});
You could use this.own defined in dijit/Destroyable, which is a base of dijit/_WidgetBase and thus most widgets (make sure your custom widget inherit from hit.).
dijit/Destroyable is used to track handles of an instance, and then destroy them when the instance is destroyed.
More infos:
http://dojotoolkit.org/reference-guide/1.10/dijit/Destroyable.html
http://dojotoolkit.org/reference-guide/1.8/dojo/Evented.html

Same RadioButton-Setting Function from Both Startup / Change in jQuery

I have a single shared jQuery function that checks a RadioButton selection: if 1 is selected, it hides a span, otherwise it shows it.
This shared function is called both on startup and on Change, because on startup, it needs to do the same thing. The startup works, but the onChange reference does NOT work:
JS_OBJ = {
toggleTier : function() {
if ($('input[name="tier"]:checked').val() == 'Y_YES')
{
$('#tierSpan').hide();
}
else
{
$('#tierSpan').show();
}
},
// this is called from document.onReady - it comes here, OK
onReady : function() {
// on startup, toggle Tier - works OK
this.toggleTier();
// Also link the radio button Change to this shared function
$('input[name="tier"]:radio').change(function () {
alert('About to enter toggle...');
// NEVER COMES HERE - Object doesn't support this property or method
this.toggleTier();
});
}
};
the this is changing value as it is passing thru the different zones. when it is first instantiated, it has a good value, but the radiobutton:change has a different this
I was able to change it get it to work:
$('input[name="tier"]:radio').change(function () {
alert('About to enter toggle...');
self; //closure
toggleTier();
});
see this: What underlies this JavaScript idiom: var self = this?
Inside the change event, this does not refer to the current JS_OBJ, it refers to the current event target in stead. You want to explicitly save your reference to this, so you can use it inside the event.
Example:
onReady : function() {
var me = this;
me.toggleTier();
// Also link the radio button Change to this shared function
$('input[name="tier"]:radio').change(function () {
me.toggleTier();
});
}

How do I access a variable from a different view?

How do I access a variable from a different view?
I want to access selectedColor in another view:
'onClickColor': function(e) {
var view = this,
selectedColor = $(e.currentTarget).data('color'), //$(this).data('color');
style = $('<style>.highlight { color: ' + selectedColor +'; margin-left: 4px;}</style>');
$('.initial').css('color', selectedColor);
$('.highlight').css('color', selectedColor);
$('html > head').append(style);
//view.canvasColorPick(e);
},
And then in another view, I want to pass the variable selectedColor using ajax on a form submission.
'formCollect' : function (e) {
var view = this;
var fname = $('#your_name').val();
var email = $('#email').val();
var state = $('#state').val();
var color = selectedColor;
var url = 'services/users/add?name='+fname+'&email='+email+'&state='+state+'&color='+color+'';
$.get(url);
},
It should be the best way – to subscribe one view to events of another one. Since you did not provide the scope your views was instantiated I assume both of them are in the global scope. If you don't understand what scope mean please read this:
What is the scope of variables in JavaScript?
So assume your first view instantiated like this: firstView = new FirstView();. The second one is secondView = new SecondView();.
When the color changed in firstView trigger an event: this.trigger( "Color changed", {newColor: "black"} );. Please make sure that both views was instantiated before this event triggered.
Now you need to subscribe secondView on the event of firstView: secondView.listenTo( firstView, "Color changed", secondView.handleColorChanged );
Here handleColorChanged is the event handler which will get event params as arguments.
Now alltogeather:
var FirstView = Backbone.view.extend({
/** your casual code here */
'onClickColor': function(e) {
/** your code here */
this.trigger( "Color changed", { newColor: "black" });
}
});
var SecondView = Backbone.view.extend({
/** your casual code here */
'handleColorChanged': function( eventData ) {
console.log( eventData );
}
});
var firstView = new FirstView(),
secnodView = new SecondView();
secondView.listenTo( firstView, "Color changed", secondView.handleColorChanged );
This is not the only one way to solve your task. But this is the way to separate views from each other. No one view knows about another one what is mostly needed in big applications, makes easy debugging process and so on.

Trigger an event in the popup from a parent

I have two windows , the second is a popup , and I want to trigger an event from the parent (the first one where I have a link to this popup).
here's a javascript code for the trigger (in the parent window's javascript code):
winPop=window.open(opts.url,opts.nom,"width="+opts.width+",height="+opts.height+",top="+opts.top+",left="+opts.left);
winPop.onload=function(){
$(winPop.document).trigger('connected', {
jid: "jid",
password: '123'
});
}
This javascript code launchs the popup and tries to trigger an event bound in popup (ready) function:
$(document).ready(function () {
$(document).bind('connected', function () {
alert("Hello , I'm here");
});
The problem is that using the previous javascript code .. the bound event is not triggered as predicted.
Thanks in advance
I had done this earlier with something like this:
var realWindowOpen = window.open;
window.open = wrappedWindowOpen;
function wrappedWindowOpen(url, name, specs, replace) {
window.open = realWindowOpen;
var windowHandle = window.open(url, name, specs, replace);
if (windowHandle)
console.log("New Popup Window created: ", {name:name});
else
console.error("New Window Failed. " + {name:name});
if (popupFnCreationNotify) {
popupFnCreationNotify(windowHandle);
popupFnCreationNotify = null;
}
window.open = wrappedWindowOpen;
}
// Calling example
var popupFnCreationNotify = function() {
console.log("I got called back");
};
window.open("my url");
Please note:
realWindowOpen always points to window.open.
I wrap the actual window.open with wrappedWindowOpen as you can see in the code.
Before calling window.open, the caller sets the popupFnCreationNotify to any callback function they wish.

Categories

Resources