Создание собственных форм

 Комментарии можно оставлять "здесь"

Приведу пример создания собственной формы для представления (View) списка. Это может понадобиться тогда, когда стандартное отображение нужно модифицировать так, что нужны будут обработчики событий на стороне сервера. 
Приведу пример: необходимо создать фильтр по дате на странице представления.

1. В проекте создадим определение списка

2. Описание шаблона (Elements.xml) редактируете на свое усмотрение. Будьте осторожны с изменение свойства "Name" - его просто так меня нельзя (требуются дополнительные изменения в проекте)

3.  Опишем схему (Schema.xml)
<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="Журнал" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/Booking" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/"  EnableContentTypes="True" VersioningEnabled="True" >
  <MetaData>
    <ContentTypes>
      <ContentType ID="0x010070ad5df37c5746a9b0a23e5a59e6bdd5" Name="Карточка"  Description="Карточка" Version="1">
        <FieldRefs>
          <FieldRef ID="{9889F6B7-74AB-48B3-902A-F18A6203522E}" />
          <FieldRef ID="{A7E3B899-CDB0-415F-B82E-329A702E5D54}" />
        </FieldRefs>
        <XmlDocuments>
          <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
            <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
            </FormUrls>
          </XmlDocument>
        </XmlDocuments>
      </ContentType>
    </ContentTypes>
    <Fields>
      <Field Type="Choice" DisplayName="Пол" ID="{9889F6B7-74AB-48B3-902A-F18A6203522E}" StaticName="sex" Name="sex" Format="Dropdown" BaseType="Text" AllowDuplicateValues="false">
        <Default>Муж.</Default>
        <CHOICES>
          <CHOICE>Муж.</CHOICE>
          <CHOICE>Жен.</CHOICE>
        </CHOICES>
      </Field>
      <Field Type="DateTime" Format="DateOnly" DisplayName="Дата прибытия (план.)" ID="{A7E3B899-CDB0-415F-B82E-329A702E5D54}" StaticName="planArrive" Name="planArrive"/>
    </Fields>
    <Views>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="Фильтрация" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" ImageUrl="/_layouts/images/generic.png" Url="FilteringView.aspx" Path="FilteringView.aspx">
        <Toolbar Type="Standard" />
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="sex"></FieldRef>
          <FieldRef Name="planArrive"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name=" planArrive " Ascending="FALSE"> </FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main"/>
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main"/>
    </Forms>
  </MetaData>
</List>


Здесь одно только отличие от стандарта - в свойствах указывается имя нашей страницы для представления.

4. Создадим эту самую форму (страницу) для нашего представления.
Добавим стандартную страницу приложения. Она автоматически будет добавлена в Layouts. Наша задача её мышкой перетащить в папку определения списка.  Далее назначить ей тип развёртывания "Element File"

Разметка:
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page language="C#" AutoEventWireup="true" MasterPageFile="~masterurl/default.master"  CodeBehind="FilteringView.aspx.cs"   Inherits="blog.Layouts.blog.FilteringView"  %>

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <SharePoint:DateTimeControl runat="server" ID="dtFilter"  DateOnly="true" HoursMode24="true" Calendar="Gregorian" AutoPostBack="true"/>
    <WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main" Visible="true">
        <ZoneTemplate>
        </ZoneTemplate>
    </WebPartPages:WebPartZone>

</asp:Content>

<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
       <SharePoint:ListProperty ID="ListProperty1" Property="TitleOrFolder" runat="server"/> -
       <SharePoint:ListProperty ID="ListProperty2" Property="CurrentViewTitle" runat="server"/>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">
       <SharePoint:ListProperty ID="ListProperty3" Property="TitleBreadcrumb" runat="server"/>
       <SharePoint:UIVersionedContent ID="UIVersionedContent1" UIVersion="4" runat="server">
             <ContentTemplate>
                    <span id="Span1" class="ms-ltviewselectormenuheader" runat="server">
                           <SharePoint:ListTitleViewSelectorMenu AlignToParent="true" id="LTViewSelectorMenu" runat="server" />
                    </span>
             </ContentTemplate>
       </SharePoint:UIVersionedContent>
</asp:Content>
<asp:content ID="Content3" contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server"></asp:content>
<asp:Content ID="Content4" ContentPlaceHolderId="PlaceHolderPageImage" runat="server"></asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderId="PlaceHolderLeftActions" runat="server"></asp:Content>
<asp:Content ID="Content6" ContentPlaceHolderId ="PlaceHolderBodyLeftBorder" runat="server"></asp:Content>

Код

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
using System.Web.UI;
using Microsoft.SharePoint.WebPartPages;

namespace blog.Layouts.blog
{
    public partial class FilteringView : WebPartPage //LayoutsPageBase //
    {
        public string selDate
        {
            get { return Request.QueryString["selDate"]; }
        }

        public string formatQuery = "<OrderBy><FieldRef Name='ID'/></OrderBy>" +
                                 "<Where>" +
                                            "<Geq><FieldRef Name='planArrive'/><Value Type='DateTime'>{0}</Value></Geq>" +
                                 "</Where>";

        public string formatRow = "<TR class=\"{0}\"><TD>{1}</TD>  <TD>{2}</TD>  <TD>{3}</TD> <TD>{4}</TD> <TD>{5}</TD>  <TD>{6}</TD> <TD>{7}</TD></TR>";

        protected void Page_Init(object sender, EventArgs e)
        {
            string pKey = string.Empty;
            foreach (var key in Page.Request.Params.AllKeys)
            {
                if (key.Contains("dtFilter"))
                    pKey = key;
            }
            SPQuery q = new SPQuery();
            q.Query = string.Format(formatQuery, SPUtility.CreateISO8601DateTimeFromSystemDateTime(string.IsNullOrEmpty(pKey) ? DateTime.Now : Convert.ToDateTime(Page.Request[pKey])));
            SPContext.Current.Web.AllowUnsafeUpdates = true;
            SPContext.Current.ViewContext.View.Query = q.Query;
            SPContext.Current.ViewContext.View.Update();
            SPContext.Current.Web.AllowUnsafeUpdates = false;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                dtFilter.SelectedDate = string.IsNullOrEmpty(selDate) ? DateTime.Now : Convert.ToDateTime(selDate);
            }
        }
    }
}

 Важно: Класс должен наследоваться от WebPartPage.
В данном примере контрол с датой делает postback. При инициализации страницы считывается значение  даты, модифицируется query у представления. 


Далее попробуем создать собственную форму для отображения (DisplayForm), редактирования (EditForm) и добавления (NewForm) элементов списка. Возможны два способа: 1. В свойствах конкретного типа контента указать URL формы, которая например размещена нами в _layouts-е. 2. У всего списка указать имя формы.


1. Своя форма просмотра, редактирования и создания элементов определённо типа контента. Исполняются файлы проекта предыдущего примера

а) Добавим в проект страницу приложения MyCTForm.aspx. Пусть её размещение будет "/_Layouts/blog/MyCTForm.aspx"

б) В схему списка добавим (Schema.xml):

<FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
<Display>_Layouts/blog/MyCTForm.aspx?mode=show</Display>
<New>_Layouts/blog/MyCTForm.aspx?mode=new</New>

<Edit>_Layouts/blog/MyCTForm.aspx?mode=edit</Edit>
</FormUrls>

в) Разметка нашей формы
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyCTForm.aspx.cs" Inherits="blog.Layouts.MyCTForm" %>

<html  xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>Карточка</title>
    </head>
    <body>
        <form id="Form1" runat="server">
            <asp:ScriptManager id="ScriptManager" runat="server" EnablePageMethods="false" EnablePartialRendering="true" EnableScriptGlobalization="false" EnableScriptLocalization="true" />
            <SharePoint:FormDigest ID="FormDigest1" runat="server"/>
            Title: <SharePoint:TextField ID="title" runat="server" FieldName="Title" ControlMode="Display" /> <br />
            <asp:Button runat="server" ID="btSaveCard" Text="Сохранить" OnClick="SaveCard_Click"/>

<input type="button" name="diidIOSaveItem" value="Сохранить 2" onclick="if (!PreSaveItem()) return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('diidIOSaveItem', '', true, '', '', false, true));window.frameElement.commitPopup();" id="diidIOSaveItem" accesskey="O" class="ms-ButtonHeightWidth" target="_self">
            <input type="button" name="diidIOGoBack" value="Отмена" onclick="window.frameElement.cancelPopUp();return false;WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('diidIOGoBack', '', true, '', '', false, true))" id="diidIOGoBack" accesskey="C" class="ms-ButtonHeightWidth" target="_self">

        </form>
    </body>

</html>

Кнопка "Сохранить" - если нужно нестандартно обработать сохранение, если сохраняем в codebehind.
Кнопка "Сохранить 2" - стандартное сохранение значений.

г) CodeBehind нашей формы

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace blog.Layouts
{
    public partial class MyCTForm : LayoutsPageBase
    {
        public string formMode
        {
            get { return Request.QueryString["Mode"]; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                switch (formMode)
                {
                    case "new":
                        title.ControlMode = SPControlMode.New;
                        break;
                    case "edit":
                        title.ControlMode = SPControlMode.Edit;
                        break;
                    default:
                        break;
                }
            }
        }

        protected void SaveCard_Click(object sender, EventArgs e)
        {
// наше сохранение, код
            Context.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");
            Context.Response.Flush();
            Context.Response.End();
        }
    }
}


д) Развёртываем, проверяем создать наш тип контента


2.  Форма применяется для всего списка.

а. Добавим форму ItemForm.aspx аналогично добавлению формы представления, описанного в этой же статье выше

Вот разметка формы:
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ItemForm.aspx.cs" Inherits="blog.Layouts.blog.ItemForm" MasterPageFile="~masterurl/default.master" %>
 <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">

</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
           <WebPartPages:WebPartZone runat="server" FrameType="None" ID="WebPartZone" Title="loc:Main">
            <ZoneTemplate>
            </ZoneTemplate>
        </WebPartPages:WebPartZone>

</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
   
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >

</asp:Content>


  Зона веб-частей обязательна, т.к. туда будет добавляться представление списка.
 CodeBehind здесь необязателен, используйте его при необходимости, когда нужна дополнительная логика и компоненты.

б. Добавим в сопоставленную парку файл "CONTROLTEMPLATES" файл MyTemplates.ascx
<%@ Control Language="C#"   AutoEventWireup="false" %>
<%@Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.WebControls"%>
<%@Register TagPrefix="ApplicationPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.ApplicationPages.WebControls"%>
<%@Register TagPrefix="SPHttpUtility" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.Utilities"%>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" src="~/_controltemplates/ToolBarButton.ascx" %>
<%@ Register Tagprefix="my" Namespace="Iterator" Assembly="$SharePoint.Project.AssemblyFullName$" %>

<SharePoint:RenderingTemplate id="NewItemListForm" runat="server">
       <Template>
             <SharePoint:FormToolBar ID="FormToolBar1" runat="server" >
            <CustomTemplate>
                <SharePoint:EditItemButton ID="EditItemButton" runat="server" />
                <SharePoint:DeleteItemButton ID="DeleteItemButton" runat="server"  />
                <SharePoint:ManagePermissionsButton ID="btnId" runat="server" Visible="false" />
                <SharePoint:AlertMeButton ID="AlertMeButton1" runat="server" Visible="false" />
            </CustomTemplate>
        </SharePoint:FormToolBar>
        <table border="0">
            <my:FieldIterator ID="ListFieldIterator1" runat="server"/>
        </table>

        <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator="&amp;#160;" runat="server">
                                  <Template_RightButtons>
                                        <SharePoint:SaveButton ID="SaveButton1" runat="server"/>
                                        <SharePoint:GoBackButton ID="GoBackButton1" runat="server"/>
                                  </Template_RightButtons>
                    </wssuc:ToolBar>
       </Template>
</SharePoint:RenderingTemplate>


в. Добавим класс Iterator.cs, который будет отвечать за прорисовку (расположение и доступность) полей элемента.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using Microsoft.SharePoint;

namespace Iterator
{
    public class FieldIterator : ListFieldIterator
    {
        protected override void Render(HtmlTextWriter output)
        {
            foreach (BaseFieldControl fieldControl in SPContext.Current.FormContext.FieldControlCollection)
            {
                if (fieldControl.Field == null)
                    continue;

                fieldControl.Visible = false;

                if (!this.IsFieldExcluded(fieldControl.Field))
                {
                    output.AddAttribute("id", "field" + fieldControl.FieldName);
                    output.RenderBeginTag(HtmlTextWriterTag.Tr);
                    output.Indent++;
                    fieldControl.Visible = true;
                    output.Write("<td>" + fieldControl.Field + "</td><td style=\"width:200px;margin:5px;\">");
                    fieldControl.RenderControl(output);
                    output.Write("</td>");
                    output.Indent++;
                    output.RenderEndTag();
                }
            }
        }
    }
}

г. Отредактируем схему (Schema.xml) 

 <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main"/>
      <Form Type="NewForm" Template="NewItemListForm" U="" Url="ItemForm.aspx" Path="ItemForm.aspx" WebPartZoneID="Main" />
    </Forms>

Есть следующие моменты:

1. Стоит перезапустить IIS, чтобы подгрузился наш шаблон NewItemListForm.
2. Для форм просмотра и редактирования всё делается аналогично.
3. Если не  требуется в форме специальной логики и интерфейса, то достаточно использовать только итератор (Iterator) без отдельной формы: 
<Form Type="NewForm" Template="NewItemListForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
4.Если указана форма для типа контента, то она приоритетнее, чем для всего списка.



 Комментарии можно оставлять "здесь"

Комментариев нет:

Яндекс.Метрика