Skip to content

Commit

Permalink
Merge pull request #30 from blackWins/optimization
Browse files Browse the repository at this point in the history
Optimize the request logic
  • Loading branch information
gdlcf88 authored Dec 29, 2023
2 parents 4f4ac87 + 6b41a2f commit 1c1cd3b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ public class SearchBookViewModel
textPropertyName: "name",
alternativeTextPropertyName: "userName",
hideSubText: false,
runScriptOnWindowLoad: true // Please set to true if the item is not in a modal.
runScriptOnWindowLoad: true, // Please set to true if the item is not in a modal.
minimumInputLength: 1, // The minimum number of characters required to start a search
delay: 500, // The delay time between the last key stroke and the request is sent to the server
enableCache: true // Enable cache to reduce the number of requests
)]
public Guid UserId { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class EasySelectorAttribute : Attribute
/// </summary>
/// <example>/api/identity/users</example>
public string GetListedDataSourceUrl { get; set; }

/// <summary>
/// Url to get single data.
/// Use <code>{id}`</code> as the key.
Expand All @@ -27,7 +27,7 @@ public class EasySelectorAttribute : Attribute
/// Used to be the display text of the option.
/// </summary>
public string TextPropertyName { get; set; }

/// <summary>
/// Used to be the display text of the option if the text property is null.
/// </summary>
Expand All @@ -49,14 +49,20 @@ public class EasySelectorAttribute : Attribute
/// Hide the sub text (key) of items.
/// </summary>
public bool HideSubText { get; set; }

/// <summary>
/// Please set to true if the item is not in a modal.
/// </summary>
public bool RunScriptOnWindowLoad { get; set; }

public string FilterParamName { get; set; }


public int Delay { get; set; }

public int MinimumInputLength { get; set; }

public bool EnableCache { get; set; }

public EasySelectorAttribute(
[NotNull] string getListedDataSourceUrl,
[NotNull] string getSingleDataSourceUrl,
Expand All @@ -68,7 +74,10 @@ public EasySelectorAttribute(
[NotNull] string filterParamName = "filter",
int maxResultCount = 10,
bool hideSubText = false,
bool runScriptOnWindowLoad = false)
bool runScriptOnWindowLoad = false,
int delay = 250,
int minimumInputLength = 0,
bool enableCache = false)
{
GetListedDataSourceUrl = getListedDataSourceUrl;
GetSingleDataSourceUrl = getSingleDataSourceUrl;
Expand All @@ -81,6 +90,9 @@ public EasySelectorAttribute(
HideSubText = hideSubText;
RunScriptOnWindowLoad = runScriptOnWindowLoad;
FilterParamName = filterParamName;
Delay = delay;
MinimumInputLength = minimumInputLength;
EnableCache = enableCache;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ protected override List<SelectListItem> GetSelectItems(TagHelperContext context,

return easySelectorAttribute != null ? new List<SelectListItem>() : base.GetSelectItems(context, output);
}

protected override string SurroundInnerHtmlAndGet(TagHelperContext context, TagHelperOutput output, string innerHtml)
{
var easySelectorAttribute = TagHelper.AspFor.ModelExplorer.GetAttribute<EasySelectorAttribute>();
Expand All @@ -89,7 +89,7 @@ protected override string SurroundInnerHtmlAndGet(TagHelperContext context, TagH
{
return base.SurroundInnerHtmlAndGet(context, output, innerHtml);
}

return "<div class=\"mb-3 form-group\">" +
Environment.NewLine +
GetSelect2ConfigurationCode(context, easySelectorAttribute) +
Expand All @@ -98,11 +98,11 @@ protected override string SurroundInnerHtmlAndGet(TagHelperContext context, TagH
Environment.NewLine +
"</div>";
}

protected virtual string GetSelect2ConfigurationCode(TagHelperContext context, EasySelectorAttribute easySelectorAttribute)
{
var styleCode = GetStyleCode(context, easySelectorAttribute);

var scriptCode = GetScriptCode(context, easySelectorAttribute);

return styleCode + scriptCode;
Expand All @@ -112,7 +112,7 @@ protected virtual string GetStyleCode(TagHelperContext context, EasySelectorAttr
{
return $"<style>.select2-selection__rendered{{line-height:48px !important;padding-left:1.25rem !important;}}.select2-selection__clear{{right:10px}} .select2-container .select2-selection--single{{height:48px !important;}}.select2-selection__arrow{{height:48px !important;right:10px !important}} .selection-subtext {{ padding-left: 10px; color: #808080 !important; font-size: smaller; }}</style>";
}

protected virtual string GetScriptCode(TagHelperContext context, EasySelectorAttribute easySelectorAttribute)
{
var currentValues = context.Items.First(x => !(x.Key is string)).Value;
Expand All @@ -131,8 +131,10 @@ protected virtual string GetScriptCode(TagHelperContext context, EasySelectorAtt

var dropdownParent = easySelectorAttribute.RunScriptOnWindowLoad ? "" : $"dropdownParent: $('#{tagId}').parent().parent(),";

var transport = easySelectorAttribute.EnableCache ? $",transport:function(params,success,failure){{if(!params.data.filter&&params.data.skipCount<{tagId.ToCamelCase()}cacheList.length){{return success({{totalCount:{tagId.ToCamelCase()}cacheList.length,{easySelectorAttribute.ItemListPropertyName}:{tagId.ToCamelCase()}cacheList}});}}if(params.data.filter&&{tagId.ToCamelCase()}cacheList.length&&params.data.skipCount<params.data.maxResultCount){{let matchList={tagId.ToCamelCase()}cacheList.filter(function(item){{return!params.data.filter||stringMatch(params.data.filter,item.name??item.userName);}});if(matchList.length>params.data.skipCount)return success({{totalCount:params.data.maxResultCount*2,{easySelectorAttribute.ItemListPropertyName}:matchList}});}}if(params.data.skipCount != 0 && {tagId.ToCamelCase()}cacheList.length > params.data.skipCount - params.data.maxResultCount){{params.data.skipCount -= params.data.maxResultCount;}}var $request=$.ajax(params);$request.then((res)=>{{res.{easySelectorAttribute.ItemListPropertyName} = res.{easySelectorAttribute.ItemListPropertyName}.filter(v => {{ return {tagId.ToCamelCase()}cacheList.every(e => e.{easySelectorAttribute.KeyPropertyName} != v.{easySelectorAttribute.KeyPropertyName}); }});{tagId.ToCamelCase()}cacheList = [...{tagId.ToCamelCase()}cacheList, ...res.{easySelectorAttribute.ItemListPropertyName}];success(res);}});$request.fail(failure);return $request;}}" : "";

var baseUrl = configuration?.BaseUrl;
var innerCode = $"$(function () {{ let currentValues = {_jsonSerializer.Serialize(currentValues)}; function stringMatch(term,candidate){{return candidate&&candidate.toLowerCase().indexOf(term.toLowerCase())>=0}}; function matchCustom(params,data){{if($.trim(params.term)===\"\"){{return data}}if(typeof data.text===\"undefined\"){{return null}}if(stringMatch(params.term,data.text)){{return data}}if(stringMatch(params.term,state.id)){{return data}}return null}}; let select2Item = function (state) {{ return $('<span>' + state.text{subTextContent} + '</span>'); }}; let select2Option = {{ allowClear: true, width: \"100%\", matcher: matchCustom, templateResult: select2Item, templateSelection: select2Item,{dropdownParent} ajax: {{ url: '{baseUrl}{easySelectorAttribute.GetListedDataSourceUrl}', dataType: \"json\", delay: 250, data: function (params) {{ params.page = params.page || 1; return {{ {easySelectorAttribute.FilterParamName}: params.term, skipCount: (params.page - 1) * {easySelectorAttribute.MaxResultCount}, maxResultCount: {easySelectorAttribute.MaxResultCount}, }} }}, processResults: function (data, params) {{ params.page = params.page || 1; return {{ results: data.{easySelectorAttribute.ItemListPropertyName}.map(function (item) {{ return {{ id: item.{easySelectorAttribute.KeyPropertyName}, text: item.{easySelectorAttribute.TextPropertyName} ?? item.{easySelectorAttribute.AlternativeTextPropertyName} }} }}), pagination: {{ more: (params.page * {easySelectorAttribute.MaxResultCount}) < data.totalCount }} }}; }}, cache: true }}, placeholder: {{ id: '', text: '{placeHolder}' }} }}; $(\"#{tagId}\").select2(select2Option); currentValues && currentValues.values.forEach(function(e) {{ if (!$(\"#{tagId}\").find('option:contains(' + e + ')').length && (e != \"00000000-0000-0000-0000-000000000000\" && e != \"\" && e != \"0\")) abp.ajax({{ type: 'GET', url: '{baseUrl}{easySelectorAttribute.GetSingleDataSourceUrl}'.replace('{{id}}', e), success: function (result) {{ $(\"#{tagId}\").append($('<option value=\"' + e + '\">').text(result.{easySelectorAttribute.TextPropertyName} ?? result.{easySelectorAttribute.AlternativeTextPropertyName})); $(\"#{tagId}\").val(currentValues.values).trigger('change'); }}}}); }}); }});";
var innerCode = $"$(function () {{ let {tagId.ToCamelCase()}cacheList = [];let currentValues = {_jsonSerializer.Serialize(currentValues)}; function stringMatch(term,candidate){{return candidate&&candidate.toLowerCase().indexOf(term.toLowerCase())>=0}}; function matchCustom(params,data){{if($.trim(params.term)===\"\"){{return data}}if(typeof data.text===\"undefined\"){{return null}}if(stringMatch(params.term,data.text)){{return data}}if(stringMatch(params.term,state.id)){{return data}}return null}}; let select2Item = function (state) {{ return $('<span>' + state.text{subTextContent} + '</span>'); }}; let select2Option = {{ allowClear: true,minimumInputLength:{easySelectorAttribute.MinimumInputLength}, width: \"100%\", matcher: matchCustom, templateResult: select2Item, templateSelection: select2Item,{dropdownParent} ajax: {{ url: '{baseUrl}{easySelectorAttribute.GetListedDataSourceUrl}', dataType: \"json\", delay: {easySelectorAttribute.Delay}, data: function (params) {{ params.page = params.page || 1; return {{ {easySelectorAttribute.FilterParamName}: params.term, skipCount: (params.page - 1) * {easySelectorAttribute.MaxResultCount}, maxResultCount: {easySelectorAttribute.MaxResultCount}, }} }}{transport}, processResults: function (data, params) {{ params.page = params.page || 1; return {{ results: data.{easySelectorAttribute.ItemListPropertyName}.map(function (item) {{ return {{ id: item.{easySelectorAttribute.KeyPropertyName}, text: item.{easySelectorAttribute.TextPropertyName} ?? item.{easySelectorAttribute.AlternativeTextPropertyName} }} }}), pagination: {{ more: (params.page * {easySelectorAttribute.MaxResultCount}) < data.totalCount }} }}; }}, cache: true }}, placeholder: {{ id: '', text: '{placeHolder}' }} }}; $(\"#{tagId}\").select2(select2Option); currentValues && currentValues.values.forEach(function(e) {{ if (!$(\"#{tagId}\").find('option:contains(' + e + ')').length && (e != \"00000000-0000-0000-0000-000000000000\" && e != \"\" && e != \"0\")) abp.ajax({{ type: 'GET', url: '{baseUrl}{easySelectorAttribute.GetSingleDataSourceUrl}'.replace('{{id}}', e), success: function (result) {{ $(\"#{tagId}\").append($('<option value=\"' + e + '\">').text(result.{easySelectorAttribute.TextPropertyName} ?? result.{easySelectorAttribute.AlternativeTextPropertyName})); $(\"#{tagId}\").val(currentValues.values).trigger('change'); }}}}); }}); }});";

return easySelectorAttribute.RunScriptOnWindowLoad
? $"<script>window.addEventListener('load', function() {{{innerCode}}}, false)</script>"
Expand Down

0 comments on commit 1c1cd3b

Please sign in to comment.