Watchkit check if WKInterfaceController is showing - watchkit

In my Apple Watch app, I update the title text via self.setTitle("some title"). The problem is, that if that code gets triggered on Controller A while Controller B is present, A, the one in the "background", (e.g. in a hierarchical/Master-Detail design) changes the title although B is showing.
What's the best way to get around this? I tried looking for a way to do something like
if (self.navigationController.topViewController == self) {
self.setTitle("Chats (live)")
}
but this isn't available on Watchos.
How else can I achieve this?

I put this together, haven't tested this much yet but on the first look it appears to work:
var masterTitle = ""
var masterActive = false
...
setControllerTitle("Test") //set the title
override func didAppear() {
masterActive = true //enables title updates
setControllerTitle(masterTitle) //sets title if view re-appeared
}
override func willDisappear() {
masterActive = false //disables title updates
}
func setControllerTitle(_ s : String){
masterTitle=s //saves title for future use
if(masterActive){
self.setTitle(s) //sets title when view is current
}
}

Related

Detect opening of PluginSidebar in Wordpress Gutenberg

I'm looking to reinitialise some settings and state data when my PluginSidebar is reopened, but I'm struggling to find anything useful in wp.data core/editor or similar that I could use to best create a subscription.
Does gutenberg provide any such data where I can check to see if the side panel is open or shut, so that I could fire a function of my choice every time it opens?
At present, I have a mutationObserver in place listening to see if it opens, which is quite clunky.
Some pseudo-code of my preferred approach.
subscribe(() => {
if (select('core/editor').isPluginSidebarOpen()) {
open = true
} else {
open = false
}
})
Your pseudo-code is so very close.. the function exists and is called isPluginSidebarOpened and comes from core/edit-post, eg:
import { subscribe, select } from '#wordpress/data';
subscribe(() => {
if (select('core/edit-post').isPluginSidebarOpened()) {
// Is open..
} else {
// Is closed..
}
});

Angular SlickGrid is it possible to use pagination AND set row color based on value?

Is it possible to set the background color for a row in slickgrid (based on data values) AND use pagination? For angular-slickgrid package.
I used getItemMetadata as suggested multiple other (old) posts - example SlickGrid: How to loop through each row and set color based on the condition?.
This code:
metadata(old_metadata_provider) {
return function(row) {
var item = this.getItem(row);
var ret = (old_metadata_provider(row) || {});
if (item) {
ret.cssClasses = (ret.cssClasses || '');
if ("attribute" in item) {
return { cssClasses: 'redRow' }; //redRow is in styles.css
}
}
return ret;
}
}
and the call is:
this.dataViewObj.getItemMetadata = this.metadata(this.dataViewObj.getItemMetadata);
It works correctly. However, when I turn pagination on, the color does not work as expected. I read that SlickGrid re-uses the same row elements when scrolling or paginating and will overwrite the styles associated with them. Is there another way to do it? Thanks for any help on this.
I tried adding the following code, after reading suggestion from ghiscoding, but the colors are still not working when pagination is enabled.
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
this.gridObj = angularGrid.slickGrid;
this.checkRowBackgroundColor(); //where I call the metadata function from my previous post, if the dataView object is defined.
//I added this code:
var self = this;
this.dataViewObj.onPagingInfoChanged.subscribe(function (e, dataView, grid) {
self.gridObj.invalidate();
self.gridObj.render();
});
}
Try this approach:
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
this.gridObj = angularGrid.slickGrid;
// check color change logic for the first time page load
this.checkRowBackgroundColor();
// use arrow function so that 'this' works properly
this.dataViewObj.onPagingInfoChanged.subscribe((e, dataView, grid) => {
// check your color change logic every time Paging Info Changed
this.checkRowBackgroundColor();
});
}
Inside your checkRowBackgroundColor:
checkRowBackgroundColor() {
// ... any of your logic
// get metadata
this.dataViewObj.getItemMetadata = this.metadata(this.dataViewObj.getItemMetadata);
// rerender the grid after getting new metadata
this.gridObj.invalidate();
this.gridObj.render();
}
Your problem should be solved now. As I have not tested on my local machine, I can not give guarantee. You can checkout original documentation of angular-slickgrid about this specific topic here: Dynamically Add CSS Classes to Item Rows

adding custom content to header in fullcalendar timeline view

I am trying to add additional content to the header for each day in timeline view
According to this link:
https://github.com/fullcalendar/fullcalendar-scheduler/issues/311
it should be doable by hooking into resourceRender.
But as far as I can tell, and what I have tried so far, I can only get hold of the resource it self and not the header per day.
I have created a codepen and hooked into resourceRender to play around with: https://codepen.io/thomasabcd/pen/YzzezoO
resourceRender: function(renderInfo){
console.log(renderInfo.el);
},
Any ideas?
If anybody else faces the same issue, I found a solution by hooking into the datesRender-callback. The code below makes a check and only adds the additional HTML to resourceTimelineWeek. Just remove the check if you don't need it.
See Codepen here: https://codepen.io/thomasabcd/pen/jOOZYRm
datesRender: function(renderInfo) {
let viewType = renderInfo.view.viewSpec.type;
if (viewType == "resourceTimelineWeek") {
let dateHeaders = renderInfo.el.querySelectorAll("th[data-date]");
dateHeaders.forEach(element => {
let headerDate = element.dataset.date;
let headerText = element.querySelector(".fc-cell-text");
let extraHTML = "<p>some text</p>";
headerText.innerHTML = headerText.innerHTML + extraHTML;
})
}
}

How to use a static range and display members according a TOP(x) style query

We are trying to add a slider jquery widget, and would like to define a static range, say percentage from 0% to 100%.
Then we would like to use the value from the slider in that range as the parameter for the TOP(x), as shown on the picture.
Is this possible?
Any hints ?
I've created an example report for you, import it using the default [Sales] schema
https://drive.google.com/file/d/0B3kSph_LgXizdk9OdnlTWkxHa1U/view?usp=sharing
You could achieve this functionality by using the next sequence:
Create Slider widget
Open a widget options dialog and configure widget properties
Select Query Wizard -> Query Type: Mdx Hierarchies
Add single random hierarchy to bypass validation(it will be replaced)
Setup the default value in Initial Selection (i.e. 10%)
Add a code to your report javascript
viz.filters.Slider.prototype.componentWillMount = function(){
if(_.isArray(this.props.items))
this.setState({
entities:new viz.EntityData(this.props.items),
range:_.map(this.props.defaults,"uniqueName")
});
}
viz.filters.Slider.prototype.onBuildAllDone = function(){
if(!_.isEmpty(this.state.range)) {
this.fireEvent(vizEventType.onSelection,
this.createEvent(this.state.range));
this.fireEvent(vizEventType.onNewLabel,
this.createEvent(this.state.range));
}
}
function consumeEvent( context, event ) {
if (event.name == 'ic3-report-init') {
// Following code will replace a data provider for Slider
// with generated numbers. But to do so, you'll need UID of
// the Slider widget, in this example it's "w1"
var widget = event.value.widgetMgr().getItemById("w1");
_.assign(widget.builder().guts_, {
items:_.times(100, function(idx){
return {
name:idx + 1 + "%",
uniqueName:idx + 1
}
})})
}
}

How do I create a paragraph break in Google Form help text?

I've looked on Google's product forums, and I can't find anything. The help text field is designed for brief text, but I want to insert a mulit-paragraph article. Without paragraph breaks, I wind up with a bunch of text that's difficult to read.
This has been bugging me for a long time and I've came up with a not so elegant but efficient solution based on Apps Script. Pavel Agarkov had the same idea! My version also works with multiple occurences and can be re-run if Google Forms removes the line breaks when you edit the text.
When editing a form, open the Script Editor from the main menu.
Create a new script, replace the content with the code below. Save it and return to your form.
Reload the page. You will notice a new option in the main menu, looking like this
That "Scripts" menu was added by our script. Don't use it for now, it won't do much.
When editing content, use fours spaces as a placeholder for line breaks.
Run the script from the Scripts menu. Now celebrate 👯‍♀️
Some things worth noting:
You will get a permission request the first time you run the script. It's ok, read the message and do what you have to do.
Once the line breaks are there, Google Forms, god bless its heart, will remove them every time you edit the field. Mildly infuriating. Just run the script again.
The script you need to use is:
// From https://stackoverflow.com/questions/22207368/
function onOpen() {
var ui = FormApp.getUi();
ui.createMenu('Scripts')
.addItem('Replace 4+ spaces with line breaks in Title and Description', 'addLineBreaks')
.addToUi();
}
function addLineBreaks() {
var theForm = FormApp.getActiveForm();
var theQuestions = theForm.getItems();
var thePlaceholder = new RegExp(/\s{4,99}|\n/, 'gi');
for (i = 0; i < theQuestions.length; i++) {
var theText = theQuestions[i].getHelpText();
if (theText.search(thePlaceholder) > 0 ) {
theQuestions[i].setHelpText(theText.replace(thePlaceholder,' \n'));
}
theText = theQuestions[i].getTitle();
if (theText.search(thePlaceholder) > 0 ) {
theQuestions[i].setTitle(theText.replace(thePlaceholder,' \n'));
}
}
}
I found that you can't do it through the editor but it is possible via the script.
Go to main menu -> script editor;
past the following code to the editor;
function addLineBreaks()
{
var form = FormApp.getActiveForm();
// find form items you need
var questions = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);
for(i = 0; i < questions.length; i++)
{
var title = questions[i].getTitle();
// if no replacement has been done yet
if(title.indexOf("\n") < 0)
{
// this will add line break after <double space> like in markdown
questions[i].setTitle(title.replace(" ", " \n"));
}
}
}
then set up trigger to start this method on form open.
I struggled with this question myself for too long!
However, when you know how its simple:
Go to "Add Item"
Choose "Section Header"
This option allows you to put paragraphed text into your Form.
As of June, 2018, the following work (but only the second option is documented):
Just put new lines in the description and it will be shown in the form - try using two for a paragraph.
If you want a bit more style - add a 'Title and Description' - see the second option in the tool bar showing 'Tᴛ'. The Title will always add extra space (even if it's empty) and will show any title as inverted, larger, text. You can disable the description if you just want a 'heading' followed by questions.
None of the above solutions worked for me, SO I added a unicode character https://www.compart.com/en/unicode/U+2002 pasted 4 to 5 times and this is how it looks
Sorry for the bad news, but this seems impossible to me.
I found the answer! While in the box into which you are entering text, go to Properties in the Developer tab. You will get a drop-down menu. At the bottom of the menu is "Plain Test Properties" with a check box for "Allow carriage returns (multiple paragraphs).
This is a better solution but based on the above. It allows you to edit the form which amazingly the above solutions don't:
// Version 2020-10-07a: by Dennis Bareis
// Handles "{nl}" in form & question descriptions
// Forms API: https://developers.google.com/apps-script/reference/forms
// Based on https://stackoverflow.com/questions/22207368/
// This code #: https://stackoverflow.com/a/64216993/3972414
// [0] ... -> Script Editor -> Create New Script
// [1] Paste into script editor
// [2] Run onOpen()
// [3] On first run authorise script
// [4] This adds 2 scripts under a new button in the edit form UI
// (to the left of the "Send" button)
// [5] Use "START" before re-editing form
// [6] Use "END" to publish the changes
// 5&6 required as otherwise you end up with "line1Line2Line3" etc
String.prototype.replaceAll = function(search, replacement)
{
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
//This doesn't perform the function on open, just adds it to the UI, you run when finished.
function onOpen()
{
var ui = FormApp.getUi();
ui.createMenu('Scripts')
.addItem('[1] Prepare for RE-EDITING this form (restore {nl})', 'editFormStart')
.addItem('[2] Publish the form (finished editing, remove {nl})', 'editFormEnd')
.addToUi();
}
function editFormStart()
{
swapLineBreaks("\n", "{nl}")
}
function editFormEnd()
{
swapLineBreaks("{nl}", "\n")
}
function swapLineBreaks(FromText, ToText)
{
var form = FormApp.getActiveForm();
// find form items you need
var oForm = FormApp.getActiveForm();
var questions = oForm.getItems();
// Fix the form's description
var formDesc = oForm.getDescription()
oForm.setDescription(formDesc.replaceAll(FromText, ToText))
// Work through each question
for(i = 0; i < questions.length; i++)
{
//var QTitle = questions[i].getTitle();
//questions[i].setTitle( QTitle.replaceAll(FromText, ToText));
var QText = questions[i].getHelpText();
questions[i].setHelpText(QText.replaceAll(FromText, ToText));
}
}

Resources