I need to show a ext lib Dialog after the user select a combobox (I use a Select2 of BootStrap for XPages).
The alert code function work well, but the XSP.openDialog not .
I've found a old stackoverflow question about this but I don't understand how can I solve my problem. Any ideas?
Tnx a lot
$(document).ready(
function() {
x$("#{id:comboBox1}").select2().on("change", function(e) {
XSP.allowSubmit();
XSP.partialRefreshPost("#{id:divView}",{
onStart: function () {
// do something when the partial update is finished
//alert("start...") -- this WORK
XSP.openDialog("#{id:dialog1}"); //this doesn't work
},
onComplete: function () {
// do something when the partial update is finished
//alert("stop...") -- THIS WORK
XSP.closeDialog("#{id:dialog1}"); //this doesn't work
}
});
} )
}
);
I've found a solution with XSP.allowSubmit();, magic Sven Hasselbach!:
$(document).ready(
function() {
x$("#{id:comboBox1}").select2().on("change", function(e) {
XSP.partialRefreshPost("#{id:divView}",{
onStart: function () {
// do something when the partial update is finished
//alert("start...") -- this WORK
XSP.allowSubmit();
XSP.openDialog("#{id:dialog1}");
},
onComplete: function () {
// do something when the partial update is finished
//alert("stop...") -- THIS WORK
XSP.allowSubmit();
XSP.closeDialog("#{id:dialog1}");
}
});
} )
}
);
Related
I am trying to get the selected element to the sidebar pane in my chrome extension.
It's working fine if the page has no frames when the element is in the frame, it's not working.
As per the document I have to pass the frameURL, but how do I get the frame or Iframe URL?
Thank you.
Note: This issue is duplicate that was opened in 3 years ago, but still no solution there, so re-opening it again.
In devtools.js
chrome.devtools.panels.elements.createSidebarPane(name, (panel) => {
// listen for the elements changes
function updatePanel() {
chrome.devtools.inspectedWindow.eval("parseDOM($0)", {
frameURL: // how to pass dynamic
useContentScriptContext: true
}, (result, exceptipon) => {
if (result) {
console.log(result)
}
if (exceptipon) {
console.log(exceptipon)
}
});
}
chrome.devtools.panels.elements.onSelectionChanged.addListener(updatePanel);
});
I ran into this as well. I ended up needing to add a content_script on each page/iframe and a background page to help pass messages between devtools and content scripts.
The key bit is that in the devtools page, we should ask the content_scripts to send back what their current url is. For every content script that was registered, we can then call chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true, frameURL: msg.iframe } );
Or in full:
chrome.devtools.panels.elements.createSidebarPane( "example", function( sidebar ) {
const port = chrome.extension.connect({ name: "example-name" });
// announce to content scripts that they should message back with their frame urls
port.postMessage( 'SIDEBAR_INIT' );
port.onMessage.addListener(function ( msg) {
if ( msg.iframe ) {
// register with the correct frame url
chrome.devtools.panels.elements.onSelectionChanged.addListener(
() => {
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true, frameURL: msg.iframe } );
}
);
} else {
// otherwise assume other messages from content scripts should update the sidebar
sidebar.setObject( msg );
}
} );
}
);
Then in the content_script, we should only process the event if we notice that the last selected element ($0) is different, since each frame on the page will also handle this.
let lastElement;
function setSelectedElement( element ) {
// if the selected element is the same, let handlers in other iframe contexts handle it instead.
if ( element !== lastElement ) {
lastElement = element;
// Pass back the object we'd like to set on the sidebar
chrome.extension.sendMessage( nextSidebarObject( element ) );
}
}
There's a bit of setup, including manifest changes, so see this PR for a full example:
https://github.com/gwwar/z-context/pull/21
You can found url of the frame this way:
document.querySelectorAll('iframe')[0].src
Assuming there is at lease one iframe.
Please note, you cannot use useContentScriptContext: true, as it will make the script execute as a context page (per documentation) and it will be in a separate sandboxed environment.
I had a slightly different problem, but it might be helpful for your case too, I was dynamically inserting an iframe to a page, and then tried to eval a script in it. Here the code that worked:
let win = chrome.devtools.inspectedWindow
let code = `
(function () {
let doc = window.document
let insertFrm = doc.createElement('IFRAME')
insertFrm.src = 'about:runner'
body.appendChild(insertFrm)
})()`
win.eval(code, function (result, error) {
if (error) {
console.log('Eror in insertFrame(), result:', result)
console.error(error)
} else {
let code = `
(function () {
let doc = window.document
let sc = doc.createElement('script')
sc.src = '${chrome.runtime.getURL('views/index.js')}'
doc.head.appendChild(sc)
})()`
win.eval(code, { frameURL: 'about:bela-runner' }, function (result, error) {
if (error) {
console.log('Eror in insertFrame(), result:', result)
console.error(error)
}
})
}
})
Hello I have a problem with Select2 component because this code that capture onChange event:
$(document).ready(
function() {
x$("#{id:comboBox1}").select2().on("change", function(e) {
XSP.partialRefreshPost("#{id:divView}",{
onStart: function () {
// do something when the partial update is finished
alert("start...")
},
onComplete: function () {
// do something when the partial update is finished
alert("stop...")
}
});
} )
}
);
Generate in Google Chrome this error that doesn't resolve x$() function (If you reload the page work)
In Internet Explorer work well..I don't know how solve.
Uncaught TypeError: undefined is not a function home.xsp:129x$ home.xsp:129j jquery-1.11.0.min.js:2k.fireWith jquery-1.11.0.min.js:2n.extend.ready jquery-1.11.0.min.js:2K jquery-1.11.0.min.js:2
Have someone any suggest?
Tnx you
Try using XSP.addOnLoad() instead of $(document).ready() in order for your function to run when the document has been fully loaded by XPages.
I'm trying to load and render additional views async and append them to the ItemView.
Simplified code - why is $el not defined in the require() block in render() - what am I missing here? Am I not using RequireJS properly, or Marionette, or just my inexperience with javascript?
What is the recommended way of doing this? It needs to be dynamic as additional section views could be available at runtime that I don't know about yet as registered by plugins.
define(['require','marionette', 'App', 'swig', 'backbone.wreqr','text!./settings.html'],
function (require,Marionette, App,Swig, Wreqr, settingsHtml )
{
var sectionViews = ['./settingscontent/GeneralView'];
var SettingsView = Marionette.ItemView.extend(
{
template: Swig.compile(settingsHtml),
commands: new Wreqr.Commands(),
initialize: function ()
{
this.commands.addHandler('save', function (options, callback)
{
callback();
});
Marionette.ItemView.prototype.initialize.apply(this, arguments);
},
render: function()
{
Marionette.ItemView.prototype.render.call(this);
var $el = this.$el;
var self = this;
require(sectionViews, function (View)
{
$el.find('div.tab-content').append(new View(self.model).render().$el);
// $el is not defined
// self != outer this - $el is an empty div
});
return this;
}
}
return SettingsView;
})
Why are you trying to overload itemview.render?
Why not use the built in onrender event
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.itemview.md#render--onrender-event
from that documentation :
Backbone.Marionette.ItemView.extend({
onRender: function(){
// manipulate the `el` here. it's already
// been rendered, and is full of the view's
// HTML, ready to go.
}
});
seems easier and more typical of marionette usage
You need to bind this inside the function to the SettingsView object. Something like:
render: function()
{
Marionette.ItemView.prototype.render.call(this);
var $el = this.$el;
var self = this;
require(sectionViews, _.bind(function (View)
{
...
}, this));
return this;
}
The local variables will not be visible inside the bound function. You can use this and this.$el safely however.
I am trying to send a value to server from anchor link and I call following code from a function which is called from the anchor link. Although I am able to trigger partial refresh,I get an error...any pointers please.....
var refreshId=dojo.query('[id$="testPanel"]')[0];
alert(refreshId.innerHTML)
alert(refreshId.id)
var mySubmitValue='whatYouWantToSendHere';
XSP.partialRefreshGet(refreshId, {
params: {
'$$xspsubmitvalue': mySubmitValue
},
onStart: function () {
alert('starting');
},
onComplete: function () {
alert('Complete');
},
onError:'myErrHandler( arguments[0], arguments[1] )'
});
You are sending the object to the server. Use the id of the element instead:
XSP.partialRefreshGet(refreshId.id, {
Got some problems with the chrome.tabs.onSelectionChanged.addListener. Everything works good, till the whole window is closed. Then this listener is triggered...for whatsoever reason. For me it's kinda buggy, but anyway:
On this listener, I'm working with the chrome.tabs.get function. And this function is throwing an error in the moment of windows close:
Error during tabs.get: No tab with id: 70.
This makes sense. The tab does no longer exist in this moment. Anyone did already had a way to work around this? One possible reason would be to remove the listener on window close. But sadly, the removeListener doesnt work (if anyone knows how to remove, I'm grateful).
Best
EDIT 1.1: Modified function from serg's approach (thx for that on this way):
First i tried to only catch the tabs of the actual window with: chrome.windows.getCurrent. But this function doesn't return the windows.tabs array. So I first read out the current windows.id and only loop through the tabs of this window.
function ensureTabExists(tabId, callback) {
chrome.windows.getCurrent(function(windows) {
var exists = false;
windowsId=windows.id;
chrome.windows.getAll({populate: true}, function(windows){
loop:
for(var w=0;w<windows.length;++w) {
if (windows[w].id == windowsId) {
for(var t=0;t<windows[w].tabs.length;++t){
if(windows[w].tabs[t].id == tabId) {
exists = true;
break loop;
}
}
}
}
if(exists && callback) {
callback();
}
});
});
}
You can loop through all tabs in all windows and check if it still exists:
function ensureTabExists(tabId, callback) {
chrome.windows.getAll({populate: true}, function(windows){
var exists = false;
loop:
for(w=0;w<windows.length;w++) {
for(t=0;t<windows[w].tabs.length;t++){
if(windows[w].tabs[t].id == tabId) {
exists = true;
break loop;
}
}
}
if(exists && callback) {
callback();
}
});
}
//usage
chrome.tabs.onSelectionChanged.addListener(function(tabId, selectInfo) {
ensureTabExists(tabId, function(){
//this code will run only if tab exists
});
});
Use the chrome.window.onRemoved API to track when windows have closed. That way you can handle the window closing case more gracefully.