Inter connected drop-downs not working episerver - dojo

So I have followed this tutorial
https://world.episerver.com/blogs/Duong-Nguyen/Dates/2014/1/Country-Region-drop-down-lists-in-All-properties-mode/
in my effort to create dependent drop downs.
public class LocationBlock : BlockData
{
[SelectOne(SelectionFactoryType = typeof(CountrySelectionFactory))]
public virtual string Country { get; set; }
[SelectOne(SelectionFactoryType = typeof(RegionSelectionFactory))]
[ClientEditor(ClientEditingClass = "alloy/editors/FilterableSelectionEditor", SelectionFactoryType = typeof(RegionSelectionFactory))]
public virtual string Region { get; set; }
}
public class ArticlePage : StandardPage
{
[Display(GroupName = "IndexData")]
public virtual LocationBlock Location { get; set; }
}
class CountrySelectionFactory : ISelectionFactory
{
public IEnumerable GetSelections(ExtendedMetadata metadata)
{
return new Country[]
{
new Country() { CountryCode = "US", Name = "United States" },
new Country() { CountryCode = "SE", Name = "Sweden" }
};
}
}
class RegionSelectionFactory : ISelectionFactory
{
public IEnumerable GetSelections(ExtendedMetadata metadata)
{
return new Region[]
{
new Region() { CountryCode = "US", RegionCode = "NY", Name = "New York" },
new Region() { CountryCode = "US", RegionCode = "CA", Name = "California" },
new Region() { CountryCode = "SE", RegionCode = "AB", Name = "Stockholm" },
new Region() { CountryCode = "SE", RegionCode = "O", Name = "Västra Götaland" }
};
}
}
class Country : ISelectItem
{
public string CountryCode { get; set; }
public string Name { get; set; }
public string Text
{
get
{
return Name;
}
}
public object Value
{
get
{
return CountryCode;
}
}
}
class Region : ISelectItem
{
public string CountryCode { get; set; }
public string RegionCode { get; set; }
public string Name { get; set; }
public string Text
{
get
{
return Name;
}
}
public object Value
{
get
{
return String.Format("{0}-{1}", CountryCode, RegionCode);
}
}
}
[EditorDescriptorRegistration(TargetType = typeof(LocationBlock))]
public class LocationBlockEditorDescriptor : EditorDescriptor
{
public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable attributes)
{
base.ModifyMetadata(metadata, attributes);
metadata.Properties.Cast().First().GroupSettings.ClientLayoutClass = "alloy/LocationBlockContainer";
metadata.Properties.Cast().First().ClientEditingClass = "alloy/editors/FilterableSelectionEditor";
}
}
After that I created a ClientResources folder in my root. Under that I created Scripts folder and placed LocationBlockConatiner there and under Scripts I created another folder named Editors and placed my FilterableSelectionEditor there.
I created a module.config file and the code in it looks like this
LocationBlockContainer is this
define([
"dojo/_base/declare",
"dojo/_base/lang",
"epi/shell/layout/SimpleContainer"
],
function (
declare,
lang,
SimpleContainer
) {
return declare([SimpleContainer], {
countryDropdown: null,
regionDropdown: null,
addChild: function (child) {
// Summar: Add a widget to the container
this.inherited(arguments);
if (child.name.indexOf("country") >= 0) {
// If it's the country drop down list
this.countryDropdown = child;
// Connect to change event to update the region drop down list
this.own(this.countryDropdown.on("change", lang.hitch(this, this._updateRegionDropdown)));
} else if (child.name.indexOf("region") >= 0) {
// If it's the region drop down list
this.regionDropdown = child;
// Update the region drop down
this._updateRegionDropdown(this.countryDropdown.value);
}
},
_updateRegionDropdown: function (country) {
console.log(1);
if (country !== "" && this.previousCountry === "") {
this.previousCountry = country;
}
// Clear the current value
if (country !== this.previousCountry) {
this.regionDropdown.set("value", null);
this.previousCountry = country;
}
console.log(this.regionDropdown);
// Set the filter
this.regionDropdown.set("filter", function (region) {
console.log(region);
return region.value.indexOf(country) === 0;
});
}
});
});
FilterableSelectionEditor.js is this
define([
"dojo/_base/declare",
"dojo/_base/array",
"epi-cms/contentediting/editors/SelectionEditor"
],
function (
declare,
array,
SelectionEditor
) {
return declare([SelectionEditor], {
_allOptions: null,
filter: null,
_setOptionsAttr: function (options) {
// summary: set the options
this._allOptions = options;
this.inherited(arguments, [array.filter(options, this.filter || function () {
// return all options if no filter function provided.
return true;
}, this)]);
},
_setFilterAttr: function (filter) {
// summary: set the option filter function
this._set("filter", filter);
this.set("options", this._allOptions);
}
});
});
It doesn't seem to work. When I select Country the Regions are emptied and then every region is added again because the end result shows all the regions no matter what country I have selected.
Any help here would be really appreciated.

Related

Add <a> link for every node in JTree using Asp.Net Core

how i can add a tag link to every node(root or children) in JTree, I Fetch data from database with EFCore
and i want to every node have link like this:
<a class="btn btn-primary" asp-action="TaskTypeDetail" asp-controller="Admin" asp-route-TaskTypeNumber=#item.TaskTypeNumber>details</a>
mycontroller like this :
public class TreeviewController : Controller
{
private readonly RoleManager<IdentityRole> roleManager;
private readonly UserManager<ApplicationUser> userManager;
private readonly ApplicationDbContext applicationDbContext;
public TreeviewController(RoleManager<IdentityRole> roleManager, UserManager<ApplicationUser> userManager, ApplicationDbContext applicationDbContext)
{
this.roleManager = roleManager;
this.userManager = userManager;
this.applicationDbContext = applicationDbContext;
}
public IActionResult Index()
{
return View();
}
public JsonResult GetRoot()
{
List<JsTreeModel> items = GetTree();
return new JsonResult ( items );
}
public JsonResult GetChildren(string id)
{
List<JsTreeModel> items = GetTree(id);
return new JsonResult ( items );
}
public List<JsTreeModel> GetTree()
{
bool checkchildren;
var items = new List<JsTreeModel>();
foreach (var role in roleManager.Roles)
{
foreach (var user in userManager.Users)
{
checkchildren = false;
var checkUserInRole = userManager.IsInRoleAsync(user, role.Name).Result;
if (checkUserInRole)
{
var checkEmployeeForUser = applicationDbContext.EmployeeInRoles.Where(s => s.RoleId == role.Id).ToList();
if (checkEmployeeForUser.Count > 0)
{
checkchildren = true;
}
items.Add(new JsTreeModel { id = user.Id.ToString(), parent = "#", text = user.Name+" "+user.Family+" ریشه " , children = checkchildren,a_attr=""});
}
}
}
// set items in here
return items;
}
public List<JsTreeModel> GetTree(string id)
{
var items = new List<JsTreeModel>();
// set items in here
//Loop and add the Child Nodes.
bool checkchildren;
string Role="";
foreach (var subType in applicationDbContext.EmployeeInRoles)
{
checkchildren = false;
string Parentid = "";
foreach (var findParent in userManager.Users)
{
var roleid = roleManager.FindByIdAsync(subType.RoleId);
var checkParent = userManager.IsInRoleAsync(findParent, roleid.Result.Name).Result;
if (checkParent) {
Parentid = findParent.Id;
}
}
var user = userManager.Users.SingleOrDefault(s => s.Id == subType.UserId);
foreach(var role in roleManager.Roles)
{
var checkUserInRole = userManager.IsInRoleAsync(user, role.Name).Result;
if (checkUserInRole)
{
Role = role.Id;
break;
}
}
var checkEmployeeForUser = applicationDbContext.EmployeeInRoles.Where(s => s.RoleId == Role).ToList();
if (checkEmployeeForUser.Count > 0)
{
checkchildren = true;
}
items.Add(new JsTreeModel { id = subType.Id.ToString(), parent = Parentid, text = user.Name + " " + user.Family, children=checkchildren});
}
return items;
}
}
JsTreeModel like this:
public class JsTreeModel
{
public string id { get; set; }
public string parent { get; set; }
public string text { get; set; }
public string a_attr { get; set; }
public bool children { get; set; } // if node has sub-nodes set true or not set false
}
and Index.cshtml
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<div id='treeview'></div>
<script>
$('#treeview').jstree({
"plugins": ["search","contextmenu"],
'core': {
'data': {
'url': function (node) {
return node.id === '#' ? "/Treeview/GetRoot" : "/Treeview/GetChildren/" + node.id;
},
'data': function (node) {
return {'id': node.id };
}
}
}
});
$('#treeview').on('changed.jstree', function (e, data) {
console.log("=> selected node: " + data.node.id);
});
but every node that show me, when I click on it, doesn't have link and # instead of link
can any one help me ?

Bad request fetching json from razor post with fullcalendar

I have implemented full calendar. It does show as it supposed to, but fetching data goes wrong
.cshtml
<div id='calendar'></div>
.cshtml.cs
public class IndexModel : PageModel
{
public JsonResult OnPost(DateTime start, DateTime end)
{
return new JsonResult(new
{
url = "something",
title = "something else",
start = ConvertToUnixTimestamp(DateTime.Now).ToString(),
end = ConvertToUnixTimestamp(DateTime.Now.AddDays(2)).ToString(),
allDay = false,
backgroundColor = "red",
textColor = "green"
});
}
}
.js
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
events: {
url: '/Overview/Employee/Index',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
method: 'POST'
},
plugins: ['dayGrid']
});
calendar.render();
});
When i load the page, i see a request happening, but it returns a 400, bad request. Any idea why?
The request:
I tried your code without 400 error( use #Html.AntiForgeryToken() in the form), but the event is not added to the calendar successfully. It works when I return a List Model, try to use below code to add events:
public class EventModel
{
public int id { get; set; }
public string start { get; set; }
public string end { get; set; }
public string title { get; set; }
public bool allDay { get; set; }
public string url { get; set; }
public string color { get; set; }
public string textColor { get; set; }
}
public class IndexModel : PageModel
{
public JsonResult OnPost(DateTime start, DateTime end)
{
IEnumerable<EventModel> events = new List<EventModel>()
{
new EventModel()
{
url = "something",
title = "something else",
start = (DateTime.Now).ToString(),
end = (DateTime.Now.AddDays(2)).ToString(),
allDay = false,
color = "red",
textColor = "green"
}
};
return new JsonResult(events);
}
}
Results:

dropdown population with viewmodel asp.net mvc

i am new in MVC. so when see code to understand then some time confusion occur. here i am giving a code. so please see the code first.
public class ProductViewModel
{
public int ID { set;get;}
public string Name { set;get;}
}
public class OrderViewModel
{
private List<ProductViewModel> _products;
public int OrderNumber { set; get; }
public List<ProductViewModel> Products
{
get
{
if (_products == null)
{
_products = new List<ProductViewModel>();
_products.Add(new ProductViewModel { ID = 1, Name = "Ketchup" });
_products.Add(new ProductViewModel { ID = 1, Name = "Mustard" });
_products.Add(new ProductViewModel { ID = 1, Name = "Relish" });
_products.Add(new ProductViewModel { ID = 1, Name = "Mayo" });
}
return _products;
}
}
public int SelectedProductId { set;get;}
}
public ActionResult Order()
{
OrderViewModel orderVM = new OrderViewModel();
return View(orderVM);
}
#model ORderViewModel
#using (Html.BeginForm())
{
<p>
#Html.DropDownListFor(x => x.SelectedProductId , new SelectList(Model.Products, "Value", "Text"), "-- Select Product--")
</p>
}
my question is can i place this code public int SelectedProductId { set;get;} in ProductViewModel instead of OrderViewModel.
if it is possible then what to change in code and in view html ?

How to assign value to Address , Country and City

Here is classes
-Person
-User
-City
-Country
-Address
Person has complex properties of (Address),
Address has complex Properties of (Country , City)
Class User inherited from Person class
scenario:-
I want to create a signup view inwhich i want to assign values to Address , country , city. How can i do it.
Below is the detail of classes
public class Person
{
public Person()
{ }
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private Gender gender;
public virtual Gender Gender
{
get { return gender; }
set { gender = value; }
}
private ICollection<ContactNumber> contactNumber;
public virtual ICollection<ContactNumber> ContactNumber
{
get { return contactNumber; }
set { contactNumber = value; }
}
private Address address;
public virtual Address Address
{
get { return address; }
set { address = value; }
}
private DateTime dateOfBirth;
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set { dateOfBirth = value; }
}
private string picture;
public string Picture
{
get { return picture; }
set { picture = value; }
}
}
public class User : Person
{
public User() : base()
{ }
private ICollection<Role> roles;
public virtual ICollection<Role> Roles
{
get { return roles; }
set { roles = value; }
}
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string email;
[Required()]
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*")]
[Display(Name = "Email Address")]
public string Email
{
get { return email; }
set { email = value; }
}
private string loginId;
[Required()]
[Display(Name = "Login")]
public string LoginId
{
get { return loginId; }
set { loginId = value; }
}
private string password;
[Required()]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string Password
{
get { return password; }
set { password = value; }
}
private string repassword;
[Required()]
[Display(Name = "Confirm Password")]
[Compare("Password")]
public string Repassword
{
get { return repassword; }
set { repassword = value; }
}
private string secretQuestion;
[Required()]
[Display(Name = "Secret Question")]
public string SecretQuestion
{
get { return secretQuestion; }
set { secretQuestion = value; }
}
private string secretAnswer;
[Required()]
[Display(Name = "Answer")]
public string SecretAnswer
{
get { return secretAnswer; }
set { secretAnswer = value; }
}
private string photoUrl;
[Display(Name = "Image")]
public string PhotoUrl
{
get { return photoUrl; }
set { photoUrl = value; }
}
}
public class Country
{
public Country()
{ }
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
//private string flagUrl;
}
public class City
{
public City()
{ }
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private Country country;
public virtual Country Country
{
get { return country; }
set { country = value; }
}
}
Thanx in Advance.
If you right click on your action method for your signup page in your controller and select Add View In the dialog that appears you can choose to make the view strongly typed. Select your User class and visual studio will scaffold a lot of the code needed.
If you need more help in working with MVC here is a good place to start.

DropDownList with possible nested DropDownList in MVC4

I have a set of questions the user can choose from and some of those questions have a secondary list of options to choose from. My goal is to have a drop down list and if you pick one of the options that has items in its SecondaryChoiceList then a second list would appear below the initial dropdown and all of this would be strongly typed and bound to the model upon submission.
I can get the initial list to appear by saying:
#Html.DropDownListFor( x => x.SelectedChoiceId, new SelectList(Model.Choices, "Id", "Name"))
But that has no hooks to the secondary list and I am completely lost as to how I would tie that secondary list back to the model that is returned when I submit the form.
Here's my view model:
public class ExampleViewModel
{
public List<Choice> ChoiceList { get; set; }
public int SelectedChoiceId { get; set; }
public int SelectedAffiliateId { get; set; }
}
Here is what a Choice looks like:
public class Choice
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<SecondaryChoice> SecondaryChoiceList { get; set; }
public Choice()
{
SecondaryChoiceList = new List<SecondaryChoice>();
}
}
And here is my SecondaryChoice object:
public class EligibleAffiliate
{
public int Id { get; set; }
public int EligibilityChoiceId { get; set; }
public string Name { get; set; }
}
If there is anything that I can clear up let me know.
I have tried to keep it as simple as possible.
So, a sample model is given below:
namespace StackOverflow.Models
{
public class Choice
{
public int Id { get; set; }
public string Name { get; set; }
public Choice()
{
Id = 0;
}
public Choice(int id, string name)
{
Id = id;
Name = name;
}
}
}
namespace StackOverflow.Models
{
public class ExampleViewModel
{
public List<Choice> PrimaryChoiceList { get; set; }
public List<Choice> SecondaryChoiceList { get; set; }
public int SelectedChoiceId { get; set; }
public int SelectedAffiliateId { get; set; }
public ExampleViewModel()
{
SelectedChoiceId = 0;
SelectedAffiliateId = 0;
PrimaryChoiceList = new List<Choice>()
{
new Choice(1, "How are you?"),
new Choice(2, "How is the weahter?"),
new Choice(3, "What have you been doing so far?"),
new Choice(4, "What's up man?"),
new Choice(5, "Any news?"),
new Choice(5, "Bla bla bla")
};
SecondaryChoiceList = new List<Choice>()
{
new Choice(1, "How are you dear?"),
new Choice(2, "How is the weahter?"),
new Choice(3, "What have you been doing so far dear?"),
new Choice(4, "What's up man?"),
new Choice(5, "Any romantic news?")
};
}
}
}
Sample controller:
namespace StackOverFlow.Controllers
{
public class SOController : Controller
{
public static ExampleViewModel evm = new ExampleViewModel();
public ActionResult Index()
{
return View(evm);
}
public ActionResult SetSelection(int id)
{
evm.SelectedChoiceId = id;
if (evm.PrimaryChoiceList.Count() > 0)
{
Choice selection = evm.PrimaryChoiceList.ElementAt(id-1);
Choice affiliate = (Choice)evm.SecondaryChoiceList.FirstOrDefault(x => x.Name == selection.Name);
if (affiliate != null)
{
return Content("show");
}
else
{
return Content("hide");
}
}
else
{
return Content("hide");
}
}
}
}
And the web page:
#using StackOverflow2.Models;
#model ExampleViewModel
<script src="#Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
#{
ViewBag.Title = "Stackoverflow Sample";
}
<h2>Index</h2>
<script type="text/javascript">
// Get the selection and make Ajax Request to the controller, action: SetSelection,
// which in turn may decide whetger you must show or hide the control
function updateSeconadryQuestion(id) {
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText == 'show')
$('#SecondaryQuestionDropBoxId').show();
else
$('#SecondaryQuestionDropBoxId').hide();
}
}
xmlhttp.open("GET", "/SO/SetSelection?id=" + id, true);
xmlhttp.send();
}
</script>
#Html.DropDownListFor(x => x.SelectedChoiceId, new SelectList(Model.PrimaryChoiceList, "Id", "Name", "Value"), new { id = "PrimaryQuestionDropBoxId", onchange = "updateSeconadryQuestion(value);" })
<div id="SeconadryQuestionDivId">
#Html.DropDownListFor(x => x.SelectedAffiliateId, new SelectList(Model.SecondaryChoiceList, "Id", "Name"), new { id = "SecondaryQuestionDropBoxId" })
</div>