Hi,
I have the following example code:
@page "/qb"
@using Syncfusion.Blazor.QueryBuilder
@using Syncfusion.Blazor.DropDowns
<div class="col-lg-12 control-section">
<SfQueryBuilder TValue="ExpenseData" Width="100%" DataSource="@DataSource" @ref="QueryBuilderRef">
<QueryBuilderEvents TValue="ExpenseData" Created="QueryBuilderCreated"></QueryBuilderEvents>
@* <QueryBuilderRule Condition="and" Rules="@Rules"></QueryBuilderRule> *@
<QueryBuilderColumns>
<QueryBuilderColumn Field="PaymentMode" Label="PaymentMode" Type=Syncfusion.Blazor.QueryBuilder.ColumnType.String>
<QueryBuilderTemplates>
<ValueTemplate>
@{
string value = (string)context.Value;
if (value == "")
{
value = DefaultValue;
context.Value = DefaultValue;
}
}
<SfDropDownList TValue="string" TItem="ItemFields" DataSource="@Items" @bind-Value="@value">
<DropDownListFieldSettings Text="Id" Value="Id"></DropDownListFieldSettings>
<DropDownListEvents TItem="ItemFields" TValue="string" ValueChange="e => OnChange(e, context)"></DropDownListEvents>
</SfDropDownList>
</ValueTemplate>
</QueryBuilderTemplates>
</QueryBuilderColumn>
<QueryBuilderColumn Field="Category" Label="Category" Type=Syncfusion.Blazor.QueryBuilder.ColumnType.String></QueryBuilderColumn>
<QueryBuilderColumn Field="Description" Label="Description" Type=ColumnType.String></QueryBuilderColumn>
<QueryBuilderColumn Field="Amount" Label="Amount" Type=Syncfusion.Blazor.QueryBuilder.ColumnType.Number></QueryBuilderColumn>
</QueryBuilderColumns>
</SfQueryBuilder>
<button @onclick="GetQueryAsSql">Get query as sql</button>
<p>@QueryAsSql</p>
</div>
@code{
protected SfQueryBuilder<ExpenseData> QueryBuilderRef { get; set; }
public string DefaultValue = "Cash";
public List<ExpenseData> DataSource;
public class ExpenseData
{
public string Category { get; set; }
public string PaymentMode { get; set; }
public string Description { get; set; }
public int Amount { get; set; }
}
protected override void OnInitialized()
{
DataSource = new List<ExpenseData>()
{
new ExpenseData() {Category= "Food", PaymentMode="Credit Card", Description="Boiled peanuts", Amount=100 },
new ExpenseData() {Category= "Food", PaymentMode="Debit Card", Description="Boiled peanuts", Amount=200 },
new ExpenseData() {Category= "Food", PaymentMode="Cash", Description="Confederate cush", Amount=300 },
new ExpenseData() {Category= "Transportation", PaymentMode="Cash", Description="Public and other transportation", Amount=150 },
new ExpenseData() {Category= "Transportation", PaymentMode="Debit Card", Description="Public and other transportation", Amount=250 }
};
}
public class ItemFields
{
public string Id { get; set; }
}
public List<ItemFields> Items = new List<ItemFields>() {
new ItemFields(){ Id= "Cash" },
new ItemFields(){ Id= "Debit Card" },
new ItemFields(){ Id= "Credit Card" },
new ItemFields(){ Id= "Net Banking" }
};
public void OnChange(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, ItemFields> args, RuleModel Rule)
{
Rule.Value = args.Value;
}
// List<RuleModel> Rules = new List<RuleModel>()
// {
// new RuleModel { Label="PaymentMode", Field="PaymentMode", Type="String", Operator="equal", Value="Debit Card" },
// new RuleModel { Label="Category", Field="Category", Type="String", Operator="equal", Value="Food" },
// new RuleModel { Label="Amount", Field="Amount", Type="Number", Operator="notequal" }
// };
protected Task QueryBuilderCreated()
{
QueryBuilderRef.SetRulesFromSql("PaymentMode = 'Debit Card'");
// Get the rules & display in the UI as SQL
var rules = QueryBuilderRef.GetRules();
QueryAsSql = QueryBuilderRef.GetSqlFromRules(rules);
return Task.CompletedTask;
}
public string QueryAsSql { get; set; }
protected void GetQueryAsSql()
{
var rules = QueryBuilderRef.GetRules();
if (rules is null)
{
QueryAsSql = "(null rules)";
}
else
{
QueryAsSql = QueryBuilderRef.GetSqlFromRules(rules);
}
}
}
If I run the code and change the operator to "In", I get an exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'string' to 'string[]'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at Syncfusion.Blazor.QueryBuilder.Internal.QueryBuilderRules`1.SetOperator()
at Syncfusion.Blazor.QueryBuilder.Internal.QueryBuilderRules`1.OnParametersSetAsync()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
How can I use a dropdown for single-selection, but also allow multi-selection with "In" op
Hi Darren,
We have validated your reported query and prepared the sample based on your requirement. Please refer the below code snippet.
|
<ValueTemplate> @{ string opr = (string)context.Operator; } @if (opr == "in" || opr == "notin") { <SfMultiSelect TValue="string[]" TItem="ItemFields" Placeholder="Select a Value" Mode="VisualMode.CheckBox" DataSource="@Items" AllowFiltering="true" FilterType="FilterType.Contains" PopupHeight="230px" > <MultiSelectEvents TItem="ItemFields" TValue="string[]" ValueChange="e => ValueChangeMultiList(e, context)"></MultiSelectEvents> <MultiSelectFieldSettings Text="Id" Value="Id"></MultiSelectFieldSettings> </SfMultiSelect> } else { string value = (string)context.Value; if (value == "") { value = DefaultValue; context.Value = DefaultValue; } <SfDropDownList TValue="string" TItem="ItemFields" DataSource="@Items" @bind-Value="@value"> <DropDownListFieldSettings Text="Id" Value="Id"></DropDownListFieldSettings> <DropDownListEvents TItem="ItemFields" TValue="string" ValueChange="e => OnChange(e, context)"></DropDownListEvents> </SfDropDownList> } </ValueTemplate> |
Could you please check with the above code and get back to us, if you need any further assistance on this.
Regards,
YuvanShankar A
That's great - thanks YuvanShankar! It would be nice if the querybuilder supported this functionality "out of the box" - I just provide a list of items and a default & the querybuilder creates the dropdowns and multiselect automatically - but I'm glad it's possible with this code.
You are welcome, Darren. We are happy to hear that your requirement has been fulfilled. Please get back to us if you need any further assistance on this.