Преобразовать строку в объект Div в vb.net/asp

0

У меня немного сложная проблема, и я не могу понять, как ее решить.

В принципе, у меня есть пара таблиц в моей базе данных, которые, идентифицируют по клиенту, с которыми делятся идентификаторы, к которым клиент имеет доступ, с помощью вкладки

Поэтому у меня есть таблица, которая идентифицирует divs по их идентификатору, используя индекс таблицы:

id | id_div
0 | Д0
1 | D1 (и т.д.)

И еще один, у которого есть только идентификатор клиентов и divs (идентифицируется полем "id"), он имеет доступ к:

client_id | div_id 29 | 0 29 | 1 (и т.д.)

Затем я перекрестно ссылаюсь на то, какие divs должны быть видимыми, а какие нет. Проблема в том, что я получаю id divs как строку и для того, чтобы иметь возможность указывать в коде, чтобы установить видимость на false, мне нужно ссылаться на div в себе.

Образец:

<dx:TabPage Name="tabServico" Text="<%$ Resources:InterfaceGenerica, lblServico %>">
    <ContentCollection>
        <dx:ContentControl>
           <div class="conteudo_pagina_tab">
               <asp:HiddenField ID="hidID" runat="server" Value="0" EnableViewState="true" />
               <asp:HiddenField ID="hidIdCliente" runat="server" Value="0" EnableViewState="true"/>
               <div id="D0" runat="server">
                   <div class="cols coluna1">
                       <asp:Literal ID="litClientes" runat="server" Text="<%$ Resources:InterfaceGenerica, lblCliente %>"></asp:Literal>
                    </div>
                    <div class="cols coluna2-4">
                        <dx:ASPxComboBox ID="cboClientes" runat="server" HelpText="" ValueField="id_cliente" TextField="nome_completo" SelectedValue="" Width="100%" AutoPostBack="true"></dx:ASPxComboBox>
                     </div>
                </div>
                <clear></clear>
                <div id="D1" runat="server">
                     <div class="cols coluna1">
                        <asp:Literal ID="litTipoOperacao" runat="server" Text="<%$ Resources:InterfaceGenerica, lblOperacao %>"></asp:Literal>
                     </div>
                     <div class="cols coluna2-4">
                         <dx:ASPxComboBox ID="cboTipoOperacao" runat="server" Width="100%" HelpText="" ValueField="id_operacoes" TextField="nome" SelectedValue="" AutoPostBack="true">
                          </dx:ASPxComboBox>
                     </div>
                 </div>
                 <clear></clear>
                 <div id="D2" runat="server">
                     <div class="cols coluna1">
                        <asp:Literal ID="litTipoServs" runat="server" Text="<%$ Resources:InterfaceGenerica, lblTipoServico %>"></asp:Literal>
                      </div>
                 <div class="cols coluna2-4">
                     <dx:ASPxComboBox ID="cboTipoServs" runat="server" HelpText="" ValueField="id_tipo_servs" TextField="nome" SelectedValue="" AutoPostBack="true" Width="100%"></dx:ASPxComboBox>
                 </div>
             </div>
             <div id="D3" runat="server">
                   <div class="cols coluna5">
                       <asp:Literal ID="litSubTipoServs" runat="server" Text="<%$ Resources:InterfaceGenerica, lblSubtipoServico %>"></asp:Literal>
                   </div>
                   <div class="cols coluna6-8">
                       <dx:ASPxComboBox ID="cboSubTipoServs" runat="server" HelpText="" ValueField="id_tipo_subtipos" TextField="nome" SelectedValue=""></dx:ASPxComboBox>
                    </div>
               </div>

И в коде за мной есть:

Dim cross As New Hashtable()
    Dim divsCliente() As String

    Dim lstDivs As List(Of campos_agd_form)
    lstDivs = campos_agd_form_mapper.CarregarDivs()

    If lstDivs IsNot Nothing Then
        For Each i In lstDivs
            cross.Add(i.id, i.id_div)
        Next
    End If

    Dim lstDivsCliente As List(Of clientes_campos_agd)
    lstDivsCliente = clientes_campos_agd_mapper.CarregarCamposCliente(guser.id)

    If lstDivsCliente IsNot Nothing Then
        divsCliente = (lstDivsCliente.Item(0).id_campos_enum).Split(",")
    End If
    'Dim divsCliente() As Integer = Convert.ToInt32((lstDivsCliente.id_divs).Split(","))

    For Each item In cross
        For Each i In divsCliente
            If item.Key = Convert.ToInt32(i) Then
                Dim div As System.Web.UI.HtmlControls.HtmlGenericControl
                div = TryCast(item.Value, System.Web.UI.HtmlControls.HtmlGenericControl)
                div.Visible = False
            End If
        Next
    Next

Поскольку я уже ожидал, что не могу преобразовать строку в объект HtmlObject, так что мне нужно сделать, это найти объект по нему id (строка), без необходимости проходить через родительский объект (в основном, искать весь документ, как и с javascript с getElementById)

Как это можно сделать?

Я использую среду.NET 4.0.

  • 0
    Вы пытались добавить родительский div (который является runat = "server") для ваших div и использовать его, чтобы найти div с определенным идентификатором? IE. parentDiv.FindControl ( "D0")?
  • 0
    Это потребовало бы, чтобы я добавил родительский div на всю страницу, я верю ... Я обновил свой aspx-код с более полным образцом, вместо одного div.
Теги:
.net-4.0

2 ответа

1
Лучший ответ

Итак, я закончил делать что-то по-другому.

В основном я использую ClientScriptManager и строю массив с скрываемыми элементами. (Который затем передается на клиентскую сторону).

Таким образом, теперь функция выглядит так:

Private Sub ManipulaFormCliente()
    Dim cross As New Hashtable()
    Dim divsCliente() As String = New String() {}
    Dim aux() As String = New String() {}
    Dim cs As ClientScriptManager = Page.ClientScript

    Dim lstDivs As List(Of campos_agd_form)
    lstDivs = campos_agd_form_mapper.CarregarDivs()

    If lstDivs IsNot Nothing Then
        For Each i In lstDivs
            cross.Add(i.id, i.id_div)
        Next
    End If

    Dim lstDivsCliente As List(Of clientes_campos_agd)
    lstDivsCliente = clientes_campos_agd_mapper.CarregarCamposCliente(" id_cliente = " & Convert.ToInt32(hidIdCliente.Value))

    If lstDivsCliente IsNot Nothing Then
        If lstDivsCliente.Count <> 0 Then
            divsCliente = (lstDivsCliente.Item(0).id_campos_enum).Split(",")
        End If
    End If

    For Each item In cross
        For Each i In divsCliente
            If item.Key = Convert.ToInt32(i) Then
                cs.RegisterArrayDeclaration("divsCliente", "'" & item.Value & "'")
            End If
        Next
    Next
End Sub

Затем на стороне клиента я выполнил функцию, которая запускается после того, как окно загрузилось, и использует массив, построенный на основе кода, для применения css "display: none" в divs, чьи идентификаторы передаются по массиву.

Код следующий:

window.onload = function hideFields() {
        if (divsCliente.length > 0) {
            for (var i = 0; i < divsCliente.length; i++) {
                document.getElementById(divsCliente[i]).style.display = 'none';
            }
        }
    }

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

В качестве последнего штриха мне пришлось добавить атрибут "clientidmode =" static "" в divs, чтобы функция getElementById() работала должным образом (согласно данным в БД)

Надеюсь, это поможет любому, кто нуждается в аналогичном решении.

  • 0
    Это работает, если JavaScript включен. Но имейте в виду, что вы генерируете много лишнего HTML, который не нужен. Если HTML не нужен, вы не должны генерировать его в первую очередь. Также пользователь может легко изменить поля, потому что они находятся в html (только скрытые), так что это может создать проблему безопасности. Если действительно пользователь не должен иметь возможность изменять эти поля, они не должны быть в HTML.
  • 0
    Я прекрасно знаю об этом сценарии. Но дополнительные div-ы действительно необходимы (так как я не хочу, чтобы элементы управления исчезали), и пользователи этого приложения (очень специфическая интранет-штука), как правило, слишком тупы в технических вопросах, поэтому это решение работает нормально, хотя и не идеально
1

Рекомендую следующий подход.

Вам нужно знать, какая информация должна отображаться для каждого пользователя, поэтому вы можете захотеть сохранить это в сессии, например (Global.asax):

Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
    ' Fetch from DB
    Session("Rights") = {"MyID1", "MyID3"}
End Sub

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

Imports System.Linq

Public MustInherit Class MyBaseControl
    Inherits System.Web.UI.UserControl

    Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
        If Page.IsPostBack Then Return

        Dim rights As String() = CType(Session("Rights"), String())
        If Not rights.Any((Function(s) s = Me.ID)) Then Me.Visible = False
    End Sub
End Class

Затем создайте x количество элементов управления содержимым, которые наследуются от этого базового элемента управления. Эти элементы управления могут иметь совершенно другой контент, но подумайте о том, чтобы сделать как можно меньше, поскольку ваши D0, D1 и т.д., Похоже, имеют почти одинаковый контент. Поэтому просто настройте элемент управления для обработки разных текстов и значений:

Public Class MyControl1
    Inherits MyBaseControl
End Class

Затем на странице вы будете иметь как можно больше из этих элементов управления:

<div>
    <uc1:MyControl1 ID="MyID1" runat="server" />
    <uc2:MyControl2 ID="MyID2" runat="server" />
    <uc3:MyControl3 ID="MyID3" runat="server" />
</div>

Надеюсь это поможет.

  • 0
    Это кажется возможным подходом, но в итоге я использовал другой подход, который я опубликую через минуту

Ещё вопросы

Сообщество Overcoder
Наверх
Меню