AjaxDropdown

AjaxDropdown needs an url, js func or controller to get data from, by default convention it will look for a controller with the same name as it + "AjaxDropdown"
Parent Category:
Child Meal:
AjaxDropdownDemo/Index.cshtml
<div class="efield einlf">
<div class="elabel">Parent Category:</div>
@(Html.Awe().AjaxDropdown("ParentCategory")
.Url(Url.Action("GetCategories", "Data")))
</div>
<div class="efield einlf">
<div class="elabel">Child Meal:</div>
@(Html.Awe().AjaxDropdown("ChildMeal")
.Parent("ParentCategory", "categories")
.Url(Url.Action("GetMeals", "Data")))
</div>

Bound to many parents

+
+
=
=
AjaxDropdownDemo/Index.cshtml
@Html.Awe().AjaxRadioListFor(o => o.Category1).Url(Url.Action("GetCategories", "Data"))
+
@Html.Awe().AjaxCheckboxList("Categories").Url(Url.Action("GetCategories", "Data"))+
@Html.Awe().TextBox("txtMealName").Placeholder("where name contains").CssClass("searchtxt")
=
@(Html.Awe().AjaxDropdownFor(o => o.ChildOfManyMeal)
.Controller<MealBoundToManyController>()
.Parent(o => o.Category1)
.Parent("Categories")
.Parent("txtMealName", "mealName"))
=
@(Html.Awe().AjaxRadioList("ChildOfManyMealRadioList")
.Controller<MealBoundToManyController>()
.Parent(o => o.Category1)
.Parent("Categories")
.Parent("txtMealName", "mealName"))
parent Category1 and "Categories" are being merged together and received by the controller as int[] parent
Awesome/AjaxDropdown/MealBoundToManyController.cs
using System.Linq;
using Microsoft.AspNetCore.Mvc;

using AweCoreDemo.Models;

using Omu.AwesomeMvc;
using System.Threading.Tasks;
using AweCoreDemo.Data;
using AweCoreDemo.Utils;

namespace AweCoreDemo.Controllers.Awesome.AjaxDropdown
{
public class MealBoundToManyController : Controller
{
private readonly MyContext mcx = new MyContext();// mock EF Db context

public MealBoundToManyController()
{

}

public async Task<IActionResult> GetItems(int[] parent, string mealName = "")
{
parent = parent ?? new int[] { };

var meals = await mcx.Meals
.Where(o => (parent.Contains(o.Category.Id)) && o.Name.Contains(mealName))
.ToArrayAsync();

return Json(meals.Select(o => new KeyContent(o.Id, o.Name)));
}
}
}

Set size and cascade


AjaxDropdownDemo/Index.cshtml
@{
var size5 = new Dictionary<string, string> { { "size", "5" } };
}
<style>
.autoh .awe-field select {
height: auto;
}
</style>
<div class="autoh">
<div class="einlf">
@(Html.Awe().AjaxDropdown("ParentCategorySz")
.EditorHtmlAttributes(size5)
.Url(Url.Action("GetCategories", "Data")))
</div>
<div class="einlf">
@(Html.Awe().AjaxDropdown("ChildMealSz")
.EditorHtmlAttributes(size5)
.Parent("ParentCategorySz", "categories")
.Url(Url.Action("GetMeals", "Data")))
</div>
<br />
@Html.Awe().AjaxDropdown("a3").DataFunc("getWords").EditorHtmlAttributes(size5)
@Html.Awe().AjaxDropdown("b3").DataFunc("getWords").Parent("a3").EditorHtmlAttributes(size5)
@Html.Awe().AjaxDropdown("c3").DataFunc("getWords").Parent("b3").EditorHtmlAttributes(size5)
@Html.Awe().AjaxDropdown("d3").DataFunc("getWords").Parent("c3").EditorHtmlAttributes(size5)
@Html.Awe().AjaxDropdown("e3").DataFunc("getWords").Parent("d3").EditorHtmlAttributes(size5)
@Html.Awe().AjaxDropdown("f3").DataFunc("getWords").Parent("e3").EditorHtmlAttributes(size5)
</div>
<script>
function getWords(params) {
var pobj = aweUtils.getParams(params);
var items = ["The", "brown", "cow", "is eating", "green", "grass"];

var parent = (pobj.parent || '') + ' ';
return awef.select(items,
function (o) {
var res = parent + ' ' + o;
return { k: res, c: res };
});
}
</script>

Set value from get items call

AjaxDropdownDemo/Index.cshtml
@(Html.Awe().AjaxDropdown("CategorySv")
.Url(Url.Action("GetCategories", "Data")))

@(Html.Awe().AjaxDropdown("MealsSv")
.Parent("CategorySv", "categories")
.Url(Url.Action("GetMealsSetValue2", "Data")))
Awesome/DataController.cs
public IActionResult GetMealsSetValue2(int[] categories)
{
categories = categories ?? new int[] { };

var items = mcx.Meals.Where(o => categories.Contains(o.Category.Id)).ToList();

object value = null;
if (items.Any())
{
value = items.Skip(1).First().Id;
}

return Json(new AweItems
{
Items = items.Select(o => new KeyContent(o.Id, o.Name)),
Value = value
});
}

Using enum for dropdown items

AjaxDropdownDemo/Index.cshtml
@(Html.Awe().AjaxDropdown("EnumAdd").Url(Url.Action("GetWeatherEnumItems", "Data")))
Awesome/DataController.cs
public IActionResult GetWeatherEnumItems()
{
var type = typeof(WeatherType);
var items = Enum.GetValues(type).Cast<int>().Select(o => new KeyContent(o, SplitByCapLetter(Enum.GetName(type, o)))).ToList();

// remove if not needed
items.Insert(0, new KeyContent(string.Empty, "please select"));

return Json(items);
}

/// <summary>
/// from HiThere to Hi There
/// </summary>
private string SplitByCapLetter(string s)
{
var r = new Regex(@"
(?<=[A-Z])(?=[A-Z][a-z]) |
(?<=[^A-Z])(?=[A-Z]) |
(?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);

return r.Replace(s, " ");
}

Using predefined parameters

setting parameter parent = { Fruits, Legumes } using .Parameter and .ParameterFunc extensions
AjaxDropdownDemo/Index.cshtml
@(Html.Awe().AjaxDropdownFor(o => o.Meal1)
.Parameter("categories", cat1.Id)
.ParameterFunc("giveParams")
.Url(Url.Action("GetMeals", "Data")))
<script>
function giveParams() {
return { categories: @(cat2.Id) };
}
</script>

Events and Api






Using client side api to change the dropdown value, disable and enable it and load with additional parameters that are sent to the server.
aweload event is handled to flash the #log div whenever the dropdown loads.
The same api methods can be used for the AjaxRadioList, AjaxCheckboxList controls and their mods.
AjaxDropdownDemo/Index.cshtml
    @{
var meal1 = DemoCache.Meals[1];
var meal2 = DemoCache.Meals[2];
}

@(Html.Awe().AjaxDropdown("ddApi")
.Url(Url.Action("ApiGetMeals", "Data")))

<br />
<br />
@Html.Awe().Button().Text("Change value to " + meal1.Name).OnClick("app1.changeval(" + meal1.Id + ")")
@Html.Awe().Button().Text("Change value to " + meal2.Name).OnClick("app1.changeval(" + meal2.Id + ")")

@Html.Awe().Button().Text("Load only first category").OnClick("app1.loadFirstCat()")
@Html.Awe().Button().Text("Reload").OnClick("app1.reload()")
@Html.Awe().Button().Text("Toggle Enable").OnClick("app1.toggleEnable()")

<br />
<br />

<div id="log">
</div>

@section scripts
{
<script>
var app1;

$(function () {
var dd = $('#ddApi');

var o = dd.data('o');
var api = o.api;

app1 = {
changeval: function (newVal) {
dd.val(newVal).trigger('change');
},
reload: function () {
api.load();
},
loadFirstCat: function () {
api.load({ oparams: { cat1: true } });
// oparams sets cat1 just for this call
// params sets persistent parameters
},
toggleEnable: function () {
api.enable(!o.enb);
}
};

dd.on('aweload', function (e, data) {
awe.flash($('#log').html('loaded ' + data.length + ' items'));
});
});
</script>
}
Awesome/DataController.cs
public IActionResult ApiGetMeals(int? v, bool? cat1)
{
var items = (cat1 == true) ?
mcx.Meals.Where(o => o.Category == mcx.Categories.First()).ToArray() :
mcx.Meals.ToArray();

return Json(items.Select(o => new KeyContent(o.Id, o.Name)));
}



Comments