mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-07-16 07:04:52 +08:00
8225: Adding a checkbox to StringFilterForm to control whether an empty value should cause the filter to be skipped (#8781)
* Adding a checkbox to StringFilterForm to control whether an empty value should cause the filter to be skipped * Removing StringOperator.ContainsAnyIfProvided as its now obsolete due to the IgnoreFilterIfValueIsEmpty checkbox setting * Code styling in StringFilterForm * Adding missing T-string * Adding migration step to upgrade from using the ContainsAnyIfProvided operator in StringFilterForm
This commit is contained in:
parent
04e9c73391
commit
3a6810ec67
@ -7,7 +7,6 @@ using Orchard.Forms.Services;
|
|||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
|
|
||||||
namespace Orchard.Projections.FilterEditors.Forms {
|
namespace Orchard.Projections.FilterEditors.Forms {
|
||||||
|
|
||||||
public class StringFilterForm : IFormProvider {
|
public class StringFilterForm : IFormProvider {
|
||||||
public const string FormName = "StringFilter";
|
public const string FormName = "StringFilter";
|
||||||
|
|
||||||
@ -20,9 +19,7 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Describe(DescribeContext context) {
|
public void Describe(DescribeContext context) {
|
||||||
Func<IShapeFactory, object> form =
|
object form(IShapeFactory shape) {
|
||||||
shape => {
|
|
||||||
|
|
||||||
var f = Shape.Form(
|
var f = Shape.Form(
|
||||||
Id: "StringFilter",
|
Id: "StringFilter",
|
||||||
_Operator: Shape.SelectList(
|
_Operator: Shape.SelectList(
|
||||||
@ -36,8 +33,14 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
Title: T("Value"),
|
Title: T("Value"),
|
||||||
Classes: new[] { "text medium", "tokenized" },
|
Classes: new[] { "text medium", "tokenized" },
|
||||||
Description: T("Enter the value the string should be.")
|
Description: T("Enter the value the string should be.")
|
||||||
)
|
),
|
||||||
);
|
_IgnoreIfEmptyValue: Shape.Checkbox(
|
||||||
|
Id: "IgnoreFilterIfValueIsEmpty",
|
||||||
|
Name: "IgnoreFilterIfValueIsEmpty",
|
||||||
|
Title: T("Ignore filter if value is empty"),
|
||||||
|
Description: T("When enabled, the filter will not be applied if the provided value is or evaluates to empty."),
|
||||||
|
Value: "true"
|
||||||
|
));
|
||||||
|
|
||||||
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.Equals), Text = T("Is equal to").Text });
|
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.Equals), Text = T("Is equal to").Text });
|
||||||
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.NotEquals), Text = T("Is not equal to").Text });
|
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.NotEquals), Text = T("Is not equal to").Text });
|
||||||
@ -49,15 +52,11 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.Ends), Text = T("Ends with").Text });
|
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.Ends), Text = T("Ends with").Text });
|
||||||
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.NotEnds), Text = T("Does not end with").Text });
|
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.NotEnds), Text = T("Does not end with").Text });
|
||||||
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.NotContains), Text = T("Does not contain").Text });
|
f._Operator.Add(new SelectListItem { Value = Convert.ToString(StringOperator.NotContains), Text = T("Does not contain").Text });
|
||||||
f._Operator.Add(new SelectListItem {
|
|
||||||
Value = Convert.ToString(StringOperator.ContainsAnyIfProvided),
|
|
||||||
Text = T("Contains any word (if any is provided)").Text
|
|
||||||
});
|
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
};
|
}
|
||||||
|
|
||||||
context.Form(FormName, form);
|
context.Form(FormName, (Func<IShapeFactory, object>)form);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +64,11 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
var op = (StringOperator)Enum.Parse(typeof(StringOperator), Convert.ToString(formState.Operator));
|
var op = (StringOperator)Enum.Parse(typeof(StringOperator), Convert.ToString(formState.Operator));
|
||||||
object value = Convert.ToString(formState.Value);
|
object value = Convert.ToString(formState.Value);
|
||||||
|
|
||||||
|
if (bool.TryParse(formState.IgnoreFilterIfValueIsEmpty?.ToString() ?? "", out bool ignoreIfEmpty)
|
||||||
|
&& ignoreIfEmpty
|
||||||
|
&& string.IsNullOrWhiteSpace(value as string))
|
||||||
|
return (ex) => { };
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case StringOperator.Equals:
|
case StringOperator.Equals:
|
||||||
return x => x.Eq(property, value);
|
return x => x.Eq(property, value);
|
||||||
@ -92,14 +96,6 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
return y => y.Not(x => x.Like(property, Convert.ToString(value), HqlMatchMode.End));
|
return y => y.Not(x => x.Like(property, Convert.ToString(value), HqlMatchMode.End));
|
||||||
case StringOperator.NotContains:
|
case StringOperator.NotContains:
|
||||||
return y => y.Not(x => x.Like(property, Convert.ToString(value), HqlMatchMode.Anywhere));
|
return y => y.Not(x => x.Like(property, Convert.ToString(value), HqlMatchMode.Anywhere));
|
||||||
case StringOperator.ContainsAnyIfProvided:
|
|
||||||
if (string.IsNullOrWhiteSpace((string)value))
|
|
||||||
return x => x.IsNotEmpty("Id"); // basically, return every possible ContentItem
|
|
||||||
var values3 = Convert.ToString(value)
|
|
||||||
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
var predicates3 = values3.Skip(1)
|
|
||||||
.Select<string, Action<IHqlExpressionFactory>>(x => y => y.Like(property, x, HqlMatchMode.Anywhere)).ToArray();
|
|
||||||
return x => x.Disjunction(y => y.Like(property, values3[0], HqlMatchMode.Anywhere), predicates3);
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
@ -130,11 +126,6 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
return T("{0} does not end with '{1}'", fieldName, value);
|
return T("{0} does not end with '{1}'", fieldName, value);
|
||||||
case StringOperator.NotContains:
|
case StringOperator.NotContains:
|
||||||
return T("{0} does not contain '{1}'", fieldName, value);
|
return T("{0} does not contain '{1}'", fieldName, value);
|
||||||
case StringOperator.ContainsAnyIfProvided:
|
|
||||||
return T("{0} contains any of '{1}' (or '{1}' is empty)",
|
|
||||||
fieldName,
|
|
||||||
new LocalizedString(string.Join("', '",
|
|
||||||
value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))));
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
@ -151,7 +142,6 @@ namespace Orchard.Projections.FilterEditors.Forms {
|
|||||||
NotStarts,
|
NotStarts,
|
||||||
Ends,
|
Ends,
|
||||||
NotEnds,
|
NotEnds,
|
||||||
NotContains,
|
NotContains
|
||||||
ContainsAnyIfProvided
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Contents.Extensions;
|
using Orchard.Core.Contents.Extensions;
|
||||||
@ -15,13 +14,16 @@ namespace Orchard.Projections {
|
|||||||
public class Migrations : DataMigrationImpl {
|
public class Migrations : DataMigrationImpl {
|
||||||
private readonly IRepository<MemberBindingRecord> _memberBindingRepository;
|
private readonly IRepository<MemberBindingRecord> _memberBindingRepository;
|
||||||
private readonly IRepository<LayoutRecord> _layoutRepository;
|
private readonly IRepository<LayoutRecord> _layoutRepository;
|
||||||
|
private readonly IRepository<FilterRecord> _filterRepository;
|
||||||
|
|
||||||
public Migrations(
|
public Migrations(
|
||||||
IRepository<MemberBindingRecord> memberBindingRepository,
|
IRepository<MemberBindingRecord> memberBindingRepository,
|
||||||
IRepository<LayoutRecord> layoutRepository) {
|
IRepository<LayoutRecord> layoutRepository,
|
||||||
|
IRepository<FilterRecord> filterRepository) {
|
||||||
_memberBindingRepository = memberBindingRepository;
|
_memberBindingRepository = memberBindingRepository;
|
||||||
_layoutRepository = layoutRepository;
|
_layoutRepository = layoutRepository;
|
||||||
|
_filterRepository = filterRepository;
|
||||||
|
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,8 +361,8 @@ namespace Orchard.Projections {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int UpdateFrom5() {
|
public int UpdateFrom5() {
|
||||||
SchemaBuilder.AlterTable("LayoutRecord", t => t.AddColumn<string>("GUIdentifier",
|
SchemaBuilder.AlterTable("LayoutRecord", t => t
|
||||||
column => column.WithLength(68)));
|
.AddColumn<string>("GUIdentifier", column => column.WithLength(68)));
|
||||||
|
|
||||||
var layoutRecords = _layoutRepository.Table.Where(l => l.GUIdentifier == null || l.GUIdentifier == "").ToList();
|
var layoutRecords = _layoutRepository.Table.Where(l => l.GUIdentifier == null || l.GUIdentifier == "").ToList();
|
||||||
foreach (var layout in layoutRecords) {
|
foreach (var layout in layoutRecords) {
|
||||||
@ -369,5 +371,20 @@ namespace Orchard.Projections {
|
|||||||
|
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int UpdateFrom6() {
|
||||||
|
// This casts a somewhat wide net, but filters can't be queried by the form they are using and different
|
||||||
|
// types of filters can (and do) use StringFilterForm. However, the "Operator" parameter's value being
|
||||||
|
// "ContainsAnyIfProvided" is very specific.
|
||||||
|
var formStateToReplace = "<Operator>ContainsAnyIfProvided</Operator>";
|
||||||
|
var filterRecordsToUpdate = _filterRepository.Table.Where(f => f.State.Contains(formStateToReplace)).ToList();
|
||||||
|
foreach (var filter in filterRecordsToUpdate) {
|
||||||
|
filter.State = filter.State.Replace(
|
||||||
|
formStateToReplace,
|
||||||
|
"<Operator>ContainsAny</Operator><IgnoreFilterIfValueIsEmpty>true</IgnoreFilterIfValueIsEmpty>");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user