5/27/17

Upload files from Linux to SharePoint on-premise


When there is a need to automate the upload of files from Linux to SharePoint on-premise, we can use the  curl command tool. Let’s take a look at an example.




curl --ntlm username:password --upload-file test.html https://sharepoint.com/files/test.html


On this command, we use the following parameters:


Parameter
Description
-ntlm
This parameter is used to pass the domain credentials for the user in the format of username:password. 

The username should not include the domain name.
-upload-file
Use this parameter to indicate that we need to upload a file to a server location

Server url
This is the server URL.  Notice how we also indicate the folder and file name.

-verbose
If you are having problems, add this parameter to see output and error messages.





Use this command to automate the process to upload your files to SharePoint.

Originally published by ozkary.com

5/20/17

AngularJS Recursive View Templates

We are often presented with a hierarchical JSON model with nested array of objects like the one shown below:

JSON Model
Collapsible Menu





Our JSON model has a nested structure in which a node can have other nodes associated to the menu property. This model represents navigation groups and sub-groups for an app which can enable us to build a hierarchical menu. A common approach to render this model is to build a nested view that iterates through the arrays to display the information. Let’s look a simple implementation here:



<ul class="nav" style="width:200px" data-ng-controller="app.ctrl.dev as ctrl">
    <li data-ng-repeat="item in ctrl.menu">
        <a href="{{item.url}}" class="dropdown-toggle" data-toggle="collapse" title="{{item.title}}" data-target="#{{item.id}}">
            <i class="fa fa-fw fa-2x {{item.class}}"></i> <span class="nav-header-primary" data-ng-bind="item.title"></span>
            &nbsp;<span data-ng-if="item.menu" class="fa fa-caret-down fa-2x pull-right"></span>
        </a>
        <ul class="nav collapse" data-ng-if="item.menu" id="{{item.id}}">
            <li data-ng-repeat="subitem in item.menu" class="collapsed active">
                <a href="{{subitem.url}}" class="dropdown-toggle"  data-toggle="collapse" data-target="#{{subitem.id}}" title="{{subitem.title}}">
                    <i class="fa {{subitem.class}} fa-fw fa-2x"></i>
                    <span data-ng-bind="subitem.title"></span>
                    &nbsp;<span data-ng-if="subitem.menu" class="fa fa-caret-down fa-2x pull-right"></span>
                </a>
            </li>
        </ul>
    </li>
 </ul>


If we look at our implementation, we can see that our view have the nested HTML mark-up rendering the same model properties on the same HTML document structure. This may not be a problem if the levels on the JSON model are just two levels deep, but the moment we need to support more levels, the view becomes unmanageable as we need to duplicate more mark-up as shown on the example below:



<ul class="nav" style="width:200px" data-ng-controller="app.ctrl.dev as ctrl">
    <li data-ng-repeat="item in ctrl.menu">
        <a href="{{item.url}}" class="dropdown-toggle" data-toggle="collapse" title="{{item.title}}" data-target="#{{item.id}}">
            <i class="fa fa-fw fa-2x {{item.class}}"></i> <span class="nav-header-primary" data-ng-bind="item.title"></span>
            &nbsp;<span data-ng-if="item.menu" class="fa fa-caret-down fa-2x pull-right"></span>
        </a>
        <ul class="nav collapse" data-ng-if="item.menu" id="{{item.id}}">
            <li data-ng-repeat="subitem in item.menu" class="collapsed active">
                <a href="{{subitem.url}}" class="dropdown-toggle"  data-toggle="collapse" data-target="#{{subitem.id}}" title="{{subitem.title}}">
                    <i class="fa {{subitem.class}} fa-fw fa-2x"></i>
                    <span data-ng-bind="subitem.title"></span>
                    &nbsp;<span data-ng-if="subitem.menu" class="fa fa-caret-down fa-2x pull-right"></span>
                </a>
                <ul class="nav collapse" data-ng-if="subitem.menu" id="{{subitem.id}}">
                    <li data-ng-repeat="item3 in subitem.menu">
                        <a href="{{item3.url}}" title="{{item3.title}}">
                            <i class="fa {{item3.class}} fa-fw fa-2x"></i>
                            <span data-ng-bind="item3.title"></span>
                        </a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
   </ul>



In the example above, we can continue to nest more mark-up, but this eventually becomes unreadably, and it is still limited to the number of segments/levels that we implement on the view. If the model has a deeper level, our view does not account for that. We need to look for a dynamic way to handle these cases.

Recursive Views:

Luckily for us AngularJS let us include content into our app with the use of a directive.  The ngInclude directive can be used to recursively include the HTML mark-up as a template as we iterate thru the different levels. Let’s modify our mark-up to demonstrate this:

Entry Point:


<nav class="navbar" style="width:200px">
    <ul class="nav">
        <li data-ng-repeat="item in ctrl.menu" class="collapse" ng-init="level=1" ng-include="'recursiveView'">
        </li>              
    </ul>
</nav>



In our view, we first create the entry point to include a template into our content. We do this by adding the ng-include directive to load a template while we read the elements on the menu array using ngRepeat which is the step that allows us to create the item scope context that is used on the template.

The Recursive Template:


<script type="text/ng-template" id="recursiveView">
<a href="{{item.url}}" class="dropdown-toggle" data-toggle="collapse" title="{{item.title}}" data-target="#nav{{item.id}}">
    <i class="fa fa-fw fa-2x {{item.class}}"></i> <span class="nav-header-primary" ng-bind="item.title"></span>
    &nbsp;<span ng-if="item.menu" class="fa fa-caret-down fa-2x pull-right"></span>
</a>
<ul class="nav collapse" style="margin-left:{{level}}0px" data-ng-if="item.menu" id="nav{{item.id}}">
    <li ng-repeat="subitem in item.menu" data-ng-init="level=level+1;item=subitem" ng-include="'recursiveView'">
    </li>
</ul>      
</script> 



 Within the template itself, the item object properties are used to render the information. We also load the template again using the include directive while reading the item menu property. This enables us to iterate the nested model and inject the template as we navigate through the different levels recursively.

The solution supports n nested levels without duplicating the markup. A few key items to notice using this strategy are the following:

1 – Initialize the level scope variable: This enables to track the levels and add some padding by using an inline style markup.  We do not want to set a class name here since we want to support multiple levels dynamically.

2- Item as a scope variable: Notice how at the start we use ngRepeat directive and set the item scope variable. On the nested level, we use the subitem scope variable to iterate the item.menu array.  We need to use different scope variable names to prevent resetting the item scope context. However when we include the template again recursively, the subitem scope context is passed. Obviously, the view is expecting an item scope variable name instead of subitem.  To overcome this, we use the ngInit directive to set the item scope context to the subitem array. At this point, we no longer need the previous context, and we can continue to render the nested levels.

Once we have accounted for the scope variable problem, our recursive view should work properly. 
This can be seen in action on the following demo:

DEMO



As we can see, we now have support for multiple levels without having to duplicate all the HTML mark-up.

Our next step is to show this approach using AngularJS 2. Stay tune for that.

Originally published by ozkary.com

4/8/17

SharePoint Gantt Chart Hidden with Bootstrap Master Page


SharePoint provides a Gantt chart web part that allows small teams to manage their projects. When using the default master pages, the web part renders with no problem.  In the cases when a custom Bootstrap master page is used, the right side panel of the Gantt grid does not display properly as shown on the image below:


By taking a look at the problem, we notice that Bootstrap uses the following CSS rule:


* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}


This causes the chart to not display properly because there is a CSS rule on the Gantt chart that sets a border on the date header. We can key on that element rule to override the Bootstrap style by adding the following to our custom CSS file that is loaded from the master page.


/*find inline style with the border rule at the end. */
div[style$="border: 1px solid rgb(171, 171, 171);"]
{
    -webkit-box-sizing: content-box;
    -moz-box-sizing: content-box;
    box-sizing: content-box;
}


We want to override the rule just for that specific element and not affect other layout elements.  We have to use this selector because the server side controllers create dynamic ids on the elements, and we want to prevent this problem in any page where this web part is used.

The solution was to find inline styles set with a border to use a box-sizing content-box instead of border-box. This prevents the hidden behavior on the Gantt chart. After the change, our page should look like this:


Hope you can now see the chart.

Originally published by ozkary.com