Thursday, April 17, 2014

Building apps for SharePoint with MVC – Part 2

In my previous post we built a provider-hosted app with MVC to display items from a Product list. We also used bootstrap to quickly style our app web page.
Lets take our sample to the next level – let us add the UI to add a new product item.

‘Add New’ Modal Dialog

Open our sample and navigate to Home\Index view.
Add the following code after the table:
<!-- Button trigger modal -->
<a data-toggle="modal" href="#myModal" class="btn btn-primary btn-large">Add Product</a>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">

            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title">New Product</h4>
            </div>

            <div class="modal-body">
                <form class="form-horizontal well">
                    <fieldset>
                        <div class="form-group">
                            <label for="productTitle">Title</label>
                            <input type="text" class="form-control" id="productTitle" placeholder="Enter product title">
                        </div>
                        <div class="form-group">
                            <label for="productDescription">Description</label>
                            <input type="text" class="form-control" id="productDescription" placeholder="Enter product description">
                        </div>
                        <div class="form-group">
                            <label for="productPrice">Price</label>
                            <input type="text" class="form-control" id="productPrice" placeholder="Enter product price">
                        </div>
                    </fieldset>
                </form>
            </div>

            <div class="modal-footer">                            
                <button id="btnClose" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button id="btnSaveProduct" type="button" class="btn btn-primary">Save</button>
            </div>

        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
The code adds a modal form using bootstrap – clicking the button will open a modal dialog form with the required labels and text fields
Now lets add the JS code to call the required action method to add a new product.
You can include your own .js file, but to keep things simple for the sample, let us add the JS code in the MVC ‘scripts’ section.
Add the following code at the end of the file:
@section scripts {
    <script type="text/javascript">


    $(document).ready(function () {

        $("#btnSaveProduct").click(function (e) {
            e.preventDefault();

            var spHostUrl = getSPHostUrlFromQueryString(window.location.search);

            var urlAddProduct = "/Home/AddProduct?SPHostUrl=" + spHostUrl;

            $.post(urlAddProduct,
                    {
                        title: $("#productTitle").val(),
                        description: $("#productDescription").val(),
                        price: $("#productPrice").val(),
                    }).done(function () {
                        $("#myModal").modal('hide');
                    })
                    .fail(function () {
                        alert("Failed to add the new product!");
                    });
        });

        // Gets SPHostUrl from the given query string.
        function getSPHostUrlFromQueryString(queryString) {
            if (queryString) {
                if (queryString[0] === "?") {
                    queryString = queryString.substring(1);
                }

                var keyValuePairArray = queryString.split("&");

                for (var i = 0; i < keyValuePairArray.length; i++) {
                    var currentKeyValuePair = keyValuePairArray[i].split("=");

                    if (currentKeyValuePair.length > 1 && currentKeyValuePair[0] == "SPHostUrl") {
                        return currentKeyValuePair[1];
                    }
                }
            }

            return null;
        }

    });

    </script>
}
Things to note here:
  • We append the action URL with SPHostUrl. This is very important as the remote web application needs at least the SharePoint host web URL to create the context.
  • SharePointContextFilter class will take care of creating the context as long as the URL as SPHostUrl, so you don’t have to worry about creating the context.
  • We get the SPHostUrl from the query string. Since your app was initially redirected from SharePoint, SharePoint adds the standard tokens which includes SPHostUrl.
    • You can find the method in Scripts\spcontext.js
  • We are still in the Home\Index view and haven’t created a separate view, instead just use a modal form to add a new product.

Home Controller – AddProduct Action Method

[HttpPost]
[SharePointContextFilter]
public ActionResult AddProduct(string title,string description,string price)
{
    HttpStatusCodeResult httpCode = new HttpStatusCodeResult(HttpStatusCode.MethodNotAllowed);

    var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);

    Product newProduct = new Product();
    newProduct.Title = title;
    newProduct.Description = description;
    newProduct.Price = price;

    if (SharePointService.AddProduct(spContext, newProduct))
    {
        httpCode = new HttpStatusCodeResult(HttpStatusCode.Created);
    }

    return httpCode;
}
As you can see, we add the SharePointContextFilter attribute to the action. This will ensure a proper SharePoint context is created.
For the sake of this sample, we just return HTTP status code.

SharePoint Service – Add Product

Finally we add the add product method to SharePointService that adds the new product to Products list:
public static bool AddProduct(SharePointContext spContext, Product product)
{
    using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
    {
        if (clientContext != null)
        {
            try
            {
                List lstProducts = clientContext.Web.Lists.GetByTitle("Products");

                ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                ListItem newProduct = lstProducts.AddItem(itemCreateInfo);
                newProduct["Title"] = product.Title;
                newProduct["ProductDescription"] = product.Description;
                newProduct["Price"] = product.Price;
                newProduct.Update();

                clientContext.ExecuteQuery();

                return true;
            }
            catch (ServerException ex)
            {
                return false;
            }
        }
    }

    return false;
}

Debug the app

Click the Add Product button at the bottom of the page. You will get a modal dialog. Fill out the new product information and click Save:
image
Refresh the page to see the new product added!
image

No comments:

Post a Comment