Лучший способ справиться с множественным выбором DropDown - PullRequest
4 голосов
/ 24 сентября 2011

enter image description here

У меня есть меню с несколькими DropDowns.Я добавил код, но в настоящее время он полностью находится в файле code-behind.Я хочу использовать любой шаблон проектирования, чтобы легко и беспрепятственно обрабатывать различные варианты.

Критерии формирования отчета подготовлены следующим образом:

Параметры типа отчета DropDown включают в себя:

  1. Схема по типу
  2. Схема
  3. Район
  4. Блок
  5. Все

По умолчанию включен только первый DropDown.При выборе параметра из этого DropDown включаются соответствующие DropDown.

Кроме того, значения Scheme, District и Block DropDowns также изменяются, когда элемент выбирается из любого из этих DropDowns или Scheme Type DropDown с использованием AJAX .

Он включает в себя различные запросы SQL и часто включает / отключает DropDowns.Мой нынешний код загроможден многими IF и EndIfs.

Я хочу знать, будет ли Observer pattern или какой-либо подход с использованием Classes использоваться для упрощения этой операции.Есть ли способ сделать этот множественный выбор и заполнение DropDowns управляемым и простым?

Отредактировано ниже для уточнения требований

Позвольте мне уточнить далее.

first DropDown - это ключ DropDown, который включается по умолчанию при открытии страницы.Все остальные DropDowns по умолчанию отключены.Но это не означает, что каскадный DropDown является правильным выбором, поскольку выбор из дочерних DropDowns является случайным.

Весь план состоит в том, чтобы упростить код в понятной форме для каждого DropDown.Для выбора правильного запроса требуется много If и ElseIf.

Например: пользователь выбирает District-wise report из основного типа отчета DropDown.В этом случае активируются три дочерних DropDown, а именно:

Scheme Type

Scheme

District

Если пользователь выбирает «ALL» из списка типов схем, все типы схем во всех категориях заполняются в DropDown схемы.

Если пользователь выбирает определенный тип схемы из опций: Городская, Сельская или Другая, DropDown схемы отфильтровывает названия схем.

Теперь в DropDown схемы также есть опция ALL.Пользователь может выбрать ВСЕ или выбрать любую конкретную схему.

То же самое с Районом.Если выбрано ВСЕ, схемы в схеме DropDown принимают все схемы во всех районах, но если выбран конкретный район, схема DropDown должна заполнять отфильтрованные схемы этого района.

Обратите внимание, что в этом случаеСейчас мы движемся в обратном порядке, потому что район DropDown снова фильтрует DropDown схемы.

То же самое применимо к Block DropDown.

Существуют различные условия, которые необходимо проверить, кроме выбранныхвариант.Предположим, что пользователь не выбрал какую-либо опцию или пользователь выбирает ALL.

Я хочу создать отдельные классы с именами каждого DropDown.Эти классы должны продолжать слышать уведомления (Наблюдатель) о любых изменениях в DropDown.

Полагаю, я смог уточнить.

Ответы [ 5 ]

5 голосов
/ 01 октября 2011

Использование AJAX Control Toolkit - это решение, соответствующее вашим требованиям.

В AJAX Control Toolkit есть CascadingDropDown Control

Синтаксис тега:

<ajaxToolkit:CascadingDropDown ID="ddlReportType" runat="server"
    TargetControlID="ddlSchemeType"
    Category="SchemeType"
    PromptText="Please select a ReportType"
    LoadingText="[Loading Report Types...]"
    ServicePath="ReportService.asmx"
    ServiceMethod="GetDropDownReportTypeContents"
    ParentControlID="DropDownList1"
    SelectedValue="SomeValue" />

А затем вам нужно создать веб-службу и несколько веб-методов, которые имеют следующую сигнатуру метода,

[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public CascadingDropDownNameValue[] GetDropDownReportTypeContents(
       string knownTypeValues, string typevalue) { ... }

UPDATE

Вы должны сделать что-то подобное, используя if-Else-If, ответ дан на предположениях и является просто примером для реализаций.

    string query = "SELECT * FROM Reports";
    List<string> filters = new List<string>();
    bool ReportType = true;
    bool SchemeType = true;
    bool Scheme = true;
    bool District = true;
    bool Block = true;

    if (ReportType)
        filters.Add("ReportType = true");
    if (SchemeType)
        filters.Add("SchemeType = true");
    if (Scheme)
        filters.Add("Scheme = true");
    if (District)
        filters.Add("District = true");
    if (Block)
        filters.Add("Block = true");

    if (filters.Count() > 0)
    {
        query = query + " WHERE " + string.Join(" AND ", filters.ToArray());
    }

Я надеюсь, что мой ответ поможет вам

Спасибо и всего наилучшего

Harsh Baid

2 голосов
/ 03 октября 2011

Не совсем то, что вы ищете, но вы можете проверить, как я решил похожую проблему в mvc с помощью jQuery.То же самое может быть достигнуто в веб-формах с использованием веб-методов вместо действий mvc.

Это история из 3 частей, и код доступен в bitbucket.Вы можете начать с части 2, так как сначала создайте демонстрационное приложение и настройте базу данных.

http://blog.goranobradovic.com/2011/06/asp-net-mvc3-app-part-2-ajax-cascading-dropdown/

Есть рабочий пример для 2 выпадающих меню, но я использовал одно и то же решение для 3 и 4без проблем.

ОБНОВЛЕНИЕ Поскольку у вас есть доступный источник, я добавлю только соответствующие строки для изменения здесь.Корректировка для предотвращения множественных вызовов ajax будет заключаться в том, чтобы сначала поместить значения параметров в id выбора (или id в значения, которые не имеют значения), или вы можете использовать некоторый атрибут в зависимом раскрывающемся списке, если вы не можете изменить идентификаторы и значения, но я буду сохранятьэто просто например.Затем, в событии изменения основного раскрывающегося списка, вы проверяете, нужно ли загружать цель:

$('#' + target.attr('cascading-dependson')).change(function () {
        if($(this).find("option:selected").val() == $(target).attr("id")){ // this is added if
            $(target).removeAttr("disabled");  // added
            selectFromAjax($(target).attr('cascading-loadfrom'),
            { id: $(this).find("option:selected").val() },
            target);
        }
        else {  //added
            $(target).attr("disabled", "disabled");
        }
    });

Вы можете легко изменить это, если использовать какой-либо пользовательский атрибут select, если вы не хотите использовать id.

ОБНОВЛЕНИЕ 2 Я только что увидел, что вы обновили вопрос.Как я вижу, есть случай, когда вам нужно обновить все зависимые выпадающие списки.Для этого вам нужно иметь идентификаторы всех выпадающих списков, которые необходимо обновить в последнем значении главного параметра выбора, разделенных, т. Е. С помощью «,», так что вы можете проверить, равен ли какой-либо из его val().split(",") идентификатор зависимого раскрывающегося списка,или вы можете иметь атрибут в зависимости, который содержит значения всех опций, для которых он должен обновляться.Вы видите в моем коде, что опции для selectFromAjax - это выбранное значение в выпадающем списке и имя основного поля.Поскольку вам, вероятно, здесь нужно иметь какое-то значение, которое будет обрабатываться серверным кодом, я предлагаю использовать второй способ, а именно - добавить настраиваемый атрибут в раскрывающийся список зависимостей, в который вы поместите значения релевантных опций выбора из master,для этого поля и зависимые должны загружаться при выборе.

Вы понимаете, что я предлагаю?

2 голосов
/ 27 сентября 2011

Поскольку кажется, что вы можете делать все это на стороне клиента, используя Javascript, почему вы так часто запрашиваете свою базу данных? Вы должны сохранить данные клиента и сервера. Вы можете вызывать все связанные раскрывающиеся данные, кэшировать их, а со стороны клиента вызывать WebMethod, который возвращает JSON с нужными вам данными. Для персистентности объектов на стороне сервера вы должны проверить Entity Framework 4.1, где каждый объект является представлением таблицы.

Я бы использовал jQuery с Knockout JS или просто jQuery для него, сохраняя данные на стороне клиента с помощью JSON, и нет необходимости возвращаться на сервер SQL.

Вот хороший пример Knockout JS в действии.
http://knockoutjs.com/examples/cartEditor.html

Конечно, если эти данные не изменяются слишком часто.

1 голос
/ 07 мая 2012

Существует простой способ добиться этого, следуйте этому подходу: во-первых, просто добавьте AjaxUpdatePanel ..., а затем в раскрывающемся списке установите свойство AutoPostBack в true, а затем просто добавьте обработчик события OnSelectedIndexChanged, чтобы включить второе удалениевниз ..

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate><asp:DropDownList id="firstDrpDown" AutoPostBack="true"  
 OnSelectedIndexChanged="firstDropDown_SelectedIndexChanged"AppendDataBoundItems="true"
   name="firstDropDown" runat="server">

<asp:DropDownList id="scndDrpDown" **AutoPostBack="true"**  
OnSelectedIndexChanged="scndDropDown_SelectedIndexChanged" AppendDataBoundItems="true"   
name="scndDropDown" runat="server" > 

 </ContentTemplate>
  <asp:UpdatePanel>
1 голос
/ 27 сентября 2011

Если я правильно понимаю вашу парадигму, действительно, у вас есть один раскрывающийся список (тип отчета), который определяет, следует ли выбирать по типу схемы, схеме, району или блоку (или всем вышеперечисленным). Если у вас нет есть опция «Все», я бы предложил либо иметь только два раскрывающихся списка (один для Типа отчета и один, чья метка изменяется в соответствии), либо исключить раскрывающийся список Тип отчета и поставить переключатель рядом с остальными, чтобы выбрать, какой вы хотите. Включая опцию «Все», вы можете не усложнять ситуацию намного сложнее; например, вы можете добавить еще одну радиокнопку и включить все четыре раскрывающихся списка.

Однако вы спрашиваете о паттерне наблюдателя. Начиная с GoF , шаблон наблюдателя полезен, когда:

  1. Абстракция имеет два аспекта, один зависит от другого;
  2. Изменение одного объекта требует изменения других, и вы не знаете, сколько объектов нужно изменить; или
  3. Объект должен иметь возможность уведомлять другие объекты, не делая предположений о том, кто эти объекты.

Я не совсем уверен, что любая из этих ситуаций применима здесь. Вторая ситуация имеет некоторые сходства с вашей проблемой, но вы делаете знаете, что нужно изменить и как. Если вы выполняете только обновление по типу отчета, это просто вопрос включения или отключения правого раскрывающегося меню. Однако вы говорите, что другие выпадающие списки влияют друг на друга, возможно, в опции «Все». Даже в этом случае я не уверен, что шаблон наблюдателя сам по себе является наиболее полезным. Поскольку вы заполняете раскрывающиеся списки с помощью SQL, я предполагаю, что вы можете использовать ряд различных хранимых процедур (или специальных запросов) в зависимости от того, какие параметры вам нужны. Вместо этого я могу предложить только один запрос в раскрывающемся списке, разумно используя NULL. Например, чтобы заполнить Блок другими значениями, вам может потребоваться:

CREATE PROCEDURE GetBlocks
(
    @SchemeTypeId INT NULL,
    @SchemeId INT NULL,
    @DistrictId INT NULL
)
AS
SELECT b.BlockId, b.BlockName
FROM   Blocks b
INNER JOIN SchemeTypeBlocks stb ON b.BlockId = stb.BlockId
INNER JOIN SchemeBlocks sb ON b.BlockId = sb.BlockId
INNER JOIN DistrictBlocks db ON b.BlockId = db.BlockId
WHERE  (@SchemeTypeId IS NULL OR stb.SchemeTypeId = @SchemeTypeId)
AND    (@SchemeId IS NULL OR sb.SchemeId = @SchemeId)
AND    (@DistrictId IS NULL OR db.DistrictId = @DistrictId)
ORDER BY b.BlockName

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

Если это не ответит на ваш вопрос, дайте мне знать, что я могу уточнить.

...