Category Archives: Desenvolvimento do SharePoint

Cuidado com alterações recentes no ItemStyle

Eu estava trabalhando com ItemStyle para personalizar a aparência de um Content Query Web Part e o direito sobre a hora do almoço, Eu fiz uma quebra de alterar para o xsl. Não percebi, Mas desta vez tiveram efeitos em todo o conjunto de sites de grande envergadura. Saí para almoçar e após o meu regresso, Notei essa mensagem que aparece em um monte de lugares:

Não é possível exibir esta Web Part. Para solucionar o problema, abrir esta página da Web em um editor de HTML compatível com o Windows SharePoint Services, como o Microsoft Office SharePoint Designer. Se o problema persistir, Contate o administrador do servidor Web.

Eu culpei o cliente (sem perceber, ainda, que foi minha culpa neste momento) Mas eventualmente notou o intellisense do visual studio foi me avisando que eu tinha malformado XSL. Eu corrigi-lo e tudo começou a trabalhar.

Enervante cuidado quando trabalhar com XSL (e qualquer um dos arquivos XSL globais) — quebrá-los afeta muitos artefatos de sites.

<final />

Exibir conteúdo consulta Web Part resultados em uma grade / Tabela

Visão geral e objectivo

Fora da caixa, MUSGO’ Web Part de consulta de conteúdo (CQWP) exibe seus resultados em um formato de lista, semelhante ao resultados da pesquisa. Também é possível exibir os resultados em um formato de grade (ou seja. Tabela HTML). Formatos de grade são melhores em algumas circunstâncias. Descrevo como conseguir esse efeito neste artigo.

Cenário de negócios

Já trabalhei com um cliente em uma distribuição de musgo de toda a empresa. Nós projetamos sua taxonomia tal que projetos são cidadãos de primeira classe na hierarquia e tem seu próprio site de nível superior. Gerentes de projeto mantém uma lista de singleton de informações de resumo do projeto, como o título, orçamento, Data de conclusão prevista, restante orçamento e outros campos de tipo de resumo. Por "singleton" Quero dizer uma lista de SharePoint personalizada garantida para conter apenas um item. Forma simplista, Ele se parece com isso:

imagem

A abordagem técnica é o mesmo descrito here (http://paulgalvin.spaces.live.com/blog/cns!1CC1EDB3DAA9B8AA!447.entry). O CQWP usa uma transformação XSL para emitir o HTML para o navegador para processar.

Eu sempre imagino o resultado antes de mergulhar o XSL porque XSL é um pesadelo. Aqui está o meu resultado desejado:

imagem

HTML como este gera esse resultado:

<HTML>
 <corpo>
 <Centro>
 <tabela fronteira= 1>

<!-- Rótulos->
 <TR bgcolor= azul>
 <TD><fonte Cor= branco><b>Nome do projeto</b></fonte></TD>
 <TD alinhar= direita><fonte Cor= branco><b>Data completa</b></fonte></TD>
 <TD alinhar= direita><fonte Cor= branco><b>Orçamento</b></fonte></TD>
 <TD alinhar= direita><fonte Cor= branco><b>Despesas reais</b></fonte></TD>
 <TD><fonte Cor= branco><b>Status geral</b></fonte></TD>
 </TR>

<TR>
 <TD>Sala de computadores re-Wire.</TD>
 <TD alinhar= direita>02/01/08</TD>
 <TD alinhar= direita>22,500.00</TD>
 <TD alinhar= direita>19,000.00</TD>
 <TD>Em andamento</TD>
 </TR>

<TR>
 <TD>Provisionar servidores para atualizar o SQL</TD>
 <TD alinhar= direita>04/01/08</TD>
 <TD alinhar= direita>7,500.00</TD>
 <TD alinhar= direita>0.00</TD>
 <TD>Planejado</TD>
 </TR>

</tabela>
 </Centro>
 </corpo>
</HTML>

Abordagem

Siga estas etapas para criar a grade:

  1. Identificar os componentes da grade (linhas/colunas).
  2. Definir e criar colunas de site necessárias.
  3. Criar páginas para os projetos e listas de singleton.
  4. Adicionar o CQWP a uma página da web e configurá-lo para pesquisar suas listas.
  5. Modificar o XML do CQWP para reunir-se as colunas adicionais.
  6. Modificar o XSL para gerar uma tabela.

Vou concentrar-me no número 6. Números de um a quatro são direta e algo que qualquer usuário CQWP já feito. O número cinco tem sido bem documentado por outros, incluindo este artigo carga exaustivo de screen shot do MSDN here (http://msdn2.microsoft.com/en-us/library/bb897399.aspx) blog do Heather Salomão e here (http://www.heathersolomon.com/blog/articles/CustomItemStyle.aspx).

Porcas e parafusos

Iniciar e implementar as etapas de um a cinco de acordo com a documentação do MSDN e artigo Heather Solomon.

Neste ponto, você adicionou seu CQWP para a página e você tem seu <CommonViewFields> configurado conforme necessário.

Seguindo os passos habituais, Posso obter estes resultados intermédios:

1. Criar um tipo de conteúdo, uma lista personalizada modelos para esse tipo de conteúdo e dois sites. Aqui é o tipo de conteúdo:

imagem

Aqui é a estrutura do site:

imagem

2. Adicionar o CQWP depois de criar meu projeto subsites e singleton listas de resumo do projeto:

imagem

3. Adicionar todas as informações adicionais que eu quero através da <CommonViewFields>:

        <Propriedade nome="CommonViewFields" tipo="Cadeia de caracteres">Project_x0020_Name;Project_x0020_Expenses;Project_x0020_Status;Project_x0020_Start_x0020_Date;Project_x0020_End_x0020_Date;Project_x0020_Budget</Propriedade>

Nota que eu tinha que manter todos os campos de propriedade em uma linha ou não iria funcionar (CQWP me diria que a consulta não retornou nenhum item).

4. Neste ponto, Estamos prontos para ir além do artigo do MSDN e aleta sobre sobre artigo de Heather Solomon. Siga seus passos, começando próximo passo #5 para criar um personalizado / unghosted versão de ItemStyle. Eu seguir o Conselho de Heather, para cima até a etapa 11 e obter estes resultados intermédios:

4.1: Meu modelo de XSL nome da seguinte forma:

<XSL:nome do modelo = "grade" corresponder = "linha[@Style = 'Grid']" modo = "itemstyle">

Eu também ligeiramente modificá-la sugeriu <XSL:for-each …> Adicionando um <DRI> marca para fornecer uma listagem mais limpa:

    <XSL:for-each Selecione="@*">
      P:<XSL:valor da Selecione="nome()" /><br/>
    </XSL:for-each>

4.2: Posso modificar a web part, ir para a aparência e selecione minha grade"" estilo:

imagem

Aplicar a alteração e aqui está o resultado:

imagem

Do acima exposto podemos ver que os campos que nós queremos (Nome do projeto, despesas, estatuto, etc) estão disponíveis para nós usarmos quando emitimos o HTML. Não só isso, Mas vemos os nomes pelos quais nós deve fazer referência a essas colunas na XSL. Por exemplo, podemos fazer referência Status do projeto como "Project_x005F_x0020_Name".

Neste ponto, Devemos afastar-se do blog de Heather e de ombros destes gigantes, Posso adicionar meu próprios pouco.

ContentQueryMain.xsl

OBSERVAÇÃO: Ao fazer alterações em tanto ContentQueryMain.xsl como ItemStyle.xsl, você precisa verificar que os arquivos de volta em antes de ver o efeito das alterações.

Para fins de tomada de grade, MOSS usa dois diferentes arquivos XSL para produzir os resultados que vemos de um CQWP. Para gerar o bit anterior da saída, Nós modificamos ItemStyle. MOSS, na verdade, usa outro arquivo XSL, ContentQueryMain para, em conjunto com ItemStyle para gerar o HTML. Como seu nome implica, ContentQueryMain.xsl é o principal"" XSL que controla o fluxo global de tradução. Ele percorre todos os itens encontrados e passa-los um por um para modelos em ItemStyle. Modificaremos ItemStyle para gerar a céu aberto <tabela> etiqueta antes de emitir a primeira linha de dados e o fechamento <tabela> etiqueta depois de emitir a última linha. Para realizar essa tarefa, ContentQueryMain.xsl é modificado para passar dois parâmetros para nossa grade"" modelo em ItemStyle.xsl, "última linha" e a "linha atual". ItemStyle usa essas condicionalmente emitir as etiquetas necessárias.

Usando a técnica do Heather Salomão, Podemos localizar ContentQueryMain. Situa-se no mesmo lugar como ItemStyle. Esta captura de tela deve ajudar:

imagem

Temos de fazer as seguintes alterações:

  • Modificar um modelo xsl, "CallItemTemplate" que na verdade invoca o nosso modelo de grade em ItemStyle. Vamos passar dois parâmetros para o modelo de grade para que ele terá os dados necessários para gerar condicionalmente abrindo e fechando <tabela> marcas.
  • Modificar outro pouco de ContentQueryMain.xsl que chama o CallItemTemplate"" passá-lo um LastRow"" parâmetro de modo que LastRow pode ser transferido para o nosso modelo de grade.

Localize o modelo chamado "OuterTemplate.CallItemTemplate" identificado pela Cadeia de caracteres:

  <XSL:modelo nome="OuterTemplate.CallItemTemplate">

Substituir o modelo inteiro como segue:

  <XSL:modelo nome="OuterTemplate.CallItemTemplate">
    <XSL:param nome="CurPosition" />

    <!--
      Adicionar o LastRow"" parâmetro.
      Nós só usá-lo quando a passagem de estilo de item no é "Grade".
    -->
    <XSL:param nome="LastRow" />

    <XSL:Escolha>
      <XSL:Quando teste="@ Estilo = 'NewsRollUpItem'">
        <XSL:aplicar-se-modelos Selecione="." modo="ItemStyle">
          <XSL:com-param nome="EditMode" Selecione="$cbq_iseditmode" />
        </XSL:aplicar-se-modelos>
      </XSL:Quando>
      <XSL:Quando teste="@ Estilo = 'NewsBigItem'">
        <XSL:aplicar-se-modelos Selecione="." modo="ItemStyle">
          <XSL:com-param nome="CurPos" Selecione="$CurPosition" />
        </XSL:aplicar-se-modelos>
      </XSL:Quando>
      <XSL:Quando teste="@ Estilo = 'NewsCategoryItem'">
        <XSL:aplicar-se-modelos Selecione="." modo="ItemStyle">
          <XSL:com-param nome="CurPos" Selecione="$CurPosition" />
        </XSL:aplicar-se-modelos>
      </XSL:Quando>

      <!--
              Transmitir posição atual e lastrow para o modelo de itemstyle.xsl de grade.
              ItemStyle.xsl que usará para emitir o abrir e fechar <tabela> marcas.
      -->
      <XSL:Quando teste="@ Estilo = 'Grid'">
        <XSL:aplicar-se-modelos Selecione="." modo="ItemStyle">
          <XSL:com-param nome="CurPos" Selecione="$CurPosition" />
          <XSL:com-param nome="Última" Selecione="$LastRow" />
        </XSL:aplicar-se-modelos>
      </XSL:Quando>

      <XSL:caso contrário>
        <XSL:aplicar-se-modelos Selecione="." modo="ItemStyle">
        </XSL:aplicar-se-modelos>
      </XSL:caso contrário>
    </XSL:Escolha>
  </XSL:modelo>

Os comentários descrevem a finalidade das alterações.

É claro, o OuterTemplate.CallItemTemplate"" Chama-se de outro modelo. Localize esse modelo procurando por essa seqüência de caracteres de texto:

<XSL:modelo nome="OuterTemplate.Body">

Percorra as instruções em OuterTemplate.Body e inserir o parâmetro LastRow como segue (mostrado como um comentário em itálico):

<XSL:modelo de convite nome="OuterTemplate.CallItemTemplate">
  <XSL:com-param nome="CurPosition" Selecione="$CurPosition" />
  <!-- Inserir o parâmetro LastRow. -->
  <XSL:com-param nome="LastRow" Selecione="$LastRow"/>
</XSL:modelo de convite>

Depois de tudo isso, Finalmente temos coisas configurar corretamente para que o nosso ItemStyle.xsl pode emitir <tabela> marcas no lugar certo.

ItemStyle.Xsl

OBSERVAÇÃO: Mais uma vez, o check-in ItemStyle.xsl depois de fazer todas as alterações para que você veja o efeito dessas alterações.

Aqui temos duas tarefas:

  • Substituir o modelo inteiro de grade. Você pode copiar/colar de baixo.
  • Adicionar alguns patranhas fora da definição de modelo que permite "formatcurrency" modelo de trabalho. (Você pode dizer que eu tenho um identificador tênue em XSL).

Primeira, perto do topo da ItemStyle.xsl, Adicione esta linha:

  <!-- Alguns patranhas que nos capacita a Exibir dos e.u.. moeda. -->
  <XSL:decimal-formato nome="pessoal" dígito="D" />

  <XSL:modelo nome="Padrão" correspondência="*" modo="ItemStyle">

Nota que eu adicionado diretamente antes do <XSL:nome do modelo = padrão"" …> definição.

Próximo, voltar para o nosso modelo de grade. Substituir o modelo de grade inteiro com o código abaixo. Isso é completamente comentou, mas não hesite em me e-mail ou deixar comentários no meu blog, se você tiver perguntas.

  <XSL:modelo nome="Grelha" correspondência="Linha[@ Estilo = 'Grid']" modo="ItemStyle">

    <!--
      ContentMain.xsl passa CurPos e última.
      Podemos usá-los para emitir condicionalmente a abrir e fechar <tabela> marcas.
    -->
    <XSL:param nome="CurPos" />
    <XSL:param nome="Última" />

    <!-- As seguintes variáveis são inalteradas desde o padrão ItemStyle -->
    <XSL:variável nome="SafeImageUrl">
      <XSL:modelo de convite nome="OuterTemplate.GetSafeStaticUrl">
        <XSL:com-param nome="UrlColumnName" Selecione="'ImageUrl'"/>
      </XSL:modelo de convite>
    </XSL:variável>
    <XSL:variável nome="SafeLinkUrl">
      <XSL:modelo de convite nome="OuterTemplate.GetSafeLink">
        <XSL:com-param nome="UrlColumnName" Selecione="'LinkUrl'"/>
      </XSL:modelo de convite>
    </XSL:variável>
    <XSL:variável nome="DisplayTitle">
      <XSL:modelo de convite nome="OuterTemplate.GetTitle">
        <XSL:com-param nome="Título" Selecione="@Title"/>
        <XSL:com-param nome="UrlColumnName" Selecione="'LinkUrl'"/>
      </XSL:modelo de convite>
    </XSL:variável>
    <XSL:variável nome="LinkTarget">
      <XSL:se teste="@OpenInNewWindow = 'True'" >Blank</XSL:se>
    </XSL:variável>

    <!--
      Aqui, definimos uma variável, "tableStart".  Este contém o HTML que usamos para definir a abertura da mesa, bem como os rótulos de coluna.  Observe que, se CurPos = 1, inclui o HTML em uma marca CDATA.
      Caso contrário, vai ser vazio.

      O valor de tableStart é emited sempre ItemStyle é chamado através de ContentQueryMain.
    -->
    <XSL:variável nome="tableStart">
      <XSL:se teste="$CurPos = 1">
        <![CDATA[
        <borda de tabela = 1>
          <TR bgcolor = "azul">
            <TD><cor da fonte = "branco"><b>Nome do projeto</b></fonte></TD>
            <TD align = "right"><cor da fonte = "branco"><b>Data completa</b></fonte></TD>
            <TD align = "right"><cor da fonte = "branco"><b>Orçamento</b></fonte></TD>
            <TD align = "right"><cor da fonte = "branco"><b>Despesas reais</b></fonte></TD>
            <TD><cor da fonte = "branco"><b>Status geral</b></fonte></TD>
          </TR>
        ]]>
      </XSL:se>
    </XSL:variável>

    <!--
      Outra variável, tableEnd simplesmente define o fechamento marca de tabela.

      Tal como acontece com tableStart, sempre é emited.  Eis porque seu valor é atribuído condicionalmente com base em se nós já foi passados a última linha por ContentQueryMain.
    -->
    <XSL:variável nome="tableEnd">
      <XSL:se teste="$CurPos = $Last">
        <![CDATA[ </tabela> ]]>
      </XSL:se>
    </XSL:variável>

    <!--
      Sempre emitir o conteúdo de tableStart.  Se isto não é a primeira linha que passou para nós por ContentQueryMain, Então sabemos que seu valor será em branco.

      Desativar a saída saída porque quando tableStart não em branco, Ele inclui HTML real que nós queremos ser processado pelo navegador.  Se não contarmos o analisador XSL para desabilitar saída escapando, Ele irá gerar coisas como"&lt;tabela&gt;" em vez de"<tabela>".
    -->
    <XSL:valor da Selecione="$tableStart" desativar-saída-saída="Sim"/>


    <TR>
      <!--
      P:Project_x005F_x0020_Name P:Project_x005F_x0020_End_x005F_x0020_Date P:Project_x005F_x0020_Budget P:Project_x005F_x0020_Expenses P:Project_x005F_x0020_Status
      -->
      <TD>
        <XSL:valor da Selecione="@ Project_x005F_x0020_Name"/>
      </TD>

      <TD alinhar="direito">
        <XSL:valor da Selecione="@ Project_x005F_x0020_End_x005F_x0020_Date"/>
      </TD>

      <TD alinhar="direito">
        <XSL:modelo de convite nome="FormatCurrency">
          <XSL:com-param nome="valor" 
Selecione="@ Project_x005F_x0020_Budget"></XSL:com-param> </XSL:modelo de convite> </TD> <TD alinhar="direito"> <XSL:modelo de convite nome="FormatCurrency"> <XSL:com-param nome="valor" Selecione="@ Project_x005F_x0020_Expenses">
</XSL:com-param> </XSL:modelo de convite> </TD> <TD> <XSL:valor da Selecione="@ Project_x005F_x0020_Status"/> </TD> <!-- Todos os itens a seguir está comentada para esclarecer as coisas. No entanto, trazer de volta e o material em um <TD> para ver seu efeito. --> <!-- <div id = "linkitem" Classe = "item"> <XSL:se teste = "Cadeia de caracteres de comprimento($SafeImageUrl) != 0 "> <div class = "image-área-esquerda"> <um href = "SafeLinkUrl{$SafeLinkUrl}" destino = "{$LinkTarget}"> <Classe img = "imagem-fixo-largura" src = "{$SafeImageUrl}"
Alt = "{@ ImageUrlAltText}"/> </uma> </div> </XSL:se> <div class = "item de link"> <XSL:modelo de convite
Name="OuterTemplate.CallPresenceStatusIconTemplate"/> <um href = "SafeLinkUrl{$SafeLinkUrl}"
destino = "{$LinkTarget}" title = "{@ LinkToolTip}"> <XSL:valor da selecione = "$ DisplayTitle" /> </uma> <div class = "description"> <XSL:valor de select="@Description" /> </div> </div> </div>
--> </TR> <!-- Emitir o fechamento marca de tabela. Se não estamos na última linha, Este será em branco. --> <XSL:valor da Selecione="$tableEnd" desativar-saída-saída="Sim"/> </XSL:modelo> <XSL:modelo nome="FormatCurrency"> <XSL:param nome="valor" Selecione="0" /> <XSL:valor da Selecione='formato-número($valor, "$ DDD,DDD,DDD.DD", "pessoal")' /> </XSL:modelo>

Telas de entrada de dados WSS/MOSS padrão não suportam suspensas em cascata (ou outro intra-comunicação)

ATUALIZAÇÃO (04/2008): Esta entrada de blog grande mostra uma abordagem deste problema bom javascript baseado: http://webborg.blogspot.com/2008/04/add-functions-and-events-to-sharepoint.html

ATUALIZAÇÃO II: (04/2008): Esta entrada de blog também parece promissor: http://www.cleverworkarounds.com/2008/03/13/free-mosswss-2007-web-part-hide-controls-via-javascript/

Várias vezes por semana, Se não diária, os usuários do fórum descrevem um requisito que normalmente seria atendido através de suspensas em cascata. Por exemplo, Eu tenho dois controles de soltar-para baixo:

  • Lista de E.U.. Estados-Membros
  • Lista de E.U.. cidades.

Como provedores de interface do usuário responsáveis, Queremos operar assim:

  • Paul seleciona dos E.U.. Estado do soltar-para baixo.
  • Isso faz com que as cidades suspensa para filtrar apenas as cidades que pertencem ao estado selecionado.
  • Paul seleciona uma cidade desta lista filtrada.

Não há nenhum suporte out-of-the-box para esse recurso. Na verdade, Não há nenhum suporte OOB para qualquer tipo de comunicação direta intra-formulário. Isso inclui programaticamente campos escondidos/ativação/desativação em resposta a alterações de campo em outro lugar no formulário.

O verdadeiro objectivo deste artigo para descrever as soluções possíveis e estas são as opções de como eu os conheço:

  1. Desenvolver um tipo de coluna personalizados. Como um costume-coluna-desenvolvedor, Você tem controle total sobre o mundo"" dessa coluna personalizada. Você pode implementar uma cascata suspensa assim.
  2. Considere o uso de fluxo de trabalho. Em alguns casos, você deseja atribuir automaticamente um valor de campo com base no valor do campo outro. Neste caso, Você normalmente tentaria usar uma coluna calculada, Mas algumas vezes, Não só vai fazer o trabalho. Fluxo de trabalho do SharePoint Designer é uma alternativa de administrar relativamente favorável para descer em código e visual studio. Se você vai esta rota, Lembre-se da questão abordada pelo Este artigo (http://paulgalvin.spaces.live.com/blog/cns!CC1EDB3DAA9B8AA!405.entry).
  3. Manipuladores de eventos: Como o fluxo de trabalho, Esta é uma solução após o fato. Manipulador de eventos é um assembly .NET (C#, VB.NET) a qual o SharePoint passa o controle. O objeto que você desenvolver tem acesso aos dados da lista (e o modelo de objeto inteiro) e posso fazer qualquer cálculo necessário.
  4. Usar o SharePoint Designer para criar formulários de entrada personalizado. Não tenho experiência direta com esta abordagem, but I hear they are doing good things with NewForm.aspx these days 🙂
  5. Rolo de sua própria função de entrada de dados do ASP.NET (como uma página da web stand-alone ou como uma web part) e utilizá-lo.

Se alguém souber de outras e/ou melhores opções, por favor, poste um comentário e eu vou atualizar o corpo deste post.

<final />

Criar gráficos de barras no SharePoint

Visão geral:

(ATUALIZAÇÃO 12/04/07: Adicionado um outro recurso interessante no final ligando para outro blog que aborda esta via uma parte muito interessante do web)

Esta entrada de blog descreve como criar um gráfico de barras no SharePoint. Isso funciona em ambientes WSS e o MOSS como depende apenas do web part de exibição de dados.

A abordagem geral é a seguinte:

  1. Criar uma lista ou biblioteca de documentos que contém os dados que você deseja gráfico.
  2. Lugar da biblioteca de documento associado / personalizado lista em uma página e convertê-lo em uma web part de exibição de dados (DVWP).
  3. Modificar XSL do DVWP para gerar HTML que mostra como um gráfico.

Cenário de negócios / Instalação:

Eu criei uma lista personalizada com a coluna de título padrão e uma coluna adicional, "Status". Este modelos (muito simplista) uma "autorização de despesa" cenário onde o título representa o projeto e o Status de um valor da lista de:

  • Propõe-se
  • No processo de
  • Parado

O objetivo é produzir um gráfico de barras horizontal interativo que mostra esses códigos de status.

Eu ter preenchido a lista e parece que isso:

imagem

Criar a Web Part de exibição de dados:

Criar o DVWP adicionando a lista personalizada para uma página (página do site no meu caso) e siga as instruções here (http://paulgalvin.spaces.live.com/blog/cns!1CC1EDB3DAA9B8AA!395.entry).

Além de simplesmente criar o DVWP, Precisamos também definir a propriedade de paginação para mostrar todas as linhas disponíveis. Para mim, Isto é algo como isto:

imagem

Neste ponto, Eu sempre fecho SPD e o navegador. Então re-abrir a página usando o navegador. Isso evita que acidentalmente estragar o layout de parte da web na página.

Modificar o XSLT:

Agora é hora de modificar o XSLT.

Sempre usar visual studio para isso. (Consulte here para uma nota importante sobre intellisense que irá ajudá-lo muito).

Criar um projeto vazio adicionar quatro novos arquivos (substituindo as palavras "Original" e "nova" conforme o caso):

  • Original.XSLT
  • New.XSLT
  • Etcconfig_datadeployment original
  • Nova etcconfig_datadeployment

No meu caso, Ele se parece com isso:

imagem

Modificar a web part e copiar o params e XSL para o Original"" versão em Visual Studio.

O objetivo aqui é fazer com que o XSL transformar os resultados de que voltarmos da consulta DVWP em HTML que processa como um gráfico.

Para este fim., ajuda a primeiro considerar o que o HTML deve olhar como antes nós ficar confuso pela loucura que é conhecida como "XSL". (Para ser claro, é simplesmente um exemplo; não digitar ou copiar/colar em visual studio. Eu forneço um golpe completo, ponto de partida para que mais tarde no write-up). O gráfico de exemplo a seguir é processado conforme o HTML imediatamente após:

Exemplo de Gráfico de Barras

HTML correspondente:

<HTML>
<corpo>
<Centro>
<largura da tabela = 80%>
<TR><TD><Centro>Gráfico de barras horizontais</TD></TR>
<TR>
<TD align = "center">
<borda de tabela = "1" largura = 80%>
<TR>
<TD largura = 10%>Aberto</TD>
<TD><tabela cellpadding ="0" CellSpacing ="0" border = 0 width = 50%><TR bgcolor = vermelho><TD>&nbsp;</TD></TR></tabela></TD>
</TR>
<TR>
<TD largura = 10%>Fechado</TD>
<TD><tabela cellpadding ="0" CellSpacing ="0" border = 0 width = 25%><TR bgcolor = vermelho><TD>&nbsp;</TD></TR></tabela></TD>
</TR>
<TR>
<TD largura = 10%>Parado</TD>
<TD><tabela cellpadding ="0" CellSpacing ="0" border = 0 width = 25%><TR bgcolor = vermelho><TD>&nbsp;</TD></TR></tabela></TD>
</TR>
</tabela>
</TD>
</TR>
</tabela>
</corpo>
</HTML>

Eu usei uma abordagem absolutamente simples para criar minhas barras definindo a cor de fundo de uma linha para "red".

Trata-se aqui o Take-Away: No final, todos nós estamos fazendo é criar o HTML com linhas e colunas.

Modelo XSLT:

Eu copiei o XSLT que gera um gráfico de barras horizontal. É razoavelmente bem para não adicionar muito aqui exceto para estas notas, comentou:

  • Eu comecei com o padrão XSL que me deu quando eu criei primeiro a DVWP SharePoint Designer.
  • Eu era capaz de reduzir este partir do SPD 657 linhas de 166 linhas.
  • Eu não mexer com o arquivo XML de parâmetros (que é separado do XSL e você saberá o que quero dizer quando você vai para modificar o DVWP em si; Existem dois arquivos que você pode modificar). No entanto, a fim de simplificar as coisas, Para remover quase todos eles de XSL. Isto significa que se você quiser fazer uso desses parâmetros, Você só precisa adicionar suas definições de variável para o XSL. Isso vai ser fácil, pois você terá as definições de variável XSL originais em seu projeto visual studio.
  • Você precisa ser capaz de copiar e cole-o diretamente no seu projeto visual studio. Em seguida, remover minhas ligações e inserir suas próprias chamadas para "ShowBar".
  • A broca para baixo funciona através da criação de um <a href> Assim: http://server/List?FilterField1=fieldname&FilterValue1=actualFilterValue. Esta técnica pode ser de valor em outros contextos. Em primeiro lugar, Eu pensei que eu precisaria de acordo com um formato mais complexo: http://server/List/AllItems.aspx?View={guid}&FilterField1=blah&FilterValue1=blah, Mas em meu ambiente que não é necessário. URL a lista é passado para pelo SharePoint, então isso é muito fácil generalizar.

Aqui é...:

<XSL:StyleSheet Versão="1.0" excluir-resultado-prefixos="RS z ó s ddwrt dt msxsl" 
xmlns:msxsl="urn:Esquemas-microsoft-com:XSLT" xmlns:XSL="http://www.w3.org/TR/1998/REC-xml-19980210 1999/XSL/Transform"
xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:ASP="http://schemas.microsoft.com/ASPNET/20" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:ó="urn:Esquemas-microsoft-com:escritório" xmlns:s="UUID:BDC6E3F0-6DA3-11D1-A2A3-00AA00C14882"
xmlns:DT="UUID:C2F41010-65B3 - 11d 1-A29F-00AA00C14882" xmlns:RS="urn:Esquemas-microsoft-com:conjunto de linhas" xmlns:z="#RowsetSchema"
xmlns:ddwrt2="urn:FrontPage:interno"
> <XSL:saída Método="HTML" travessão="Não" /> <XSL:decimal-formato NaN="" /> <XSL:param nome="ListUrlDir"></XSL:param> <!-- Preciso disto para apoiar um aprofundamento. --> <XSL:modelo correspondência="/" xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:__designer=http://schemas.microsoft.com/WebParts/v2/DataView/designer xmlns:ASP="http://schemas.microsoft.com/ASPNET/20"
> <XSL:variável nome="dvt_StyleName">Tabela</XSL:variável> <XSL:variável nome="Linhas" Selecione="/dsQueryResponse/linhas/linha" /> <XSL:variável nome="dvt_RowCount" Selecione="contagem($Linhas)" /> <XSL:variável nome="IsEmpty" Selecione="$dvt_RowCount = 0" /> <XSL:variável nome="dvt_IsEmpty" Selecione="$dvt_RowCount = 0" /> <XSL:Escolha> <XSL:Quando teste="$dvt_IsEmpty"> Não há dados para o gráfico!<br/> </XSL:Quando> <XSL:caso contrário> <!-- As coisas interessantes começam aqui. Precisamos definir um par de variáveis para cada linha no gráfico: número total de itens e por cento do total. --> <XSL:variável nome="totalProposed" Selecione="contagem(/dsQueryResponse/linhas/linha[Normalizar-espaço(@Status) = 'Proposta'])" /> <XSL:variável nome="percentProposed" Selecione="$totalProposed div $dvt_RowCount" /> <XSL:variável nome="totalInProcess" Selecione="contagem(/dsQueryResponse/linhas/linha[Normalizar-espaço(@Status) = 'Em processo'])" /> <XSL:variável nome="percentInProcess" Selecione="$totalInProcess div $dvt_RowCount" /> <XSL:variável nome="totalStalled" Selecione="contagem(/dsQueryResponse/linhas/linha[Normalizar-espaço(@Status) = 'Parado'])" /> <XSL:variável nome="percentStalled" Selecione="$totalStalled div $dvt_RowCount" /> <!-- Definimos nossa tabela HTML aqui. Eu peguei emprestado de alguns estilos padrão do SharePoint aqui para torná-lo coerente. Acho que isso honrará as alterações para o arquivo css global bem como tema substitui. --> <tabela Largura="100%" CellSpacing="0" CellPadding="2" estilo="fronteira-direito: 1 #C0C0C0 sólido; beira-parte inferior: 1 #C0C0C0 sólido; border-left-style: sólidos; border-left-width: 1; border-top-style: sólidos; border-top-width: 1;"> <TR> <TD alinhar="Centro"> <tabela fronteira="1" Largura="100%"> <!-- Para cada Estado que nós queremos fazer um gráfico, Nós chamamos o "ShowBar" modelo. Que passa por ela: 1. Um rótulo para a linha. Isso é transformado em um hiperlink. 2. Os por cento (variável de cima). 3. O nome do campo real do código da lista subjacente. Isto não precisa corresponder ao rótulo de exibição. 4. Valor do campo correspondente para #3. 5. Total de itens deste código de status (Não o total geral de todos os códigos de status). Ele emite um <TR></TR> e a linha do gráfico de barras horizontais. Nós chamamos este modelo para cada código de status, que queremos ver os. --> <XSL:modelo de convite nome="ShowBar"> <XSL:com-param nome="BarDisplayLabel" Selecione="'Proposta'"/> <XSL:com-param nome="BarPercent" Selecione="$percentProposed"/> <XSL:com-param nome="QueryFilterFieldName" Selecione="'Status'"/> <XSL:com-param nome="QueryFilterFieldValue" Selecione="'Proposta'"/> <XSL:com-param nome="TotalItems" Selecione="$totalProposed"></XSL:com-param> </XSL:modelo de convite> <XSL:modelo de convite nome="ShowBar"> <XSL:com-param nome="BarDisplayLabel" Selecione="'Parado'"/> <XSL:com-param nome="BarPercent" Selecione="$percentStalled"/> <XSL:com-param nome="QueryFilterFieldName" Selecione="'Status'"/> <XSL:com-param nome="QueryFilterFieldValue" Selecione="'Parado'"/> <XSL:com-param nome="TotalItems" Selecione="$totalStalled"></XSL:com-param> </XSL:modelo de convite> <XSL:modelo de convite nome="ShowBar"> <XSL:com-param nome="BarDisplayLabel" Selecione="'Em processo'"/> <XSL:com-param nome="BarPercent" Selecione="$percentInProcess"/> <XSL:com-param nome="QueryFilterFieldName" Selecione="'Status'"/> <XSL:com-param nome="QueryFilterFieldValue" Selecione="'Em processo'"/> <XSL:com-param nome="TotalItems" Selecione="$totalInProcess"></XSL:com-param> </XSL:modelo de convite> </tabela> </TD> </TR> </tabela> </XSL:caso contrário> </XSL:Escolha> </XSL:modelo> <!-- Este modelo faz o trabalho de exibir linhas individuais no gráfico de barras. Você provavelmente vai fazer a maioria de seus ajustes aqui. --> <XSL:modelo nome="ShowBar"> <XSL:param nome="BarDisplayLabel" /> <!-- rótulo para mostrar --> <XSL:param nome="BarPercent"/> <!-- Por cento do total. --> <XSL:param nome="QueryFilterFieldName"/> <!-- Usado para saltar para a consulta & filtro --> <XSL:param nome="QueryFilterFieldValue"/> <!-- Usado para saltar para a consulta & filtro --> <XSL:param nome="TotalItems" /> <!-- contagem total desta barlabel --> <TR> <!-- O bar em si rotular. --> <TD Classe="MS-formbody" Largura="30%"> <!-- Este set de instruções cria uma seqüência de caracteres de consulta que permite-nos detalhar uma exibição filtrada dos dados subjacentes. Fazemos uso de umas coisas aqui: 1. Podemos fazer FilterField1 e FilterValue1 para uma lista para filtrar uma coluna. 2. SharePoint é passar um parâmetro chave para nos, ListUrlDir que aponta para a lista subjacente contra o qual este DVWP está "em execução". Não é divertido XSL? --> <XSL:texto desativar-saída-saída="Sim"> <![CDATA[<um href ="]]></XSL:texto> <XSL:valor da Selecione="$ListUrlDir"/> <XSL:texto desativar-saída-saída="Sim"><![CDATA[?FilterField1 =]]></XSL:texto> <XSL:valor da Selecione="$QueryFilterFieldName"/> <XSL:texto desativar-saída-saída="Sim"><![CDATA[&FilterValue1 =]]></XSL:texto> <XSL:valor da Selecione="$QueryFilterFieldValue"/> <XSL:texto desativar-saída-saída="Sim"><![CDATA[">]]></XSL:texto> <XSL:valor da Selecione="$BarDisplayLabel"/> <XSL:texto desativar-saída-saída="Sim"><![CDATA[</uma>]]></XSL:texto> <!-- A próxima cena mostra alguns números no formato: "(total / % do total)" --> (<XSL:valor da Selecione="$TotalItems"/> / <!-- Isso cria uma etiqueta bonita por cento para nós. Obrigado, Microsoft! --> <XSL:modelo de convite nome="percentformat"> <XSL:com-param nome="por cento" Selecione="$BarPercent"/> </XSL:modelo de convite>) </TD> <!-- Finalmente, emitir um <TD> marca para o bar em si.--> <TD> <tabela CellPadding="0" CellSpacing="0" fronteira="0" Largura="{rodada($BarPercent * 100)+1}%"> <TR bgcolor="vermelho"> <XSL:texto desativar-saída-saída="Sim"><![CDATA[&nbsp;]]></XSL:texto> </TR> </tabela> </TD> </TR> </XSL:modelo> <!-- Isto é tirado diretamente de alguns XSL que encontrei em um modelo de MS. --> <XSL:modelo nome="percentformat"> <XSL:param nome="por cento"/> <XSL:Escolha> <XSL:Quando teste="formato-número($por cento, '#,##0%;-#,##0%')= 'NaN'">0%</XSL:Quando> <XSL:caso contrário> <XSL:valor da Selecione="formato-número($por cento, '#,##0%;-#,##0%')" /> </XSL:caso contrário> </XSL:Escolha> </XSL:modelo> </XSL:StyleSheet>

Os resultados:

O XSL de cima gera este gráfico:

imagem

Detalhar os dados subjacentes, clicando sobre o código de status:

imagem

Pensamentos finais:

Isto pode ser generalizado?

Eu amo este conceito gráfico, Mas eu odeio o fato de que eu tenho que entrar e fazer tanta mão-codificação. Pensei um pouco para se pode ser generalizada e estou otimista, Mas também estou um pouco temeroso de que pode haver uma parede de tijolos em algum lugar ao longo do caminho que não oferece qualquer forma de contornar. Se alguém tiver ideias sobre este, por favor faça uma nota nos comentários ou correio eletrónico a mim.

Gráficos verticais:

Este é um gráfico de barras horizontal. É certamente possível criar um gráfico vertical. Só precisamos alterar o HTML. Eu começaria da mesma forma: Criar uma representação de HTML de um gráfico de barras vertical e então descobrir como conseguir isso através de XSL. Se alguém estiver interessado em que, Eu poderia ser persuadido para experimentá-lo e trabalhar as arestas. Se alguém já fez isso, por favor, deixe-me saber e terei prazer em vincular ao seu blog 🙂

Acho que o desafio com um gráfico vertical é que os rótulos de gráfico são mais difíceis de gerenciar, Mas certamente não é impossível.

Do campo nome Gotcha:

Há pelo menos duas coisas para procurar com seus nomes de campo.

Primeira, um nome de campo com um espaço tem que ser antecedidas na XSL. Este provavelmente será um problema aqui:

        <XSL:variável nome="totalProposed" 
Selecione="contagem(/dsQueryResponse/linhas/linha[Normalizar-espaço(@Status) = 'Proposta'])" />

Se seu Status"" coluna na verdade é chamada "código de Status" Então você precisa fazer referência a ele como "Status_x0020_Code":

   <XSL:variável nome="totalProposed" 
Selecione="contagem(/dsQueryResponse/linhas/linha[Normalizar-espaço(@Status_x0020_Code) = 'Proposta'])" />

Segundo, e estou um pouco confuso com isto, Mas você também precisa estar alerta para alterações de nome de domínio. Se o nome de seu campo "código de Status" e, posteriormente, na, Renomeie-o para "AFE Status", o nome"interno" Não muda. O nome interno ainda será o código de Status"" e deve ser referenciada como "Status_x0020_Code". Os "outros recursos" links podem ajudar a diagnosticar e corrigir esse tipo de problema.

Sobre essa cor:

Eu escolhi "vermelho" Porque é agradável para mim no momento. Não seria um grande negócio para mostrar cores diferentes a fim de fornecer mais do que apenas uma descrição visual de um número, Mas também fornecer um KPI útil. Por exemplo, se a percentagem de "parado" AFE é > 10% em seguida, mostrar vermelho, caso contrário, mostrá-lo em preto. Utilização <XSL:Escolha> para realizar essa tarefa.

Outros recursos:

Transformando feliz!

<final />

Subscreva ao meu blog!

Apresentar dados da OM através de uma lista personalizada (ou, Ainda outra OM dados Displayor [como YACC, mas diferentes])

Hoje, Passei um punhado de horas para rastrear a causa raiz para trás a mensagem "o nome da coluna que você inseriu já está em uso ou reservados. Escolha outro nome."

A coluna em questão poderia ser criada, excluído e recriado em outro ambiente, Então eu sabia que não era um nome reservado. No entanto, Eu simplesmente não conseguia encontrar a coluna em qualquer lugar através da interface de usuário padrão SharePoint em qualquer site na coleção site.

Eu postei a Fóruns do MSDN aqui e o indomável Andrew Woodward me apontou na direção dos dados do modelo subjacente do objeto.

Saí para CodePlex para encontrar algumas ferramentas que me ajudasse a perscrutar os dados subjacentes do OM e me ajudar a localizar o problema.

Eu tentei várias ferramentas e eles eram muito legal e interessante, mas no final, a interface do usuário não era suficientemente bom para o meu propósito. Não estou a criticá-los por qualquer meio, mas claramente os fabricantes de ferramentas não tinham meu problema em mente quando eles criaram sua interface do usuário :). A maioria das pessoas parecem ser investir uma quantidade razoável de tempo e esforço na criação de estação de trabalho / aplicativos de cliente que fornecem modos de exibição de árvore, botão direito do mouse menus de contexto e assim por diante. Estes são legais e todos os, mas é muito trabalho para criar uma experiência de usuário de top-of-the-line que também é muito flexível.

Eu realmente precisava de uma resposta para este problema. Ocorreu-me que se eu pudesse pegar todas as colunas de site na coleção site em uma lista personalizada, Eu poderia filtrar, classificar e criar modos de exibição que iria me ajudar a encontrar essa coluna supostamente existente (o que aconteceu, BTW). Eu fui em frente e fez isso e uma ou duas horas mais tarde, tinham todas as minhas colunas de site carregado em uma lista personalizada com agrupamento, classificação e assim por diante. Eu encontrei minha resposta cinco minutos mais tarde.

Se e quando tomo com sucesso o mundo, Acho que será o decreto que todos os fornecedores de ferramentas do SharePoint devem considerar seriamente aplainando seus dados de modelo de objeto em uma lista personalizada. Dessa forma, Eu tenho o poder para procurar qualquer caminho que eu quero (restrita, É claro, por recursos do sharepoint padrão).