state variable resetting itself for no re - reactjs

I have a React Component that includes a list of items. When the user double clicks an item, a new browser window opens that allows the user to edit the item. The opener (the component that opens the new browser window) needs to keep track of all the browser windows that it has opened and when they close. This is needed so that if the user double clicks an item that has already been opened, I can give focus to the existing window for that item rather than opening a new one. I'm trying to keep track of the open windows in a state variable. Here is the relevant code:-
const handleSalesItemDoubleClick = (salesItem) => {
var windowRef = window.open(process.env.REACT_APP_APP_SERVER + '/' + site.SiteCode + '/SalesItem/' + salesItem,
salesItem,
'width=1000,left=0,top=0,height=600,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,directories=no,status=no'
)
windowRef.onload = function () {
windowRef.onbeforeunload = () => { handleWindowClose(salesItem) }
}
var tabs = [...openSalesItems, {salesItem: salesItem, window: windowRef}];
setOpenSalesItems(tabs);
}
const handleWindowClose = (salesItemId) => {
var tabs = openSalesItems.filter(function (tab) { return tab.salesItem !== salesItemId })
setOpenSalesItems(tabs);
}
setOpenSalesItems is the function that sets the state variable "openSalesItems".
When I open multiple new windows then close them in reverse order, the openSalesItems contains the correct array at all times but if I open multiple windows then close the window that I opened first, the openSalesItems array becomes empty.

Related

Command handling in Qooxdoo multi window application

I want to create a Qooxdoo application that consists of a Desktop with multiple Windows. The Desktop (and not each Window) also has a (common) ToolBar.
Now I want to have a command to "save" the document of the active window. This command can be triggered by the keyboard shortcut "Ctrl+S" as well as a button on the toolbar.
To handle the "Ctrl+S" to reach the currently active window the qx.ui.command.GroupManager (as described by https://qooxdoo.org/documentation/v7.5/#/desktop/gui/interaction?id=working-with-commands and https://qooxdoo.org/qxl.demobrowser/#ui~CommandGroupManager.html) is supposed to be the best solution. And I could easily implement that in my code.
But now I'm struggling to make the toolbar save button also call the save command of the currently active window as I don't know how to bind it correctly to the GroupManager.
An example code to get started in the playground https://qooxdoo.org/qxl.playground/:
// NOTE: run this script only once. Before running it again you need to reload
// the page as it seems that the commands are accumulation and not reset.
// I guess that this is a bug in the Playground
const root = this.getRoot();
qx.Class.define('test.Application',
{
extend : qx.application.Standalone,
members: {
main: function() {
const layout = new qx.ui.layout.VBox(5);
const container = new qx.ui.container.Composite(layout);
root.add(container, {edge: 0});
const windowManager = new qx.ui.window.Manager();
const desktop = new qx.ui.window.Desktop(windowManager);
this._manager = new qx.ui.command.GroupManager();
const menuBar = new qx.ui.menubar.MenuBar();
let menu = new qx.ui.menu.Menu();
///////////////////////////
// TODO: Call _doSave() of the active window!
let saveMenuButton = new qx.ui.menu.Button('Save','#MaterialIcons/save/16');
///////////////////////////
menu.add(saveMenuButton);
var fileMenu = new qx.ui.menubar.Button('File', null, menu);
menuBar.add(fileMenu);
const toolBar = new qx.ui.toolbar.ToolBar();
///////////////////////////
// TODO: Call _doSave() of the active window!
let saveToolBarButton = new qx.ui.toolbar.Button('Save','#MaterialIcons/save/16');
///////////////////////////
toolBar.add(saveToolBarButton);
container.add(menuBar,{flex:0});
container.add(toolBar,{flex:0});
container.add(desktop,{flex:1});
this._foo1 = new test.Window('foo1', this);
desktop.add(this._foo1);
this._foo1.open();
this._foo1.moveTo(100,20);
this._foo2 = new test.Window('foo2', this);
desktop.add(this._foo2);
this._foo2.open();
this._foo2.moveTo(200,100);
this._foo3 = new test.Window('foo3', this);
desktop.add(this._foo3);
this._foo3.open();
this._foo3.moveTo(300,180);
},
getGroupManager() {
return this._manager;
}
}
});
qx.Class.define('test.Window', {
extend: qx.ui.window.Window,
construct(windowName, controller) {
this.base(arguments, windowName);
this._name = windowName;
let commandGroup = new qx.ui.command.Group();
const cmd = new qx.ui.command.Command("Ctrl+S");
cmd.addListener('execute', this._doSave, this);
commandGroup.add('save', cmd);
controller.getGroupManager().add(commandGroup);
this.addListener('changeActive', () => {
if (this.isActive()) {
controller.getGroupManager().setActive(commandGroup);
}
}, this);
},
members: {
_doSave() {
alert("save " + this._name);
}
}
});
a = new test.Application();
How should the saveMenuButton.setCommand() and saveToolBarButton.setCommand() should look like to always call the command of the active window?
You can control a current active window via Desktop class:
let saveToolBarButton = new qx.ui.toolbar.Button('Save');
saveToolBarButton.addListener("click", function(){
desktop.getActiveWindow()._doSave();
}, this);
Would be great for your solution imo is to create a separate command and add this command to buttons:
const saveActiveWindowCommand = new qx.ui.command.Command();
saveActiveWindowCommand.addListener("execute", function(){
desktop.getActiveWindow()._doSave();
}, this);
let saveMenuButton = new qx.ui.menu.Button('Save');
saveMenuButton.setCommand(saveActiveWindowCommand);
let saveToolBarButton = new qx.ui.toolbar.Button('Save');
saveToolBarButton.setCommand(saveActiveWindowCommand);
EDIT:
You could set commands dynamically for "Main Panel" menu buttons. Because there is only one instance of command pressing "Ctrl+S" will trigger only one command but maybe you would like that main bar save buttons have extra logic.
You have in application class next method which will be called from window class when changeActive event happens.
setSaveCommand(command){
this.saveMenuButton.setCommand(command);
this.saveToolBarButton.setCommand(command);
},
and in your Window class:
if (this.isActive()) {
controller.setSaveCommand(cmd);
controller.getGroupManager().setActive(commandGroup);
}

React - when document open in new tab change the name of this new tab

I need to open document in a new tab in the browser and change the name of this tab
I wrote this code:
const blobUrlDocs = URL.createObjectURL(blob);
var newWindow = window.open(blobUrlDocs, "_blank");
newWindow.document.title = data.D_NAME;
return newWindow;
but the namews tab has not changed
I try wrote it in onload function :
newWindow.onload = function () {
newWindow.document.title = data.D_NAME;
return newWindow;
};
But the name of the tab only changed when the document was loaded.
What should I do so that the name of the document remains even after loading the document?

Share variable between two windows. Angularjs

From my angularjs application I open a new window:
$window.open($state.href('catalog-detalleTicketMapa', {
id: $localStorage.idRamdom
}), 'window', 'height=700,width=700');
And when I close that new window I want the parent window to know about that event, and I do the following
// controller auxiliary window
vm.onExit = function () {
$rootScope.$broadcast('ventanaCerrada');
};
$window.onbeforeunload = vm.onExit;
// controller main windows
$scope.$on('ventanaCerrada', function () {
$rootScope.ventanaAbierta = false;
});
If it enters the event $rootScope.$broadcast but not to the event scope.$on.
I have also tested with localStorage, but it is only updated in the auxiliary window, but the main one does not.
How can I share a variable between two open windows at the same time in my browser?
When you open a new window with $window.open, it won't share the scope with the calling window, so it's impossible (afaik) to broadcast anything between them with angular. But the calling window can access global variables in the opened window, so I'm using something like an observer to watch that variable.
I have the following code in a WindowService to open the new window (we only open a single window; if you need more, you need to adjust the code):
angular.module('myproject')
.service('WindowService', ['$window', '$interval', '$timeout',
function ($window, $interval, $timeout) {
var self = this;
this.myOpenWindow = null;
// opens a window and starts the wait-function
this.openWindow = function (url, callbackFn) {
// open the window
self.myOpenWindow = $window.open(url);
// Puts focus on the new window
if (window.focus) {
self.myOpenWindow.focus();
}
// check for response in opened window
self.waitForResponse(callbackFn);
};
this.waitStarted = false;
this.waitForResponse = function (callbackFn) {
if (!self.waitStarted && self.myOpenWindow) {
self.waitStarted = true;
var intervalPeriod = 1000; // check once every second
var waitHandler;
waitHandler = $interval(function (index) {
if (self.myOpenWindow.closed) {
// window was closed, commence cleaning operation
$interval.cancel(waitHandler);
waitHandler = $timeout(function () {
// re-initialize waitStarted so it can be used again
self.waitStarted = false;
// call callback-Function when the window is closed
if (callbackFn) {
callbackFn();
}
}, intervalPeriod);
} else {
// window is still open, check if the observed variable is set
if (self.myOpenWindow && self.myOpenWindow.response_message) {
var message = self.myOpenWindow.response_message;
// do what you want with the message
// ...
// afterwards close the window (or whatever)
if (self.myOpenWindow) {
self.myOpenWindow.close();
}
}
}
}, intervalPeriod);
}
};
}
]);
In the opened window you need to set that global variable somewhere, e.g. like this:
window['response_message'] = { 'result': 'Done' };
Normally you can't share storage data between two windows. If you really need that changes in data in one window reflect in another window then use socket or firebase to get real-time data.

How to focus on second tab and work on it using selenium webdriver

I have opened the link now i am clicking on login link on that page,
By clicking on login button its opening in a new tab automatically. I have to fill the form in that tab. For that i tried following code:
Actions act = new Actions(Initialsetupfirefox.driver);
new Actions(Initialsetupfirefox.driver) .keyDown(Keys.CONTROL).click(Initialsetupfirefox.driver.findElement(By.xpath("//a[contains(text(),'LOGIN')]")))
.keyUp(Keys.CONTROL)
.perform();
Thread.sleep(3000);
new Actions(Initialsetupfirefox.driver).sendKeys(Initialsetupfirefox.driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(Initialsetupfirefox.driver.findElement(By.tagName("html")),Keys.NUMPAD2).build().perform();
By this i am able to switch the focus but not able to do anything in this tab.
Please suggest
you can do like this:
Set<String> handles = driver.getWindowHandles();
String currentHandle = driver.getWindowHandle();
for (String handle : handles) {
if (!handle .equals(currentHandle))
{
driver.switchTo().window(handle);
}
}
//fill your form in the other tab
......
//go back to first tab if you want
driver.switchTo().window(currentHandle);
This it the code when using selenium with Node.js and Typescript
const mainHandle = await this.driver.getWindowHandle();
// load new tab here ..
const allHandles = await this.driver.getAllWindowHandles();
for (const handle of allHandles) {
if (handle !== mainHandle) {
await this.driver.switchTo().window(handle);
}
}
Get the browser-tabs and do as you like:
List<String> browserTabs = Lists.newArrayList(driver.getWindowHandles());
driver.switchTo().window(browserTabs.get(1)); // Switch to second tab
// Do something on second tab here...
driver.switchTo().window(browserTabs.get(0)); // Return to first tab
// Do something on first tab here...

Devexpress - How to open a form as a tabbed view

I have a Ribbon Form with a treelist on the left so i put a XtraUserControl to insert a DocumentManager in which i would like to add all my tabbed forms (like in Visual Studio).
How can i do this?
Thanks
I suggedt you start from the How to: Display Documents Using a Tabbed UI example. The main idea of this example is that you can add the DocumentManager onto the form and then handle a treelist item's Click to add all needed child forms as MDI-children - the DocumentManager will track all the changes automatically:
Form childForm = new Form();
childForm.MdiParent = this;
childForm.Show();
To read more about the another Document Manager concepts and features please refer to the corresponding documentation articles.
public void Viewchild(Form _form)
{
//Check Before Open
if (!IsFormActive(_form))
{
_form.MdiParent = this;
_form.Show();
}
}
//Check If a Form Is Opened Already
private bool IsFormActive(Form form)
{
bool IsOpened = false;
//If There Is More Than One Form Opened
if (MdiChildren.Count() > 0)
{
foreach (var item in MdiChildren)
{
if (form.Name == item.Name)
{
// Active This Form
xtraTabbedMdiManager1.Pages[item].MdiChild.Activate();
IsOpened = true;
}
}
}
return IsOpened;
}
open form in
Master.frmBranch fb = new Master.frmBranch();
fb.Name = "frmBranch";

Resources