I tried to resize a Client Web Part with non integers as size, but it failed. And that’s why:

1
2
3
4
var regex = RegExp(/(<\s*[Mm]essage\s+[Ss]ender[Ii]d\s*=\s*([\dAaBbCcDdEdFf]{8})(\d{1,3})\s*>[Rr]esize\s*\(\s*(\s*(\d*)\s*([^,\)\s\d]*)\s*,\s*(\d*)\s*([^,\)\s\d]*))?\s*\)\s*<\/\s*[Mm]essage\s*>)/);
var results = regex.exec(e.data);
if (results == null)
return;

The regular expression shows that it doesn’t allow float numbers.

I’m learning how to upgrade SharePoint App, and I met a problem when I added a new list field in the upgrade.

The document mentioned that if you added a field to a content type in the feature, you should add an AddContentTypeField element to the VersionRange section. But there is no ContentType in my app, it only has a ListDefinition. I tried to add an AddContentTypeField, unfortunately it throws exception.

So I tried another way. The document also mentioned that if you have changed a file that is referenced in an elements manifest file, you have to copy the ElementManifest element for the component from the ElementManifests section to the ApplyElementManifests section. When we added a new field to list, the Schema.xml is changed, although it’s not referenced in a ElementManifest, I still copied MyList/Elements.xml to ApplyElementManifests, so it looks like this:

1
2
3
4
5
6
7
8
<UpgradeActions>
<VersionRange>
<ApplyElementManifests>
...
<ElementManifest Location="MyList\Elements.xml" />
</ApplyElementManifests>
</VersionRange>
</UpgradeActions>

And it works. Hope it’s helpful.

Reference:

Issue

Today I met a bug in SharePoint 2013, I failed to resize my app part by using postMessage. Here is my code:

1
2
var message = "<Message senderId=" + senderId + ">" + "resize(" + width + "," + height + ")</Message>";
window.parent.postMessage(message, hostUrl);

It fails to work if I set Chrome Type to None or Border Only. And I found an error message in console:

1
Uncaught TypeError: Cannot read property 'style' of null

Then I located the code in my web part page which throws the error:

1
2
3
4
5
if (resizeWidth)
{
document.getElementById(webPartDivId + '_ChromeTitle').style.cssText = widthCssText;
cssText = 'width:100% !important;'
}

It tries to find the title element and resize it. But document.getElementById(webPartDivId + '_ChromeTitle') returns null if Chrome Type is None or Border Only!
Because the app part doesn’t have a title under these 2 modes. Of course it will throw exception.

Solution

This bug is described here, you can install a patch to fix this bug.

After the patch is installed, you can find that the original code is changed, it will resize the element only if it’s not null:

1
2
3
4
5
6
7
8
9
10
if (resizeWidth)
{
var webPartChromeTitle = document.getElementById(webPartDivId + '_ChromeTitle');
if (null != webPartChromeTitle)
{
webPartChromeTitle.style.cssText = widthCssText;
}

cssText = 'width:100% !important;'
}

Hope it’s helpful.

Reference

Introduction

SharePoint App Model provides a new approach to SharePoint development. And here is the question: where to save app data? There are several ways to save data in an app, you can create a list or connect to a database in Windows Azure or set custom properties in AppManifest.xml. But we can also save data to the property bag of a SharePoint web.

Add property to web

Adding custom property to web is easy. Let’s just see the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var context = SP.ClientContext.get_current();
var web = context.get_web();

// Add a new property
var props = web.get_allProperties();
props.set_item("MyProperty", "My property value");

// Apply change to web
web.update();
context.load(web);

context.executeQueryAsync(function (sender, args) {
alert("Success.");
}, function (sender, args) {
alert("Request failed.");
});

How do we know “MyProperty” is really added to web? We can check it here: http://your_web/_api/web/AllProperties?$select=MyProperty. The result looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8" ?>
<entry xml:base="http://your_web/test/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<id>http://your_web/_api/web/AllProperties</id>
<category term="SP.PropertyValues" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="web/AllProperties" />
<title />
<updated>2013-12-04T04:37:07Z</updated>
<author>
<name />;
</author>
<content type="application/xml">
<m:properties>
<d:myproperty>My property value</d:myproperty>
</m:properties>
</content>
</entry>

Read property from web

We have two approaches to read properties from web: props.get_item("PropertyKey") or REST API.

The get_item method

1
2
3
4
5
6
7
8
9
10
11
12
var context = SP.ClientContext.get_current();
var web = context.get_web();

var props = web.get_allProperties();
context.load(props);

context.executeQueryAsync(function (sender, args) {
var prop = props.get_item("MyProperty");
alert(prop);
}, function (sender, args) {
alert("Request failed.");
});

The REST API

1
2
3
4
5
6
7
8
9
10
11
12
13
var executor = new SP.RequestExecutor('http://your_web');
executor.executeAsync({
url: 'http://your_web/_api/web/AllProperties?$select=MyProperty',
method: 'GET',
headers: { "Accept": "application/json; odata=verbose" },
success: function (response) {
var obj = JSON.parse(response.body);
alert(obj.d.MyProperty);
},
error: function (response) {
alert(response.body);
}
});

And here is the json query result, very straightforward:

1
2
3
4
5
6
7
8
9
10
{
"d": {
"__metadata": {
"id": "http://your_web/_api/web/AllProperties",
"uri": "http://your_web/_api/web/AllProperties",
"type": "SP.PropertyValues"
},
"MyProperty": "My property value"
}
}

Reference

0%