Blog


Hidden New Feature in iOS 14

Now personal automations are truly automatic in iOS 14! Before, you had to tap a notification to run them, now that’s gone, they just run and are amazing! ios-12-shortcuts-basics
And dangerous! Have 🤩!

More about iOS Shortcuts here.


How To Send Mail As on iOS With Gmail Account (E-Mail Alias)

IOS mail default Gmail modeIt’s nice to only have a single e-mail address, but for some people that’s just impossible. And instead of configuring multiple accounts for all e-mail addresses on your phone, you can forward all mail to a single account and receive and send using all e-mail addresses.

The native Google Mail mode on iOS (currently iOS 13.6) only allows sending as the primary e-mail address for the account, but there is a way around that. That way is IMAP mode, but we’ll also keep the native mode because it supports Contacts and Calendars syncing. And this works for both personal Gmail accounts and Google Apps (aka G Suite).

If you already have the native mode configured on your iPhone, we’ll just deactivate the E-mail syncing by going to

Settings > Password & Accounts > [Account Name]

and deselecting the Mail option as in the print screen to the right.

Then add a new account of type Other > Add Mail Account

To be able to use your account as IMAP, you either need to allow un-secure apps or enable 2 step authentication and add an App Password: https://myaccount.google.com/security

Then, in the web version of Gmail (https://mail.google.com), go to Accounts and Import and click Add Another E-mail Address. If that address is not part of the same G Suite account, you’ll be asked for a username and password. If using the Allow Unsecured Apps option (see above), then you’ll use your account’s password. Otherwise, if using 2-step authentication, use an App Password you’ll generate.

Now it’s time to test sending from your new e-mail aliases!

Enjoy and please share!

ios email send as web alias

ios mail disable mail

 


How to update a SharePoint list item using REST

If the list’s forms are customized and you can’t edit a field using them, with due permissions you can just make a fetch request from the console to update a certain field.
You need the list name, item ID, field internal name and the new value.
As with all POST requests to SharePoint, you need the REQUESTDIGEST value, which you can get from a freshly loaded page, by searching the page contents by `__REQUESTDIGEST`
The request you need to make is:


fetch("/sites/SITE_NAME/_api/web/lists/getbytitle('LIST TITLE')/items(ITEM_ID)", {body: JSON.stringify({FIELD_INTERNAL_NAME: 'NEW_VALUE'}), method:'POST', headers:{'content-type': 'application/json',accept:'application/json;odata=nometadata', 'X-HTTP-Method': 'MERGE', 'X-RequestDigest': 'REQUESTDIGEST', 'If-Match': '*'}}).then(a => a.text()).then( a => console.log(a))


SharePoint How To: Change a field’s JSLink property using JSOM

Whether you need to update the .js file and want browsers to automatically download the new version (skip local cache) or you need to completely change the script, here’s how you can achieve this in your browser’s console:

const listUrl = '/sites/siteName/Lists/List';
const fieldTitle = 'My Field';

const clientContext = SP.ClientContext.get_current();
const web = clientContext.get_web();
const list = web.getList(listUrl);
const field = list.get_fields().getByInternalNameOrTitle(fieldTitle);

clientContext.executeQueryAsync(
	() => {
		console.log(fieldTitle, "'s JSLink: " + field.get_jsLink());

		// set new JSLink:
		if (false) {
			const newJSLink = 'NEWJSLINK HERE';
			field.set_jsLink(newJSLink);
			field.update();
			clientContext.executeQueryAsync(
				() => {
					console.log(`Successfully set JSLink for field ${fieldTitle} to ${newJSLink}`);
				},
				(sender, error) => {
					console.error(error.get_message);
				}
			);
		}
	},
	(sender, errror) => {
		console.error(errror.get_message());
	}
);

 

While viewing any list in your SharePoint site, open the console, add your list url and field title and first run the script to see the current JSLink and then remove the `false` branch to change it.


How add Siri voice control to any smart device (*)

There are a lot of smart devices out there these days that are compatible with Alexa, Google Assistant or HomeKit, although most of them only offer support for Alexa or Google Assistant. A lot of them also support IFTTT, an integration platform for end users. If you have an iPhone and a smart device with IFTTT but no HomeKit support, this article is for you. I’ll show you how to add Siri voice control for your device without extra hardware.

In short, these are the steps:

  1. Connect your smart device in IFTTT
  2. Add the Webhooks service in IFTTT
  3. Create an applet in IFTTT that is triggered by Webhooks and controls your device
  4. Create a Shortcut on your iPhone that triggers the IFTTT applet you created at step 3.

 

And here are the above steps in detail:

1. Connect your smart device in IFTTT

IFTTT is an iOS app you can install that allows you to link two different apps. It’s simple and a lot of manufacturers support it.

After your account is set up, follow your device’s instructions for adding support for it inside IFTTT. Basically you securely connect the manufacturer’s service to IFTTT.

2. Add the Webhooks service in IFTTT

Webhooks is a service made by IFTTT that can serve either as a trigger or as an action. Trigger example: an external app calls a url. Action example: IFTTT calls a custom url from an external service.ifttt-webhooks

To add it, just search for it inside IFTTT and activate it. You will get a url with an API key that you can access in your browser to see an example of how to use it. The final URL that you will use at step 4 looks like:

https://maker.ifttt.com/trigger/{garage_door}/with/key/{your_own_ifttt_webhooks_key}

3. Create an applet in IFTTT 

Webhooks based applets cannot be shared, so you will need to create this applet yourself, but not fret, it only takes a minute: start a new applet, then add webhooks as the trigger. Set the Event Name field to your custom word, something like garage_door – this will be used in the call from the Shortcuts iPhone app.

In the action for this applet, add the service for your device (you configured this in step 1).

4. Create a Shortcut on your iPhone

Shortcut is an app made by Apple. You can find it and download it in the AppStore. Then create a new shortcut with the following two steps:

  • URL
  • Get Contents of URL

In the first step, you paste the url in step 2.

For the shortcut settings, you give it a name and set the Siri phrase to invoke it.

 

That’s it! You can now run your shortcut to test it and then ask Siri to run it!


How To Get Effective Z-Indexes on All Elements On A Page

Sometimes you need to know what z-Index to set on a positioned element in order for it to really be on top of everything. If you own the whole page, that’s easy to manage, but when working on a page shared with other scripts that you don’t control, you need a way to tell what are elements have z-Index set.

You can run this in the console to get a list of all elements that have z-Index set and the corresponding elements:

document.querySelectorAll('*').forEach(e=>{const s = getComputedStyle(e);if (s.zIndex !== 'auto') console.log(s.zIndex, e)})

Or you can define a function that you can call dynamically when you need to get the current largest z-Index:

function largestZIndex() {
    let z = 0;
    document.querySelectorAll(‘*’).forEach((e) => {
        const s = getComputedStyle(e);
        if (s.zIndex !== ‘auto’ && +s.zIndex > z) {
            z = +s.zIndex;
        }
    });
    return z;
}

 


How To Change UserCustomAction in SharePoint with Javascript (JSOM)

If you customized some part of SharePoint with a User Custom Action, Location=Scriptlink and need to update the js file at some point, having users use the new version is achieved by changing the scriptSrc. Otherwise, the old version of the JS file is cached by the browser even after F5. Only a SHIFT+F5 would refresh it to the new version. To avoid having all users the pain, you can easily update the path to you js by adding some date code in the path, like http://path-to-file/siteassets/file.js?v=2017112702

var ideaCtx = SP.ClientContext.get_current();
var web = ideaCtx.get_web();
var oCustomActions = web.get_userCustomActions();
ideaCtx.load(oCustomActions);
ideaCtx.executeQueryAsync(
function () {
var enumerator = oCustomActions.getEnumerator();
while (enumerator.moveNext()) {
// first log all Custom Actions to identify the one you want to delete
console.log(enumerator.get_current().get_title() + " -> " + enumerator.get_current().get_location() + ' -> ' + enumerator.get_current().get_scriptSrc());
}
var ca = oCustomActions.getItemAtIndex(IDENTIFIED_ZERO_BASED_INDEX_IN_ABOVE_ENUM); // choose this after
ca.set_scriptSrc(UPDATE_THIS_WITH_newPath)
ca.update();
ideaCtx.executeQueryAsync(
function () { console.log('CA modified'); },
function (sender, args) { console.log(args.get_message()); }
)
},
function (sender, args) { console.log(args.get_message()); });


SharePoint – Cannot change hidden attribute for this field

In case you ever provisioned a Title field with the property Hidden=TRUE, and you need to set it to Hidden=FALSE later, you end up with this enchanting error:

Cannot change hidden attribute for this field

There are a couple of articles that suggest using PowerShell and Reflection, but if you like a pure web / JS solution, here it is:

Get the current SchemaXML for the field. In Chrome, while viewing a list, run the following line by line (the executequeryasync being async, you would need to use a callback if you wanted to run all commands as a block)

let myctx = SP.ClientContext.get_current()
let field = myctx.get_web().get_lists().getByTitle('List 1').get_fields().getByInternalNameOrTitle('Title')
myctx.load(field, 'SchemaXml')
myctx.executeQueryAsync(()=>console.log('success'), (a,error)=>console.log('error',error))

(wait for success here, should take max 1s)

field.get_schemaXml()

(change Hidden=”FALSE” in this string and use it in the set_SchemaXml command)

field.set_schemaXml(`previous string with Hidden="FALSE" instead of TRUE`)
field.update()
myctx.executeQueryAsync(()=>console.log('success'), (a,error)=>console.log('error',error))

That’s it, your field is visible now


SharePoint – Changing JSLink property for a Content Type with REST

JSLink is a way to attach custom JavaScript code to run when the object it is attached to is shown on the page. For example, if setting the JSLink property on a field, the JS file(s) will be executed whenever that field is shown in a view or in a form.

JSLink property can be set on:

  • Fields
  • Content Types
  • Views

Although the JSLink property can be specified in a list schema for the list forms, the JSLink value gets attached to the form’s web part instead of being a property.

Coming back to fields, content types and views, JSLink property can be set declaratively in the XML and can also be changed later with REST and JSOM. This article will show you how to set or change the JSLink property of a list content type (copy of a content type applied to a list). You can run this in Chrome Console on a SharePoint page:


fetch("https://webAbsoluteUrl/_api/lists/getbytitle('List Title')/contenttypes('<content_type_id>')",
{"method": "POST",
"credentials": "include",
"body": JSON.stringify({"__metadata": { "type": "SP.ContentType" }, "JSLink": "~sitecollection/Style Library/js/file.js?rev=2017050801"})
"headers":
{"content-type":"application/json;odata=verbose",
"accept": "application/json;odata=verbpse",
"X-RequestDigest": document.querySelector('#__REQUESTDIGEST').value}
})

Versions of SharePoint: 2013, 2016


Moving from event receivers to workflows in SharePoint Online (Office 365)

As Microsoft announced at end of July 2016 that coded sandbox solutions will stop working, any existing event receivers must be moved to one of:

  • Remote event receiver in a provider hosted app
  • Workflow
  • JavaScript that runs on the New or Edit forms

Each has advantages and drawbacks, so you would plan ahead. Actually at the time of writing, transitioning from existing working coded sandboxed solutions is very rough because coded sandboxed solutions cannot be activated anymore, making testing in a site collection separate from production impossible.

This post only touches lightly the subject, so if you need help, please contact us and we’ll try to give a hand.

Remote event receiver in a provider hosted app

This would probably be the most robust option, but also the most complex and one that requires additional hosting costs. Also, the fact that that the service must pe SOAP would probably push back a lot of people.

Workflow

Workflows can be set to start automatically on a new item or when an item is changed, so this would make for a good substitute. Only thing is that we don’t have synchronous capabilities like an event receiver could have been, so we need to analyze if a workflow is suitable.

There are two main type of workflows when it comes to development tools: SharePoint Designer workflows and Visual Studio workflows. Apart from the tooling, there’s an important distinction between them which is very important in our scenario: performance. VS workflows are way faster and kick off without delay, whereas Sharepoint Designer ones tend to take their time, making for a laggy experience. So if you’re comfortable with VS, you’d definitely choose it.

JavaScript that runs on the New / Edit forms

Actually one might need to combine this option with the previous one to achieve what was so simple to do in an event receiver.

In order to to this, you would most probably set the JSLink of forms.