У меня немного сложная проблема, и я не могу понять, как ее решить.
В принципе, у меня есть пара таблиц в моей базе данных, которые, идентифицируют по клиенту, с которыми делятся идентификаторы, к которым клиент имеет доступ, с помощью вкладки
Поэтому у меня есть таблица, которая идентифицирует 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.
Итак, я закончил делать что-то по-другому.
В основном я использую 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() работала должным образом (согласно данным в БД)
Надеюсь, это поможет любому, кто нуждается в аналогичном решении.
Рекомендую следующий подход.
Вам нужно знать, какая информация должна отображаться для каждого пользователя, поэтому вы можете захотеть сохранить это в сессии, например (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>
Надеюсь это поможет.