Thursday, January 4, 2018

Customizing KWizCom SPFx remote list viewer to add google maps popup

We are hard at work here at KWizCom working hard to bring you amazing SPFx web parts. I'm sure you know that.

One of our best offerings are now a bundle of some amazing web parts that are all built on SPFx using KnockoutJS templating and bindings - which gives you the power to influence and change the HTML template of these web parts, or write some custom actions and buttons to really make them feel like custom tailored solutions for your exact needs.

One example I want to discuss today is something our product manager asked me 10 minutes before doing a demo for a potential customer, who mentioned he was interested in showing a location from a list item's column in a popup google map.

He was demoing our remote list viewer app http://www.kwizcom.com/sharepoint-apps/remote-list-viewer/overview/

but this is true for our list aggregator or any of our web parts that are built on top of our amazing Data View Plus: http://www.kwizcom.com/sharepoint-apps/data-view-plus/overview/

So, in just a few minutes I was able to provide him with this script that would add an action to the table control that opens a city or address from a column named "City" or "Title" in a popup.

Here is how it works.

Start with a list that has a location either in the Title column, or in a column named "City".
(you can have any other column names you want - you will just have to specify the column name in the script sample...)

Next, lets create a modern page and add a remote list viewer to it, setting the data source to this list:
You end up with this basic table control showing your list items. Please note the action buttons on each row - these are customizable actions that we are going to change:
Now, just click the "Open designer" button to bring up our template designer, scroll down and expand "configure table" section where you will find the "Item actions" list:
By default we provide an item click action plus 4 actions with icons for each item:
1. Open item properties in a popup
2. Open a new email with the item's properties
3. Open the item view form in a new window
4. Open the item edit form in a new window

Choose any one of these to replace, click on it and an action editor popup will open. First - change the icon to something with a map (you can type "map" to filter the icons list):
Next, paste this script into the script editor text area. For more hints on what objects and data you can use - see this popup for more help and information.

var openInPopup = true; //change this to open in new window

//for popup
var mapsLink = "https://www.google.ca/maps/place/{city}";
//for iframe
var mapsLinkEmbed = "https://maps.google.com/maps?q={city}&output=embed";
//get the city column value, if doesn't exist - take the item's title.
var fieldValue = item.City && item.City.text || item.Title;

var buildCityPopup = function(city, src) {
    var popupCity = document.getElementById('kwCityPopup') || document.createElement('div');
    if (popupCity.classList.length < 1) {
        popupCity.classList.add("kw-Dialog");
        popupCity.classList.add("kw-Dialog--lgHeader");
        document.body.appendChild(popupCity);
    }
    var html = '<div class="kw-Dialog-title">{city}</div><div class="kw-Dialog-content" style="overflow:auto;max-height:500px;"> <div class="kw-Dialog-subText"><div style="text-align:center;width: 100%;border-bottom: 2px solid #ce4b1f;max-height:180px;"><iframe src="{src}" width="300" height="150" frameborder="0" style="border:0"></iframe></div></div></div><div class="kw-Dialog-actions"><button class="kw-Button kw-Dialog-action"><span class="kw-Button-label">Close</span></button></div>'.replace("{city}", encodeURIComponent(city))
        .replace("{src}", src);
    popupCity.innerHTML = html;
    new kwfabric['Dialog'](popupCity).open();
};

if (fieldValue && fieldValue.length > 0) {
    mapsLink = mapsLink.replace("{city}", encodeURIComponent(fieldValue));
    mapsLinkEmbed = mapsLinkEmbed.replace("{city}", encodeURIComponent(fieldValue));

    openInPopup ? buildCityPopup(fieldValue, mapsLinkEmbed) : window.open(mapsLink);
} else alert("Sorry, could not find a city column value. Please edit the action or add a column named 'City'.");

That's it. you are done. Close the popup and designer by clicking outside on the web part area.
Now you web part shows a map action icon:
When you click on it, you will get a popup with google maps of that location:

Like it? Questions? Comments?
Feel free to write in the comments below.
Please note, for support or more advanced "how do I?" questions, I recommend as always to contact our support (at) kwizcom (dot) com

Thanks, Shai.

Friday, December 15, 2017

SPFx 1.4 brings automatic CDN deployment option!

Reading the latest release notes, it was a bit hard to find and to understand fully but here is what I got from it so far:

Starting from SPFx 1.4, there will be a new setting in the package-solution.json file.

"includeClientSideAssets"

Basically, when this feature is turned on, building a produciton package will no longer force you to specify the target CDN and manually host your files there.

Instead, all of these assets will go into the .sppkg file, and when deployed into SharePoint, they will be automatically uploaded to a CDN-enabled library either in your app catalog or - if you enabled it - another pre-designated CDN location.


The benefits are obvious:
That means smaller dev teams or vendors don't have to worry about keeping a CDN up to host their files.
Also, you won't have to worry about uploading and managing these files yourself.

The disadvantages for vendors like us are also clear:
We will have no control over the CDN, meaning - again - any minor change in code would have to result in a new package being built, published, sent to customers and installed before they will see any fixes applied.

While that was how we did things for years in the full trust world, in the ever-changing fast pace apps/add-ins world I am not sure if that is a viable option anymore.
Changes are being rolled to SharePoint continuously. Admins no longer have control on when updates are being installed. And so - our frequently have to update our code to work with these changes and adapt to new features on a regular basis.
Having our own CDN allows us to do just that - push updates to our CDN on a fast ring and production releases and our customers could be happier.

So, it is exciting to see this as an option, even though I probably won't be able to use it in the real world.

What do you think?

Tuesday, December 12, 2017

SharePoint REST API double encoding field internal names when using $expand=FieldValuesAsText

This is a simple bug I found when building one of our products while it was used by a French speaking customer...

He simply created a column with a french name that had some special characters, for example: "Français"

So, the letter ç was encoded when creating the column's internal name, which is what you'd expect. The column's internal name was: "Fran_x00e7_ais"

When making REST requests to SharePoint to get items, query items, or anything you like - you would get the item field value under this internal name - gain, as you would expect.

But!!!

If you wanted to get the values as text and used the $expand=FieldValuesAsText in your query (or /FieldValuesAsText if getting a single item) - SharePoint returns something very different.

The value for this column would be set in "Fran_x005f_x00e7_x005f_ais", which is basically a double encoded version of the real internal name: "Fran_x00e7_ais"


I couldn't find a solution for this problem besides hacking it, so now I hard coded updated my code to replace _x005f_ with _ when looking for field values as text...

I'll report this issue but since changing it would potentially break so many existing applications I doubt it would be fixed any time soon.

So for now - keep that in mind, and let me know if there is a better way to finding out the field name that this REST API uses!