Creación de un formulario Sharepoint personalizado usando Angular y Office UI Fabric

Formulario sharepoinr y oficce fabric

Creación de un formulario Sharepoint personalizado usando Angular y Office UI Fabric

 

La creación y personalización de un formulario interactivo en SharePoint puede convertirse en una labor compleja. Una forma fácil para afrontar esta tarea es mediante el uso de AngularJS y Office UI Fabric.

Hoy vamos a mostrar cómo realizar un formulario de alta de un empleado usando Angular 1.5, Office UI Fabric y SharePoint API REST.

¿Qué es AngularJS?

AngularJS es un framework MVC de código abierto desarrollado por Google y escrito en Javascript, que trabaja del lado del cliente (client-side) y nos permite hacer más dinámica nuestra aplicación web, trabajando de la mano con otras tecnologías como HTML y CSS, así como librerías de terceros.

El equipo de AngularJS lo define como: “un framework estructural para páginas web dinámicas”.

¿Qué es Office UI Fabric?

Se trata de un framework para desarrollo Front-End, responsivo y mobile-first que permite crear interfaces de usuario con el aspecto Office y SharePoint. Con Fabric puede:

  • Estandarizar patrones de IU en código, mediante HTML, CSS, temas, iconografía y patrones comunes.
  • Aplicar un conjunto común de estilos a complementos que desarrolle para todos los productos y plataformas.
  • Crear experiencias con apariencia de ser parte de Office.

 

Preparando el escenario

Tenemos una lista personalizada llamada Empleados que es rellenada por el personal de Recursos Humanos. En la siguiente captura podemos ver la estructura de columnas que contiene la misma.

formulario sharepoint 1

Ahora llega el momento de descargar los scripts que vamos a usar en nuestra aplicación:

Dentro de la carpeta ‘Activos del Sitio’ crearemos una carpeta llamada ‘FichaEmpleados’, donde guardaremos todos los archivos de la aplicación que vamos a usar:

formulario sharepoint 2

 

Miguel 3

 

Creamos el formulario

Creamos la plantilla html del formulario FichaEmpleado.html

 

<div ng-controller=”empleadoCtrll” class=”ms-Grid”>

<h1>Alta Empleado</h1>

<br>

<div>

<div>

<!– Message bar component –>

<uif-message-bar>

<uif-content>

<h4>Instrucciones:</h4>

Por favor informe todos los campos del formulario.</p>

</uif-content>

</uif-message-bar>

</div>

</div>

<br>

 

<div class=”ms-Grid-row ms-Grid”>

<h3 class=”section-divider”><uif-icon uif-type=”circleInfo”></uif-icon> Recursos Humanos</h3>

<div class=”ms-Grid-col ms-u-sm6 ms-u-md6 ms-u-lg6″>

 

<!– Textbox component –>

<uif-textfield uif-label=”Nombre” ng-model=”empleado.Nombre”></uif-textfield>

 

<!– Textbox component –>

<uif-textfield uif-label=”Apellidos” ng-model=”empleado.Apellidos”></uif-textfield>

 

<!– Textbox component –>

<uif-textfield uif-label=”DNI” ng-model=”empleado.DNI”></uif-textfield>

 

<!– Textbox component –>

<uif-textfield uif-label=”N&uacute;mero Seguridad Social” ng-model=”empleado.NumSeguridadSocial”></uif-textfield>

 

<!– Date picker component–>

<uif-label>Fecha de Nacimiento</uif-label>

<uif-datepicker ng-model=”empleado.FechaNacimiento”></uif-datepicker>

 

<!– Textbox component –>

<uif-textfield uif-label=”Tel&eacute;fono” ng-model=”empleado.Telefono”></uif-textfield>

</div>

<div class=”ms-Grid-col ms-u-sm6 ms-u-md6 ms-u-lg6″>

 

<!– Dropdown component –>

<uif-label>Tipo de Contrato</uif-label>

<uif-dropdown ng-model=”empleado.TipoContrato”>

<uif-dropdown-option value=”{{key}}” ng-repeat=”(key, value) in Contratos” title=”{{value}}“>{{value}}</uif-dropdown-option>

</uif-dropdown>

 

<!– Dropdown component –>

<uif-label>Tipo de Jornada</uif-label>

<uif-dropdown ng-model=”empleado.TipoJornada”>

<uif-dropdown-option value=”{{key}}” ng-repeat=”(key, value) in TipoJornadas” title=”{{value}}“>{{value}}</uif-dropdown-option>

</uif-dropdown>

 

<!– Date picker component–>

<uif-label>Fecha de Incorporaci&oacute;n</uif-label>

<uif-datepicker ng-model=”empleado.FechaIncorporacion”></uif-datepicker>

 

<!– Dropdown component –>

<uif-label>Departamento</uif-label>

<uif-dropdown ng-model=”empleado.Departamento”>

<uif-dropdown-option value=”{{key}}” ng-repeat=”(key, value) in Departamentos” title=”{{value}}“>{{value}}</uif-dropdown-option>

</uif-dropdown>

 

<!– Textbox component –>

<uif-textfield uif-label=”Puesto Desempe&ntilde;o” ng-model=”empleado.Puesto”></uif-textfield>

 

<!– Peoplepicker component –>

<uif-label>Responsable</uif-label>

<uif-people-picker uif-people=”getResponsable” ng-model=”empleado.Responsable” uif-type=”compact”

uif-selected-person-click=”personClicked” data-ng-click=”getSelectedUserId(empleado)” uif-search-delay=”300″ placeholder=”Buscar responsable”>

<uif-people-search-more>

<uif-secondary-text>Showing {{asyncResultadoResponsable.length}} results</uif-secondary-text>

<uif-primary-text uif-search-for-text=”Estas buscando por: “>Buscar personal de empresa</uif-primary-text>

</uif-people-search-more>

</uif-people-picker>

</div>

<div class=”ms-Grid-col ms-u-sm12 ms-u-md12 ms-u-lg12″>

<!– Textbox component –>

<uif-textfield uif-label=”Direcci&oacute;n” ng-model=”empleado.Direccion”></uif-textfield>

 

<!– Text area component –>

<uif-textfield ng-model=”empleado.Comentarios” uif-label=”Comentarios” uif-multiline=”true”></uif-textfield>

</div>

<div class=”ms-Grid-col ms-u-sm12 ms-u-md12 ms-u-lg12 taRight”>

<!– Primary button components–>

<uif-button type=”button” data-ng-click=”crearEmpleado(empleado)” uif-type=”primary”>Grabar</uif-button>

<uif-button type=”button” data-ng-click=”cancel()” uif-type=”command”>Cancelar</uif-button>

</div>

</div>

</div>

 

<!– jQuery –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/jquery.min.js”></script>

 

<!– PickerJS –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/picker.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/picker.date.js”></script>

 

<!– Angular y ngOfficeUiFabric –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/angular.min.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/ngOfficeUiFabric.min.js”></script>

 

<!— Fichero de la aplicación –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/controllers.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/services.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/app.js”></script>

 

</div>

 

 

En la etiqueta <div> que contiene la plantilla se indica el controlador al que pertenece esta vista, ng-controller=”empleadoCtrll”. Mediante la directiva ng-model enlazamos los datos de la aplicación a cada uno de los elementos HTML.

Aquí http://ngofficeuifabric.com/demos/ podemos encontrar ejemplos de cada uno de los componentes de Office UI Fabric.

 

App.js

El siguiente código es el punto de entrada de nuestra aplicación. Primero creamos un módulo. Luego, utilizando la inyección de dependencia, añadimos las referencias a nuestros servicios, controladores y los módulos officeuifabric.core y officeuifabric.component.

 

var app = new angular.module(‘app’, [

‘app.services’,

‘app.controllers’,

‘officeuifabric.core’,

‘officeuifabric.components’

]);

 

 

Service.js

 

angular.module(‘app.services’, [])

 

.factory(‘EmpleadoFactory’, function ($q, $http) {

var webUrl = _spPageContextInfo.webAbsoluteUrl + “/_api/”;

var factory = {};

 

factory.getUserId = function (UserName) {

var deferred = $q.defer();

 

$http({

url: webUrl + “web/siteusers(@v)?@v='” + encodeURIComponent(UserName) + “‘”,

method: “GET”,

headers: {

“accept”: “application/json;odata=verbose”

}

})

.success(function (result) {

deferred.resolve(result);

})

.error(function (result, status) {

deferred.reject(status);

});

 

return deferred.promise;

};

 

factory.searchPeople = function (request) {

var deferred = $q.defer();

 

$http({

url: webUrl + “SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser”,

method: “POST”,

data: JSON.stringify({

‘queryParams’: {

‘__metadata’: { ‘type’: ‘SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters’ },

‘AllowEmailAddresses’: true,

‘AllowMultipleEntities’: false,

‘AllUrlZones’: false,

‘MaximumEntitySuggestions’: 50,

‘PrincipalSource’: 15,

‘PrincipalType’: 1,

‘QueryString’: request

}

}),

headers: {

“accept”: “application/json;odata=verbose”,

‘content-type’: ‘application/json;odata=verbose’,

‘X-RequestDigest’: document.getElementById(‘__REQUESTDIGEST’).value

}

})

.success(function (result) {

var data = JSON.parse(result.d.ClientPeoplePickerSearchUser);

var formattedPeople = [];

var topResultsGroup = { name: “Top Results”, order: 0 };

 

if (data.length > 0) {

angular.forEach(data, function (value, key) {

var name = value.DisplayText;

var userInitials = name.match(/\b\w/g) || [];

userInitials = ((userInitials.shift() || ”) + (userInitials.pop() || ”)).toUpperCase();

 

formattedPeople.push({

initials: userInitials,

primaryText: name,

secondaryText: value.EntityData.Department,

presence: ‘available’,

group: topResultsGroup,

color: ‘blue’,

id: value.Key

});

});

 

deferred.resolve(formattedPeople);

}

 

})

.error(function (result, status) {

 

deferred.reject(status);

alert(“Código Estado: ” + status);

});

 

return deferred.promise;

};

 

factory.createRequest = function (data) {

var deferred = $q.defer();

var createRequestURL = webUrl + “web/lists/GetByTitle(‘Empleados’)/items”;

$http({

url: createRequestURL,

method: “POST”,

headers: {

“accept”: “application/json;odata=verbose”,

“X-RequestDigest”: document.getElementById(“__REQUESTDIGEST”).value,

“content-Type”: “application/json;odata=verbose”

},

data: JSON.stringify(data)

})

.success(function (result) {

deferred.resolve(result);

history.go(-1);

})

.error(function (result, status) {

deferred.reject(status);

alert(“Código Estado: ” + status);

});

return deferred.promise;

};

 

return factory;

});

 

 

El código del servicio tiene las siguientes características:

  • Hay una dependencia de $q. Este servicio garantiza que las funciones se ejecuten de forma asíncrona y utilizar sus valores de retorno cuando se ha completado el procesamiento.
  • El código utiliza _spPageContextInfo.webAbsoluteUrl que representa la URL absoluta para el sitio de SharePoint donde se encuentra la aplicación
  • La función searchPeople () se utiliza para consultar los datos de usuario del control de selector de personas. Utiliza el _api / SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser .
  • Los datos devueltos por searchPeople () son una cadena. Utilice JSON.parse para convertir los datos de la respuesta en una matriz de objetos JSON.
  • La función getUserId () se utiliza para recuperar el identificador de usuario para el usuario que está seleccionado en el control de selector de personas del formulario. Se requiere del ID de usuario para guardar el usuario en el campo Responsable, de la lista de Empleados.
  • La función createRequest () se utiliza para crear un nuevo registro en la lista de Empleados.

Controller.js

 

angular.module(‘app.controllers’, [])

 

.controller(’empleadoCtrll’, function ($scope, $q, $timeout, EmpleadoFactory) {

init();

 

function init() {

 

//Definición de los valores para los desplegables

$scope.Departamentos = {

‘Comercial’: ‘Comercial’,

‘RRHH’: ‘RRHH’,

‘Financiero’: ‘Financiero’,

‘IT’: ‘IT’,

‘Gerencia’: ‘Gerencia’

};

 

$scope.Contratos = {

‘Indefinido’: ‘Indefinido’,

‘Temporale’: ‘Temporal’,

‘Formativo’: ‘Formativo’,

‘Contrato en prácticas’: ‘Contrato en prácticas’,

‘A tiempo parcial’: ‘A tiempo parcial’

};

 

$scope.TipoJornadas = {

‘Tiempo Completo’: ‘Tiempo Completo’,

‘Tiempo Parcial’: ‘Tiempo Parcial’,

‘Parcial por hora’: ‘Parcial por hora’

};

 

$scope.empleado = {

Nombre: ”,

Apellidos: ”,

DNI: ”,

NumSeguridadSocial: ”,

FechaNacimiento: new Date().toISOString(),

Telefono: ”,

Direccion: ”,

TipoContrato: ”,

TipoJornada: ”,

FechaIncorporacion: new Date().toISOString(),

Departamento: ”,

Puesto: ”,

ResponsableId: null,

Responsable: [],

Comentarios: ”,

__metadata: { ‘type’: ‘SP.Data.EmpleadosListItem’ }

};

 

}

 

var asyncResponsable = [];

 

var getPeople = function (people, searchQuery) {

if (!searchQuery) {

return [];

}

 

console.log(“Buscar por ” + searchQuery);

return people;

}

 

//Se encuentra el id de usuario cuando un usuario es seleccionado en el peoplepicker

$scope.getSelectedUserId = function (data) {

 

//Asignación del id del usuario responsable

var ResponsableId = data.Responsable[0].id;

 

EmpleadoFactory.getUserId(ResponsableId).then(function (results) {

data.ResponsableId = results.d.Id;

console.log(results.d.Id);

 

ResponsableId = null;

});

}

 

//Búsqueda de usuarios

$scope.getResponsable = function (query) {

if (query !== undefined) {

var deferred = $q.defer();

 

EmpleadoFactory.searchPeople(query).then(function (results) {

 

asyncResponsable = JSON.parse(JSON.stringify(results));

 

$scope.asyncResultadoResponsable = getPeople(asyncResponsable, query);

 

if (!$scope.asyncResultadoResponsable || $scope.asyncResultadoResponsable.length === 0) {

 

return $scope.asyncResultadoResponsable;

 

}

 

deferred.resolve($scope.asyncResultadoResponsable);

 

});

 

return deferred.promise;

}

}

 

//Alta de un nuevo empleado

$scope.crearEmpleado = function (data) {

delete data.Responsable;

console.log(data);

EmpleadoFactory.createRequest(data).then(function (results) {

return results;

});

};

 

//Cancela el formulario y regresa al formulario anterior

$scope.cancel = function () {

history.go(-1);

};

});

 

 

El código del controlador tiene las siguientes características:

  • Declara los arrays Departamentos, Contratos y TipoJornadas. Estos se utilizarán para cargar los diferentes desplegables del formulario.
  • La función getSelectedUserId () a la función getUserId () de la factoria. Esta función se llama en ell ng-click de la directiva del people picker del responsable.
  • La función submitRequest () se utiliza para crear un nuevo empleado en la lista. Una vez que la solicitud finaliza se re direcciona a la página anterior.

Creación del formulario

Para utilizar el formulario de alta creado, debemos ir a la lista Empleados y en la pestaña Lista de la Ribbon , en la opción “Elementos web de formulario”, seleccionar “Formulario nuevo predeterminado”.

A continuación, agregamos un editor de contenido al aspx.

En la propiedad “Vínculo de contenido” del Editor de Contenido, indicamos la url de nuestra plantilla, en mi caso “/sites/test/SiteAssets/FichaEmpleados/FichaEmpleado.html”, guardamos.

El formulario queda así:

 

La creación y personalización de un formulario interactivo en SharePoint puede convertirse en una labor compleja. Una forma fácil para afrontar esta tarea es mediante el uso de AngularJS y Office UI Fabric.

Hoy vamos a mostrar cómo realizar un formulario de alta de un empleado usando Angular 1.5, Office UI Fabric y SharePoint API REST.

¿Qué es AngularJS?

AngularJS es un framework MVC de código abierto desarrollado por Google y escrito en Javascript, que trabaja del lado del cliente (client-side) y nos permite hacer más dinámica nuestra aplicación web, trabajando de la mano con otras tecnologías como HTML y CSS, así como librerías de terceros.

El equipo de AngularJS lo define como: “un framework estructural para páginas web dinámicas”.

¿Qué es Office UI Fabric?

Se trata de un framework para desarrollo Front-End, responsivo y mobile-first que permite crear interfaces de usuario con el aspecto Office y SharePoint. Con Fabric puede:

  • Estandarizar patrones de IU en código, mediante HTML, CSS, temas, iconografía y patrones comunes.
  • Aplicar un conjunto común de estilos a complementos que desarrolle para todos los productos y plataformas.
  • Crear experiencias con apariencia de ser parte de Office.

 

Preparando el escenario

Tenemos una lista personalizada llamada Empleados que es rellenada por el personal de Recursos Humanos. En la siguiente captura podemos ver la estructura de columnas que contiene la misma.

 

Ahora llega el momento de descargar los scripts que vamos a usar en nuestra aplicación:

Dentro de la carpeta ‘Activos del Sitio’ crearemos una carpeta llamada ‘FichaEmpleados’, donde guardaremos todos los archivos de la aplicación que vamos a usar.

 

Creamos el formulario

Creamos la plantilla html del formulario FichaEmpleado.html

 

<div ng-controller=”empleadoCtrll” class=”ms-Grid”>

<h1>Alta Empleado</h1>

<br>

<div>

<div>

<!– Message bar component –>

<uif-message-bar>

<uif-content>

<h4>Instrucciones:</h4>

Por favor informe todos los campos del formulario.</p>

</uif-content>

</uif-message-bar>

</div>

</div>

<br>

 

<div class=”ms-Grid-row ms-Grid”>

<h3 class=”section-divider”><uif-icon uif-type=”circleInfo”></uif-icon> Recursos Humanos</h3>

<div class=”ms-Grid-col ms-u-sm6 ms-u-md6 ms-u-lg6″>

 

<!– Textbox component –>

<uif-textfield uif-label=”Nombre” ng-model=”empleado.Nombre”></uif-textfield>

 

<!– Textbox component –>

<uif-textfield uif-label=”Apellidos” ng-model=”empleado.Apellidos”></uif-textfield>

 

<!– Textbox component –>

<uif-textfield uif-label=”DNI” ng-model=”empleado.DNI”></uif-textfield>

 

<!– Textbox component –>

<uif-textfield uif-label=”N&uacute;mero Seguridad Social” ng-model=”empleado.NumSeguridadSocial”></uif-textfield>

 

<!– Date picker component–>

<uif-label>Fecha de Nacimiento</uif-label>

<uif-datepicker ng-model=”empleado.FechaNacimiento”></uif-datepicker>

 

<!– Textbox component –>

<uif-textfield uif-label=”Tel&eacute;fono” ng-model=”empleado.Telefono”></uif-textfield>

</div>

<div class=”ms-Grid-col ms-u-sm6 ms-u-md6 ms-u-lg6″>

 

<!– Dropdown component –>

<uif-label>Tipo de Contrato</uif-label>

<uif-dropdown ng-model=”empleado.TipoContrato”>

<uif-dropdown-option value=”{{key}}” ng-repeat=”(key, value) in Contratos” title=”{{value}}“>{{value}}</uif-dropdown-option>

</uif-dropdown>

 

<!– Dropdown component –>

<uif-label>Tipo de Jornada</uif-label>

<uif-dropdown ng-model=”empleado.TipoJornada”>

<uif-dropdown-option value=”{{key}}” ng-repeat=”(key, value) in TipoJornadas” title=”{{value}}“>{{value}}</uif-dropdown-option>

</uif-dropdown>

 

<!– Date picker component–>

<uif-label>Fecha de Incorporaci&oacute;n</uif-label>

<uif-datepicker ng-model=”empleado.FechaIncorporacion”></uif-datepicker>

 

<!– Dropdown component –>

<uif-label>Departamento</uif-label>

<uif-dropdown ng-model=”empleado.Departamento”>

<uif-dropdown-option value=”{{key}}” ng-repeat=”(key, value) in Departamentos” title=”{{value}}“>{{value}}</uif-dropdown-option>

</uif-dropdown>

 

<!– Textbox component –>

<uif-textfield uif-label=”Puesto Desempe&ntilde;o” ng-model=”empleado.Puesto”></uif-textfield>

 

<!– Peoplepicker component –>

<uif-label>Responsable</uif-label>

<uif-people-picker uif-people=”getResponsable” ng-model=”empleado.Responsable” uif-type=”compact”

uif-selected-person-click=”personClicked” data-ng-click=”getSelectedUserId(empleado)” uif-search-delay=”300″ placeholder=”Buscar responsable”>

<uif-people-search-more>

<uif-secondary-text>Showing {{asyncResultadoResponsable.length}} results</uif-secondary-text>

<uif-primary-text uif-search-for-text=”Estas buscando por: “>Buscar personal de empresa</uif-primary-text>

</uif-people-search-more>

</uif-people-picker>

</div>

<div class=”ms-Grid-col ms-u-sm12 ms-u-md12 ms-u-lg12″>

<!– Textbox component –>

<uif-textfield uif-label=”Direcci&oacute;n” ng-model=”empleado.Direccion”></uif-textfield>

 

<!– Text area component –>

<uif-textfield ng-model=”empleado.Comentarios” uif-label=”Comentarios” uif-multiline=”true”></uif-textfield>

</div>

<div class=”ms-Grid-col ms-u-sm12 ms-u-md12 ms-u-lg12 taRight”>

<!– Primary button components–>

<uif-button type=”button” data-ng-click=”crearEmpleado(empleado)” uif-type=”primary”>Grabar</uif-button>

<uif-button type=”button” data-ng-click=”cancel()” uif-type=”command”>Cancelar</uif-button>

</div>

</div>

</div>

 

<!– jQuery –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/jquery.min.js”></script>

 

<!– PickerJS –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/picker.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/picker.date.js”></script>

 

<!– Angular y ngOfficeUiFabric –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/angular.min.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/scripts/ngOfficeUiFabric.min.js”></script>

 

<!— Fichero de la aplicación –>

<script src=”/sites/test/SiteAssets/FichaEmpleados/controllers.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/services.js”></script>

<script src=”/sites/test/SiteAssets/FichaEmpleados/app.js”></script>

 

</div>

 

 

En la etiqueta <div> que contiene la plantilla se indica el controlador al que pertenece esta vista, ng-controller=”empleadoCtrll”. Mediante la directiva ng-model enlazamos los datos de la aplicación a cada uno de los elementos HTML.

Aquí http://ngofficeuifabric.com/demos/ podemos encontrar ejemplos de cada uno de los componentes de Office UI Fabric.

 

App.js

El siguiente código es el punto de entrada de nuestra aplicación. Primero creamos un módulo. Luego, utilizando la inyección de dependencia, añadimos las referencias a nuestros servicios, controladores y los módulos officeuifabric.core y officeuifabric.component.

 

var app = new angular.module(‘app’, [

‘app.services’,

‘app.controllers’,

‘officeuifabric.core’,

‘officeuifabric.components’

]);

 

 

Service.js

 

angular.module(‘app.services’, [])

 

.factory(‘EmpleadoFactory’, function ($q, $http) {

var webUrl = _spPageContextInfo.webAbsoluteUrl + “/_api/”;

var factory = {};

 

factory.getUserId = function (UserName) {

var deferred = $q.defer();

 

$http({

url: webUrl + “web/siteusers(@v)?@v='” + encodeURIComponent(UserName) + “‘”,

method: “GET”,

headers: {

“accept”: “application/json;odata=verbose”

}

})

.success(function (result) {

deferred.resolve(result);

})

.error(function (result, status) {

deferred.reject(status);

});

 

return deferred.promise;

};

 

factory.searchPeople = function (request) {

var deferred = $q.defer();

 

$http({

url: webUrl + “SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser”,

method: “POST”,

data: JSON.stringify({

‘queryParams’: {

‘__metadata’: { ‘type’: ‘SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters’ },

‘AllowEmailAddresses’: true,

‘AllowMultipleEntities’: false,

‘AllUrlZones’: false,

‘MaximumEntitySuggestions’: 50,

‘PrincipalSource’: 15,

‘PrincipalType’: 1,

‘QueryString’: request

}

}),

headers: {

“accept”: “application/json;odata=verbose”,

‘content-type’: ‘application/json;odata=verbose’,

‘X-RequestDigest’: document.getElementById(‘__REQUESTDIGEST’).value

}

})

.success(function (result) {

var data = JSON.parse(result.d.ClientPeoplePickerSearchUser);

var formattedPeople = [];

var topResultsGroup = { name: “Top Results”, order: 0 };

 

if (data.length > 0) {

angular.forEach(data, function (value, key) {

var name = value.DisplayText;

var userInitials = name.match(/\b\w/g) || [];

userInitials = ((userInitials.shift() || ”) + (userInitials.pop() || ”)).toUpperCase();

 

formattedPeople.push({

initials: userInitials,

primaryText: name,

secondaryText: value.EntityData.Department,

presence: ‘available’,

group: topResultsGroup,

color: ‘blue’,

id: value.Key

});

});

 

deferred.resolve(formattedPeople);

}

 

})

.error(function (result, status) {

 

deferred.reject(status);

alert(“Código Estado: ” + status);

});

 

return deferred.promise;

};

 

factory.createRequest = function (data) {

var deferred = $q.defer();

var createRequestURL = webUrl + “web/lists/GetByTitle(‘Empleados’)/items”;

$http({

url: createRequestURL,

method: “POST”,

headers: {

“accept”: “application/json;odata=verbose”,

“X-RequestDigest”: document.getElementById(“__REQUESTDIGEST”).value,

“content-Type”: “application/json;odata=verbose”

},

data: JSON.stringify(data)

})

.success(function (result) {

deferred.resolve(result);

history.go(-1);

})

.error(function (result, status) {

deferred.reject(status);

alert(“Código Estado: ” + status);

});

return deferred.promise;

};

 

return factory;

});

 

 

El código del servicio tiene las siguientes características:

  • Hay una dependencia de $q. Este servicio garantiza que las funciones se ejecuten de forma asíncrona y utilizar sus valores de retorno cuando se ha completado el procesamiento.
  • El código utiliza _spPageContextInfo.webAbsoluteUrl que representa la URL absoluta para el sitio de SharePoint donde se encuentra la aplicación
  • La función searchPeople () se utiliza para consultar los datos de usuario del control de selector de personas. Utiliza el _api / SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser .
  • Los datos devueltos por searchPeople () son una cadena. Utilice JSON.parse para convertir los datos de la respuesta en una matriz de objetos JSON.
  • La función getUserId () se utiliza para recuperar el identificador de usuario para el usuario que está seleccionado en el control de selector de personas del formulario. Se requiere del ID de usuario para guardar el usuario en el campo Responsable, de la lista de Empleados.
  • La función createRequest () se utiliza para crear un nuevo registro en la lista de Empleados.

Controller.js

 

angular.module(‘app.controllers’, [])

 

.controller(’empleadoCtrll’, function ($scope, $q, $timeout, EmpleadoFactory) {

init();

 

function init() {

 

//Definición de los valores para los desplegables

$scope.Departamentos = {

‘Comercial’: ‘Comercial’,

‘RRHH’: ‘RRHH’,

‘Financiero’: ‘Financiero’,

‘IT’: ‘IT’,

‘Gerencia’: ‘Gerencia’

};

 

$scope.Contratos = {

‘Indefinido’: ‘Indefinido’,

‘Temporale’: ‘Temporal’,

‘Formativo’: ‘Formativo’,

‘Contrato en prácticas’: ‘Contrato en prácticas’,

‘A tiempo parcial’: ‘A tiempo parcial’

};

 

$scope.TipoJornadas = {

‘Tiempo Completo’: ‘Tiempo Completo’,

‘Tiempo Parcial’: ‘Tiempo Parcial’,

‘Parcial por hora’: ‘Parcial por hora’

};

 

$scope.empleado = {

Nombre: ”,

Apellidos: ”,

DNI: ”,

NumSeguridadSocial: ”,

FechaNacimiento: new Date().toISOString(),

Telefono: ”,

Direccion: ”,

TipoContrato: ”,

TipoJornada: ”,

FechaIncorporacion: new Date().toISOString(),

Departamento: ”,

Puesto: ”,

ResponsableId: null,

Responsable: [],

Comentarios: ”,

__metadata: { ‘type’: ‘SP.Data.EmpleadosListItem’ }

};

 

}

 

var asyncResponsable = [];

 

var getPeople = function (people, searchQuery) {

if (!searchQuery) {

return [];

}

 

console.log(“Buscar por ” + searchQuery);

return people;

}

 

//Se encuentra el id de usuario cuando un usuario es seleccionado en el peoplepicker

$scope.getSelectedUserId = function (data) {

 

//Asignación del id del usuario responsable

var ResponsableId = data.Responsable[0].id;

 

EmpleadoFactory.getUserId(ResponsableId).then(function (results) {

data.ResponsableId = results.d.Id;

console.log(results.d.Id);

 

ResponsableId = null;

});

}

 

//Búsqueda de usuarios

$scope.getResponsable = function (query) {

if (query !== undefined) {

var deferred = $q.defer();

 

EmpleadoFactory.searchPeople(query).then(function (results) {

 

asyncResponsable = JSON.parse(JSON.stringify(results));

 

$scope.asyncResultadoResponsable = getPeople(asyncResponsable, query);

 

if (!$scope.asyncResultadoResponsable || $scope.asyncResultadoResponsable.length === 0) {

 

return $scope.asyncResultadoResponsable;

 

}

 

deferred.resolve($scope.asyncResultadoResponsable);

 

});

 

return deferred.promise;

}

}

 

//Alta de un nuevo empleado

$scope.crearEmpleado = function (data) {

delete data.Responsable;

console.log(data);

EmpleadoFactory.createRequest(data).then(function (results) {

return results;

});

};

 

//Cancela el formulario y regresa al formulario anterior

$scope.cancel = function () {

history.go(-1);

};

});

 

 

El código del controlador tiene las siguientes características:

  • Declara los arrays Departamentos, Contratos y TipoJornadas. Estos se utilizarán para cargar los diferentes desplegables del formulario.
  • La función getSelectedUserId () a la función getUserId () de la factoria. Esta función se llama en ell ng-click de la directiva del people picker del responsable.
  • La función submitRequest () se utiliza para crear un nuevo empleado en la lista. Una vez que la solicitud finaliza se re direcciona a la página anterior.

Creación del formulario

Para utilizar el formulario de alta creado, debemos ir a la lista Empleados y en la pestaña Lista de la Ribbon , en la opción “Elementos web de formulario”, seleccionar “Formulario nuevo predeterminado”.

creación formulario sharepoint

A continuación, agregamos un editor de contenido al aspx.

formulario sharepoint

En la propiedad “Vínculo de contenido” del Editor de Contenido, indicamos la url de nuestra plantilla, en mi caso “/sites/test/SiteAssets/FichaEmpleados/FichaEmpleado.html”, guardamos.

El formulario queda así:

formulario sharepoint

formulario sharepoint

 

Artículo escrito por Miguel Ortiz Jiménez programador en MVP Cluster