I have the following plunker working with save/restore and localStorage:
http://plnkr.co/edit/Ad12QG1uKFEf38aOtpaL?p=preview
I can save the grid state, adjust some columns (like column resize, move, etc), and then restore back to the saved grid state just fine.
Once I've saved it though, how would I go about making a "reset" function work? I want to reset it to the default state of my grid before there were any saved changes.
My attempt, which so far is unsucessfull. I'm assuming I would try to save the default state on load before the restore occurs...
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.defaultState = $scope.gridApi.saveState.save();
...
...and then restore similar to the $scope.restoreState function...
$scope.resetState = function() {
$scope.gridApi.saveState.restore($scope, $scope.defaultState);
}
...but that's throwing errors.
I was able to get it to work. Here's a functioning example:
http://plnkr.co/edit/Ad12QG1uKFEf38aOtpaL?p=preview
I took the same approach I outlined in my question, but I had to wrap the defaultState in a $timeout() because the state isn't immediately available within onRegisterApi without that timeout. I just made sure to make it occur before the restoreState timeout.
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$timeout(function() {
$scope.defaultState = $scope.gridApi.saveState.save();
}, 50);
$timeout(function() {
$scope.restoreState();
}, 100);
},
I'm not that familiar with angular yet, so I'm sure someone could improve this.
Related
I am currently tying our audio player with mediaSession.
Everything is working as it should, when I hit play and update navigator.mediaSession.metadata, it's properly displayed in the notification on desktop and mobile.
But after I reload the page and hit play, the notification has always default values (website URL as a title and link rel="icon" for the artwork). This only happens after I reload the website. If I close it and open again the notification is working properly again.
Here's how it's done:
//...
initialConfiguration: {
title: 'Initial Title',
artist: 'Initial Artist',
album: '',
artwork: [
{ src: "initial/artwork/url.jpg", sizes: "512x512", type: "image/jpg" },
]
},
currentMetadata: null,
setMediaSessionMetaData: function(){
let self = this;
if ('mediaSession' in navigator) {
if( !self.currentMetadata ){
self.currentMetadata = new MediaMetadata(self.initialConfiguration);
}else{
// Update existing metadata
self.currentMetadata.title = "New Title";
self.currentMetadata.artist = "New Artist";
self.currentMetadata.artwork = [
{ src: "new/artwork/url.jpg", sizes: '512x512', type: "image/jpg" },
];
}
navigator.mediaSession.metadata = self.currentMetadata;
}
},
//...
This function works perfectly fine on first page load, when I hit play for the first time it loads the initialConfiguration and if I call the function again the title and artwork gets updated. But after reload, the notification has always default values ignoring my configuration.
Is there a bug in mediaSession, I didn't find anything regarding this issue on mediaSession github page (https://github.com/w3c/mediasession/issues) and searching this issue gives me zero results.
After Searching for days and not finding anything....
I discovered a workaround. It has to do with the performance.navigation.type when you first open a page it is set to 0 and after a refresh it gets set to 1. I was curious if this had any effect on the mediasession so I figured out how to "Hard Refresh" the page by using window.open(window.location.href, "_self");, because apparently that generates a "Hard Refresh". After that the mediasession works again. so what I did was setup an onload function that checks to see if performance.navigation.type == 1 and if so then do a "Hard Refresh"
window.onload = function() {
if (performance.navigation.type != 0) {
window.open(window.location.href, "_self");
}
};
Now when the user refresh's it will do a "Hard Refresh".
Also make sure to move the window. Onload line to the end of the javascript file or after the initial function
have found that in my electron application the following code from the main.js only returns a device list of length 1 (filled with one device) even though there are many devices around.
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
event.preventDefault();
console.log(deviceList);
bluetoothSelection.selectBluetoothDevice(deviceList, mainWindow, (deviceId) => {
callback(deviceId);
});
If I call
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: [serviceUuid]
})
multiple times, the device returned changes and if I cycle through it often enough, I get the device I want eventually.. But I built a device Picker window and all that stuff and now the window opens for only one device, which makes everything quite annoying:P
Any ideas on what could cause this or even how I could fix it?
If you have a look at https://www.electronjs.org/docs/latest/api/web-contents#event-select-bluetooth-device you will find the example code provided by electron you probably already know:
win.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
event.preventDefault()
const result = deviceList.find((device) => {
return device.deviceName === "test"
})
if (!result) {
callback('')
} else {
callback(result.deviceId)
}
})
You have to prevent the callback until you have found the device you are looking for. I suggest to open a second window and pass in the deviceList. Now you can display the devices and let the user choose one. If the user has chosen a device, you can close the second window and call the callback with this deviceId.
To communicate between the windows you can use the “contextBridge” with “ipcRenderer” and “ipcMain” and to call the callback you can make a global variable
var callbackForBluetoothEvent = null;
and fill it int the
mainWindow.webContents.on(
// stuff
callbackForBluetoothEvent = callback; //to make it accessible outside
// stuff
);
With a “ipcMain.on”
ipcMain.on("BLEScannFinished", (event, args) => {
console.log(args);
console.log(BLEDevicesList.find((item) => item.deviceId === args));
let BLEDevicesChoosen = BLEDevicesList.find((item) => item.deviceId === args);
callbackForBluetoothEvent(BLEDevicesChoosen.deviceId);
});
You can than call the callback
Unfortunately this is a bit to much code for a forum post but you can find a rudimentary solution of this suggestion at the link:
https://github.com/grosdode/Electron-multible-BLE-devices
The electron issues 11865 was also helpful and there is a page which shows alternative code for the suggested solution. Unfortunately also to much code to post it here.
https://technoteshelp.com/electron-web-bluetooth-api-requestdevice-error/
I'm loading the Zendesk web widget into a page, and this is the event handler for when it's loaded in
scriptElement.onload = function () {
zE(function () {
$zopim(function () {
$zopim.livechat.button.setHideWhenOffline(true);
$zopim.livechat.setOnStatus(function (status) {
console.log('status',status);
status === 'online' ? $zopim.livechat.button.show() : $zopim.livechat.button.hide();
});
$zopim.livechat.setStatus('offline');
});
});
};
It has the setOnStatus event handler which should trigger anytime the status changes. It seems to be triggered once when the page initially loads in. You'd expect it to be triggered as well everytime I call the setStatus method, but that's not the case. Where I log the status, it's always just 'online', and it only happens once.
What I'm trying to do is force the button to disappear when the status is offline. Yet setting the status to 'offline' doesn't hide the button, just displays the offline version (i.e. a button which lets me send an offline message, rather than a live chat).
I thought the setHideWhenOffline method might have helped, but that doesn't seem to make any difference in this case.
Any ideas?
Actually I found the solution I needed here, this prevents the offline button appearing.
window.zESettings = {
webWidget: {
contactForm: {
suppress: true
}
}
};
https://developer.zendesk.com/embeddables/docs/widget/settings#suppress
I'm having a very difficult time trying to get my data to be grouped via month. I've even gone so far as to programmatically filter through my data to return only the last day of the month and calculate the monthly value. I've tried to find a good explanation on the 'dataGrouping' property but have had no luck understanding it nor properly implementing it. Every results returns my series in a daily interval.
My questions are as follows:
Is there a minimum number of data points needed for data grouping to
work?
Under the dataGrouping.units I've tried to use this
documentation but nothing has worked for me - Still results in a
daily interval - Could someone explain this for me?
Any help on this would be GREATLY appreciated.
Are you using HighStock graph?
If yes...
Sure, it takes a lot of data to get grouping. If datagrouping option is enabled, Highstock handle automatically the switch between every grouping mode. So if you don't have a lot of data, it will not work with default settings
So, if you want to group by default, you need to force the grouping.
series:[{
[...]
dataGrouping: {
approximation: "sum",
enabled: true,
forced: true,
units: [['month',[1]]]
}
}]
EDIT
Here is a working example demo (fork of a basic highstock demo)
http://jsfiddle.net/NcNvu/
Hope it helps!
Regards
We tried a Hack around this, where we used Highstock's (Splinechart) RangeSelector, Event and DataGrouping. On click of weekly rangeselectorButton we catch this event through setExtremes. Post catching the event approximate it to "sum". If you are using two series than iterate the object. Currently doing it weekly just extend it for Monthly using corresponding UNIT
events: {
setExtremes: function (e) {
if (e.rangeSelectorButton != undefined) {
var triger = e.rangeSelectorButton;
if (triger.type == 'week') {
$.each(this.series, function (index, obj) {
obj.options.dataGrouping.units[0] = ['week', [1]];
});
} else if (triger.type == 'day') {
$.each(this.series, function (index, obj) {
obj.options.dataGrouping.units[0] = ['day', [1]];
});
}
}
}
},
I'm using a jQuery modal dialog to display a 'Please Wait' type message to a user when a ajax call is made back to the server.
I'm doing this by making the dialog visible using the jQuery ajaxSend method. And I close the dialog using the jQuery ajaxComplete method.
All fairly routine stuff I'm sure.
However if the call takes a very short about of time (say 10 milliseconds) then I want wait until a second has passed since making the dialog visible before I then close the dialog. The reason is to provide user feedback ... and to stop the horrible flicker of the dialog quickly opening and then closing.
How can I achieve this using jQuery and / or ajax?
Many thanks for any pointers.
Would a better paradigm be to actually wait for a period of time before showing the dialog? If you have a responsive app then it would make sense to only show the modal if the response does not come back within say 100ms. This would avoid delaying the UI just to avoid flicker which is what you are proposing.
Note I am using beforesend and success here to dummy up the code
var timerid;
beforeSend: function(){
//open the dialog in 100 milliseconds
timerid = window.setTimeout( function(){
$('#dialog').dialog('close');
}, 100)
},
success: function(){
//cancel the showing of the dialog if not already called
window.clearTimeout( timerid );
//close the dialog regardless
$('#dialog').dialog('close');
}
If you dont like this idea then simplay put the dialog close function inside a setTimeout within the ajax complete callback e.g
complete : function(){
//close the dialog in 1 second
window.setTimeout( function(){
$('#dialog').dialog('close');
}, 1000)
}
I've pulled together a solution for this myself - based on the great response from 'redsquare' and some further reading.
I have used the code from redsqure to open the modal dialog only after a given duration has passed - thus hopefully not having to open the modal at all.
For when the modal has opened I've added code to ensure it remains open for a minimum of 800 milliseconds ... just to avoid the possibility of it quickly flashing up on the screen. To achieve this I start a javascript timer in the 'ajaxSend' method and then I use the 'ajaxComplete' method to determine whether the modal is open. If so I use the timer to calculate how long it has been open for and make up the difference to 800 milliseconds. I adapted a script I found on line for my timer. Script below.
var timer_ms = 0;
var timer_state = 0;
/// <summary>
/// Responsible for starting / stopping the timer. Also calculates time.
/// </summary>
function timerStartStop() {
if (timer_state == 0) {
timer_ms = 0;
timer_state = 1;
then = new Date();
then.setTime(then.getTime() - timer_ms);
}
else {
timer_state = 0;
now = new Date();
timer_ms = now.getTime() - then.getTime();
}
}
/// <summary>
/// Resets the timer.
/// </summary>
function timerReset() {
timer_state = 0;
timer_ms = 0;
}
Thanks.
Thanks.