This commit is contained in:
2022-05-23 17:28:34 +01:00
parent 56f6b0bb7e
commit 25386026af
86 changed files with 2395 additions and 664 deletions
+12
View File
@@ -261,6 +261,18 @@ namespace Saxonite.Net.Core.Web.Base.App
return GetCodeTypeCaption(Sax.CodeType.OrganisationRole, organisationRole);
}
// Address types.
public String GetAddressTypeCaption(Sax.AddressType addressType)
{
return GetCodeTypeCaption(Sax.CodeType.AddressType, addressType);
}
// Contact Method.
public String GetContactMethodCaption(Sax.ContactMethod contactMethod)
{
return GetCodeTypeCaption(Sax.CodeType.ContactMethod, contactMethod);
}
// Event type.
public String GetEventTypeCaption(Sax.EventType eventType)
{
@@ -122,6 +122,7 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
public List<TypeCodeDesc> OrganisationCategoryCodes { get { return Internals.OrganisationCategoryCodes; } }
public List<TypeCodeDesc> OrganisationRoleCodes { get { return Internals.OrganisationRoleCodes; } }
public List<TypeCodeDesc> AddressTypeCodes { get { return Internals.AddressTypeCodes; } }
public List<TypeCodeDesc> ContactMethodCodes { get { return Internals.ContactMethodCodes; } }
public List<TypeCodeDesc> EventTypeCodes { get { return Internals.EventTypeCodes; } }
public List<TypeCodeDesc> OpportunityTypeCodes { get { return Internals.OpportunityTypeCodes; } }
public List<TypeCodeDesc> ActivityReactionCodes { get { return Internals.ActivityReactionCodes; } }
@@ -486,6 +487,25 @@ namespace Saxonite.Net.Core.Web.Base.Controllers
/// <summary>Updated on date - formatted per locale</summary>
public String UpdatedOnFmt { get; set; }
}
/// <summary>Contact Method properties.</summary>
public class ContactMethodData
{
public String Method { get; set; }
public String MethodCaption { get; set; }
public String Value { get; set; }
}
/// <summary>Address properties.</summary>
public class AddressData : ItemData_Base
{
public String Line1 { get; set; }
public String Line2 { get; set; }
public String Line3 { get; set; }
public String Town { get; set; }
public String Province { get; set; }
public String RegionIdProvince { get; set; }
public String Country { get; set; }
public String PostalCode { get; set; }
}
/// <summary>
/// Item data with label and value.
/// </summary>
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Mvc.Rendering;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
@@ -58,6 +59,20 @@ namespace Saxonite.Net.Core.Web.Base.Models
public String PageCaption { get; set; }
public String InstanceVersion { get { return !StringUtil.IsEmpty(App.AppConfig.Instance) ? App.AppConfig.Instance + " v" + Sax.Version.GetFullVersion() : "v" + Sax.Version.GetAppVersion(); } }
public bool IncludeGoogleAnalytics { get; set; } = false;
// Views can be registered to avoid multiple inclusions in a page.
private HashSet<String> registeredViews = new HashSet<String>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Views can be registered to avoid multiple inclusions in a page.
/// <para>Only generate view content if this method returns true.</para>
/// </summary>
public bool RegisterView (String viewName)
{
#if DEBUG
if (registeredViews.Contains(viewName))
SaLogger.Warn(this.GetType().Name + ".RegisterView View already registered: " + viewName);
#endif
return registeredViews.Add(viewName);
}
//-------------------------------------------------------------------
// Business components.
@@ -83,6 +98,7 @@ namespace Saxonite.Net.Core.Web.Base.Models
public List<TypeCodeDesc> OrganisationCategoryCodes { get { return Internals.OrganisationCategoryCodes; } }
public List<TypeCodeDesc> OrganisationRoleCodes { get { return Internals.OrganisationRoleCodes; } }
public List<TypeCodeDesc> AddressTypeCodes { get { return Internals.AddressTypeCodes; } }
public List<TypeCodeDesc> ContactMethodCodes { get { return Internals.ContactMethodCodes; } }
public List<TypeCodeDesc> EventTypeCodes { get { return Internals.EventTypeCodes; } }
public List<TypeCodeDesc> OpportunityTypeCodes { get { return Internals.OpportunityTypeCodes; } }
public List<TypeCodeDesc> ActivityReactionCodes { get { return Internals.ActivityReactionCodes; } }
@@ -28,7 +28,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Construction.
public AjaxResponse_OrganisationActivationInfo(SaxModel_Admin model) : base(model) { }
// Organisation details.
public OrganisationData_Full organisation { get; } = new OrganisationData_Full();
public OrganisationItemData organisation { get; } = new OrganisationItemData();
// Member awaiting activation.
public List<MemberData_List> Members { get; } = new List<MemberData_List>();
}
@@ -69,8 +69,12 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Organisation address.
SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId());
disposableItems.Add(address);
// Construct response.
PopulateOrganisationResponseData(organisation, responseData.organisation);
PopulateOrganisationResponseItemData(organisation, address, responseData.organisation);
GetOrganisationMembers(model, organisationId, responseData.Members);
}
@@ -119,12 +123,16 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
SysId organisationId = model.OrganisationId.ToSysId();
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
disposableItems.Add(organisation);
if (organisation == null && SysId.IsValid(organisationId))
if (organisation == null)
{
SaLogger.Warn(fn + " Failed to retrieve organisation for. : '" + model.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Organisation address.
SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId());
disposableItems.Add(address);
// Retrieve users.
List<OrganisationMemberData> organisationMembersToActivate = new List<OrganisationMemberData>();
foreach (String userOrganisationId in model.OrganisationMemberIds)
@@ -206,7 +214,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
}
// Construct response.
PopulateOrganisationResponseData(organisation, responseData.organisation);
PopulateOrganisationResponseItemData(organisation, address, responseData.organisation);
}
// Complete response.
@@ -21,7 +21,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
{
//-------------------------------------------------------------------
// Organisation data.
private class OrganisationData_List : AjaxResponse_Data.ItemData_Base
private class OrganisationListData : AjaxResponse_Data.ItemData_Base
{
public String Name { get; set; }
public String TypeCode { get; set; }
@@ -38,12 +38,14 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Address.
public String AddressSummary { get; set; }
}
private class OrganisationData_Full : OrganisationData_List
private class OrganisationItemData : OrganisationListData
{
public String About { get; set; }
public String Facilities { get; set; }
public List<AjaxResponse_Data.ContactMethodData> ContactMethods { get; set; }
public AjaxResponse_Data.AddressData Address { get; set; }
}
private void PopulateOrganisationResponseData(SaxOrganisation organisation, OrganisationData_List data)
private void PopulateOrganisationResponseListData(SaxOrganisation organisation, OrganisationListData data)
{
data.Id = SysId.ToString(organisation.Id);
data.Name = organisation.Name;
@@ -64,11 +66,32 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
data.StatusCode = organisation.StatusCode;
data.StatusDesc = organisation.StatusDesc;
}
private void PopulateOrganisationResponseData(SaxOrganisation organisation, OrganisationData_Full data)
private void PopulateOrganisationResponseItemData(SaxOrganisation organisation, SaxItemAddress address, OrganisationItemData data)
{
PopulateOrganisationResponseData(organisation, data as OrganisationData_List);
PopulateOrganisationResponseListData(organisation, data as OrganisationListData);
data.About = organisation.About;
data.Facilities = organisation.Facilities;
// Contact methods.
SaxContactData contactData = new SaxContactData(organisation.ContactData);
foreach (Sax.ContactMethod method in contactData.Methods)
{
if (data.ContactMethods == null) data.ContactMethods = new List<AjaxResponse_Data.ContactMethodData>();
data.ContactMethods.Add(new AjaxResponse_Data.ContactMethodData() { Method = method.ToString(), MethodCaption = Localiser.GetContactMethodCaption(method), Value = contactData.GetContactMethodValue(method) });
}
// Address.
if (address != null)
{
data.Address = new AjaxResponse_Data.AddressData();
data.Address.Id = address.Id.ToString();
data.Address.Line1 = address.Line1;
data.Address.Line2 = address.Line2;
data.Address.Line3 = address.Line3;
data.Address.Town = address.Town;
data.Address.Province = address.Province;
data.Address.Country = address.Country;
data.Address.PostalCode = address.PostalCode;
}
// Common properties.
data.Notes = organisation.Notes;
}
@@ -80,8 +103,9 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Construction.
public AjaxResponse_OrganisationList(SaxModel_Admin model) : base(model) { }
// Organisation list.
public List<OrganisationData_List> Organisations { get; } = new List<OrganisationData_List>();
public List<OrganisationListData> Organisations { get; } = new List<OrganisationListData>();
// Reference data.
public List<AjaxResponse_Data.ItemCodeDesc> ContactMethods { get; } = new List<ItemCodeDesc>();
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
public String DefaultStatusCode { get; set; }
}
@@ -98,6 +122,15 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Reference data - contact methods.
List<Sax.ContactMethod> validContactMethods = SaxOrganisation.ValidContactMethods;
foreach (TypeCodeDesc contactMethod in ContactMethodCodes)
{
// Skip methods that aren't associated with Organisations.
if (!validContactMethods.Contains((Sax.ContactMethod)contactMethod.Type)) continue;
responseData.ContactMethods.Add(new AjaxResponse_Data.ItemCodeDesc() { Code = contactMethod.Code, Desc = Localiser.GetContactMethodCaption((Sax.ContactMethod)contactMethod.Type) });
}
// Reference data - statuses.
foreach (SaStatus status in SaxOrganisation.ValidStatuses.FindAll(item => item != SaStatus.Deleted))
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
@@ -149,7 +182,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
OrganisationData_List organisationData = new OrganisationData_List()
OrganisationListData organisationData = new OrganisationListData()
{
Id = values.GetLong(colId.DataName).ToString(),
Name = values.GetString(colName.DataName),
@@ -185,7 +218,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Construction.
public AjaxResponse_Organisation(SaxModel_Admin model) : base(model) { }
// Organisation details.
public OrganisationData_Full organisation { get; } = new OrganisationData_Full();
public OrganisationItemData organisation { get; } = new OrganisationItemData();
}
//-------------------------------------------------------------------
[HttpPost]
@@ -200,6 +233,10 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// Identify item.
SysId organisationId = model.OrganisationId.ToSysId();
if (!SysId.IsValid(organisationId))
@@ -207,18 +244,23 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Retrieve item.
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
disposableItems.Add(organisation);
if (organisation == null)
{
SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Organisation address.
SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId());
disposableItems.Add(address);
// Construct response.
PopulateOrganisationResponseData(organisation, responseData.organisation);
PopulateOrganisationResponseItemData(organisation, address, responseData.organisation);
// Complete response.
responseData.Success = true;
}
return Json(responseData);
}
@@ -237,6 +279,10 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
if (!ValidUserSession)
return GetAjaxResult_InvalidSession(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
// Validate item properties.
model.ValidateOrganisationData(responseData);
if (responseData.HasControlErrors())
@@ -245,6 +291,7 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Retrieve existing item.
SysId organisationId = model.OrganisationId.ToSysId();
SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId);
disposableItems.Add(organisation);
if (organisation == null && SysId.IsValid(organisationId))
{
SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'");
@@ -253,7 +300,14 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
// Create new item if required.
if (organisation == null)
{
organisation = AccountMgr.CreateOrganisation();
disposableItems.Add(organisation);
}
// Organisation address.
SaxItemAddress organisationAddress = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId());
disposableItems.Add(organisationAddress);
// Populate item properties.
if (model.OrganisationName != null)
@@ -270,6 +324,8 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
organisation.About = model.OrganisationAbout;
if (model.OrganisationFacilities != null)
organisation.Facilities = model.OrganisationFacilities;
if (model.ContactData != null)
organisation.ContactData = model.ContactData.GetContactData();
// Common properties.
if (model.OrganisationStatusCode != null)
organisation.Status = model.OrganisationStatus;
@@ -294,12 +350,77 @@ namespace Saxonite.Net.Core.Web.Admin.Controllers
}
}
if (model.Address.IsSpecified())
{
// Organisation regions.
SaxRegion.Data regionCountry = Internals.GetRegion(organisation.RegionIdPrimary);
if (regionCountry != null && regionCountry.RegionType != Sax.RegionType.Country)
regionCountry = null;
SaxRegion.Data regionProvince = null;
// Create Organisation address if required.
if (organisationAddress == null)
{
organisationAddress = ItemDataMgr.CreateItemAddress(organisation.GetItemId(), SaxItemAddress.DefaultOrganisationAddressType);
disposableItems.Add(organisationAddress);
}
// Store address.
if (model.Address.Line1 != null)
organisationAddress.Line1 = model.Address.Line1;
if (model.Address.Line2 != null)
organisationAddress.Line2 = model.Address.Line2;
if (model.Address.Line3 != null)
organisationAddress.Line3 = model.Address.Line3;
if (model.Address.Town != null)
organisationAddress.Town = model.Address.Town;
if (regionProvince != null)
{
organisationAddress.Province = regionProvince.Name;
organisationAddress.RegionIdProvince = regionProvince.Id;
}
else
{
if (model.Address.Province != null)
organisationAddress.Province = model.Address.Province;
}
if (regionCountry != null)
{
organisationAddress.Country = regionCountry.Name;
organisationAddress.RegionIdCountry = regionCountry.Id;
}
else
{
if (model.Address.Country != null)
organisationAddress.Country = model.Address.Country;
}
organisationAddress.PostalCode = model.Address.PostalCode;
if (!SysId.IsValid(organisationAddress.Id))
{
// Create new address.
if (!ItemDataMgr.InsertItemAddress(organisationAddress, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to insert organisation address - " + ItemDataMgr.ErrorStateMessage);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
}
else
{
// Update existing address.
if (!ItemDataMgr.UpdateItemAddress(organisationAddress, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update organisation address - " + ItemDataMgr.ErrorStateMessage);
return Json(responseData.SetGoHome(messageTitle, Localiser["msg.error.system"]));
}
}
}
// Construct response.
PopulateOrganisationResponseData(organisation, responseData.organisation);
PopulateOrganisationResponseItemData(organisation, organisationAddress, responseData.organisation);
// Complete response.
responseData.Success = true;
}
return Json(responseData);
}
@@ -0,0 +1,64 @@
using Microsoft.AspNetCore.Mvc;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Core.Web.Admin.Models;
using Saxonite.Net.Core.Web.Base.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Helpers;
using System;
namespace Saxonite.Net.Core.Web.Admin.Controllers
{
//=======================================================================
// Admin Reference Controller - Contact Method Ajax actions only.
//=======================================================================
partial class ReferenceController
{
//-------------------------------------------------------------------
// Validate Contact Method.
//-------------------------------------------------------------------
private class AjaxResponse_ValidateContactMethod : AjaxResponse_Data
{
public AjaxResponse_ValidateContactMethod(SaxModel_Base model) : base(model) { }
}
[HttpPost]
[Route("Reference/Ajax/ValidateContactMethod")]
public IActionResult Ajax_ValidateContactMethod(Model_ContactMethod model)
{
String fn = GetType().Name + ".Ajax_ValidateContactMethod";
String messageTitle = Localiser["caption.contact.method"];
AjaxResponse_ValidateContactMethod responseData = new AjaxResponse_ValidateContactMethod(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
// Validate method.
Sax.ContactMethod method = EnumUtil.ParseEnum(model.ContactMethod, Sax.ContactMethod.Unknown);
if (model.ContactMethod.IsEmpty() || (int)method < 1)
responseData.SetControlError(nameof(model.ContactMethod), Localiser["msg.validation.mandatory.value"]);
// Validate method.
if (model.ContactValue.IsEmpty())
responseData.SetControlError(nameof(model.ContactValue), Localiser["msg.validation.mandatory.value"]);
// Method specific value validation.
if (!SaxContactMethodHelper.IsValidContactMethodValue(method, model.ContactValue))
{
// Log invalid values so that the validation can be adjusted if needed.
SaLogger.Warn(fn + " Invalid contact method value. Mathod: " + method.ToString() + ". Value: " + model.ContactValue);
responseData.SetControlError(nameof(model.ContactValue), Localiser["msg.validation.invalid.value"]);
}
if (responseData.HasControlErrors())
return Json(responseData);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Admin.Controllers
{
//=======================================================================
// Admin Reference Controller - Ajax actions only.
//=======================================================================
public partial class ReferenceController : SaxController_Admin
{
//-------------------------------------------------------------------
// Construction.
public ReferenceController(SaxLocaliser localiser, ILogger<HomeController> logger) :
base(localiser, logger)
{}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,141 @@
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Base.App;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Admin.Models
{
//=======================================================================
/// <summary>
/// Address model data properties.
/// </summary>
public class ModelData_Address : ModelData_Admin
{
//-------------------------------------------------------------------
// Construction.
public ModelData_Address(SaxModel_Admin model, String controlNameSuffix) : base(model)
{
this.ControlNameSuffix = StringUtil.EmptyOnNull(controlNameSuffix) + "Address";
}
//-------------------------------------------------------------------
// Properties.
private String ControlNameSuffix { get; }
// Address properties.
public String Id { get; set; }
public String Line1 { get; set; }
public String Line2 { get; set; }
public String Line3 { get; set; }
public String Town { get; set; }
public String Province { get; set; }
public String RegionIdProvince { get; set; }
public String Country { get; set; }
public String PostalCode { get; set; }
//-------------------------------------------------------------------
// Utilities.
/// <summary>Have any address values been supplied by the form.</summary>
public bool IsSpecified()
{
if (Id != null || Line1 != null || Town != null || Province != null || Country != null || PostalCode != null)
return true;
return false;
}
//-------------------------------------------------------------------
// Validation.
//-------------------------------------------------------------------
// Address.
public bool ValidateAddressData(SaxController_Base.AjaxResponse_Data responseData)
{
// Address Line 1 - optional.
if (Line1 != null)
{
responseData.SetControlValue(ControlNameSuffix + "Line1", Line1);
if (StringUtil.GetLength(Line1) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1))
responseData.SetControlError(ControlNameSuffix + "Line1", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1)]);
}
// Address Line 2 - optional.
if (Line2 != null)
{
responseData.SetControlValue(ControlNameSuffix + "Line2", Line2);
if (!StringUtil.IsEmpty(Line2))
{
if (StringUtil.GetLength(Line2) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line2))
responseData.SetControlError(ControlNameSuffix + "Line2", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line2)]);
}
}
// Address Line 3 - optional.
if (Line3 != null)
{
responseData.SetControlValue(ControlNameSuffix + "Line3", Line3);
if (!StringUtil.IsEmpty(Line3))
{
if (StringUtil.GetLength(Line3) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line3))
responseData.SetControlError(ControlNameSuffix + "Line3", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line3)]);
}
}
// Address Town - mandatory.
if (Town != null)
{
responseData.SetControlValue(ControlNameSuffix + "Town", Town);
if (StringUtil.IsEmpty(Town))
responseData.SetControlError(ControlNameSuffix + "Town", Model.Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(Town) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town))
responseData.SetControlError(ControlNameSuffix + "Town", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town)]);
}
// Address Province - optional.
if (Province != null)
{
responseData.SetControlValue(ControlNameSuffix + "Province", Province);
if (!StringUtil.IsEmpty(Province))
{
if (StringUtil.GetLength(Province) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Province))
responseData.SetControlError(ControlNameSuffix + "Province", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Province)]);
}
}
// Address Country - optional.
if (Country != null)
{
responseData.SetControlValue(ControlNameSuffix + "Country", Country);
if (!StringUtil.IsEmpty(Country))
{
if (StringUtil.GetLength(Country) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Country))
responseData.SetControlError(ControlNameSuffix + "Country", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Country)]);
}
}
// Address PostalCode - optional.
if (PostalCode != null)
{
responseData.SetControlValue(ControlNameSuffix + "PostalCode", PostalCode);
if (!StringUtil.IsEmpty(PostalCode))
{
if (StringUtil.GetLength(PostalCode) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_PostalCode))
responseData.SetControlError(ControlNameSuffix + "PostalCode", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_PostalCode)]);
}
}
return !responseData.HasControlErrors();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,38 @@
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Base.App;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Admin.Models
{
//=======================================================================
/// <summary>
/// Online model data.
/// </summary>
public class ModelData_Admin
{
//-------------------------------------------------------------------
// Construction.
public ModelData_Admin(SaxModel_Admin model)
{
this.Model = model;
}
//-------------------------------------------------------------------
// Properties.
public SaxModel_Admin Model { get; }
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,28 @@
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Admin.Models
{
//=======================================================================
public class Model_ContactMethod : SaxModel_Admin
{
//-------------------------------------------------------------------
// Construction.
public Model_ContactMethod(SaxLocaliser localiser) :
base(localiser)
{
}
//-------------------------------------------------------------------
// Form properties.
public String ContactMethod { get; set; }
public String ContactValue { get; set; }
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -6,13 +6,11 @@ using Sarand.Net.Standard.Base.Utils;
using Saxonite.Base.App;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using Saxonite.Net.Core.Web.Base.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using Saxonite.Net.Standard.Base.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Admin.Models
{
@@ -25,6 +23,7 @@ namespace Saxonite.Net.Core.Web.Admin.Models
base(localiser)
{
AdditionalFiles_JS.Add("js/sax-org.js");
Address = new ModelData_Address(this, "Address");
}
//-------------------------------------------------------------------
@@ -83,6 +82,15 @@ namespace Saxonite.Net.Core.Web.Admin.Models
public String OrganisationNotes { get; set; }
public String OrganisationStatusCode { get; set; }
public SaStatus OrganisationStatus { get { return SacsSystem.GetStatusForCode(OrganisationStatusCode); } }
// Contact Methods.
/// <summary>Placeholder field value to indicate the number of Contact Methods in form (even if none are populated).</summary>
public String ContactMethods { get; set; }
public String[] ContactMethod { get; set; }
public String[] ContactValue { get; set; }
/// <summary>Contact methods to be populated during validation.</summary>
public SaxContactData ContactData { get; set; }
// Address.
public ModelData_Address Address { get; }
// Utilities.
public bool IsSportMandatory()
@@ -96,6 +104,8 @@ namespace Saxonite.Net.Core.Web.Admin.Models
// Organisation validation.
public bool ValidateOrganisationData(SaxController_Base.AjaxResponse_Data responseData)
{
String fn = this.GetType().Name + ".ValidateOrganisationData";
// Organisation name.
if (OrganisationName != null)
{
@@ -174,6 +184,29 @@ namespace Saxonite.Net.Core.Web.Admin.Models
responseData.SetControlError(nameof(OrganisationFacilities), Localiser["msg.validation.maximum.length", GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Facilities)]);
}
// Contact Methods.
if (ContactMethods != null)
{
ContactData = new SaxContactData("");
ContactMethod = ContactMethod ?? new String[0];
ContactValue = ContactValue ?? new String[0];
for (int idx = 0; idx < ContactMethod.Length && idx < ContactValue.Length; idx++)
{
String methodValue = ContactMethod[idx];
String value = ContactValue[idx];
if (methodValue == null & value == null) continue;
Sax.ContactMethod method = EnumUtil.ParseEnum(methodValue, Sax.ContactMethod.Unknown);
if (method > 0 && !value.IsEmpty() && SaxContactMethodHelper.IsValidContactMethodValue(method, value))
ContactData.SetContactMethodValue(method, value);
else SaLogger.Warn(fn + " Invalid Contact Method data. Method: " + methodValue + ". Value: " + value);
}
if (ContactData.Methods.Count != ContactMethods.ToInt())
{
SaLogger.Warn(fn + " Inconsistent Contact Methods received. Expected: " + ContactMethods + ". Received: " + ContactData.Methods.Count);
responseData.SetMessage("caption.contact.method", "System error");
}
}
// Organisation notes.
if (OrganisationNotes != null)
{
@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="caption.contact.method" xml:space="preserve">
<value>Contact Method</value>
</data>
<data name="company.name" xml:space="preserve">
<value>Sportierre</value>
</data>
@@ -201,6 +204,9 @@
<data name="label.columns" xml:space="preserve">
<value>Columns</value>
</data>
<data name="label.contact" xml:space="preserve">
<value>Contact</value>
</data>
<data name="label.country" xml:space="preserve">
<value>Country</value>
</data>
@@ -285,6 +291,9 @@
<data name="label.members.awaiting.activation" xml:space="preserve">
<value>Members awaiting activation</value>
</data>
<data name="label.method" xml:space="preserve">
<value>Method</value>
</data>
<data name="label.name" xml:space="preserve">
<value>Name</value>
</data>
@@ -423,6 +432,9 @@
<data name="label.users.online" xml:space="preserve">
<value>Users online</value>
</data>
<data name="label.value" xml:space="preserve">
<value>Value</value>
</data>
<data name="label.yes" xml:space="preserve">
<value>Yes</value>
</data>
@@ -0,0 +1,50 @@
@model SaxModel_Admin
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/ContactMethods")) return;
<script src="~/js/sax-cnt-mth.js?@Model.HrefVersion"></script>
<script type="text/javascript">
</script>
<div id="dlgContactMethod" class="sax-dialog sax-form" title="@Localiser["caption.contact.method"]">
<div class="spacer4"></div>
@* Method *@
<div class="sax-form-control ContactMethod">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.method"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<select name="ContactMethod" class="ContactMethod sax-select" style="max-width:240px;" ></select>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<div class="spacer"></div>
@* Value *@
<div class="sax-form-control ContactValue">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.value"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" name="ContactValue" class="ContactValue sax-input" />
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<div class="spacer"></div>
</div>
@@ -0,0 +1,75 @@
@* Contact Methods controls *@
@model SaxModel_Admin
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/Controls-ItemContactMethods")) return;
<style>
.ItemContactMethods .ContactMethods
{
min-height: 32px;
max-height: 64px;
background-color: #fff;
border: 1px solid #808080;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
overflow-y: scroll;
}
.ItemContactMethods .ContactMethods table.sax-data tr:hover
{
background-color: #f0f0f0;
}
.ItemContactMethods .ContactMethods table.sax-data .sax-label
{
margin:0;
padding:0 8px 0 0;
}
</style>
@* Contact Methods *@
<div class="sax-form-control ItemContactMethods">
<input type="hidden" name="ContactMethods" value="0" />
<div class="row">
<div class="col-sm-3 row">
<div class="col">
<div class="sax-label">
<label for=""><span>@Localiser["label.contact"]</span></label>
</div>
</div>
<div class="fixed">
@* Action to add new contact method. *@
<div class="sax-actions">
<div class="sax-action sax-add pr4"><img src="~/img/action/add24.png" alt="@(Localiser["label.add"])" title="@(Localiser["label.add"])" /></div>
</div>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col">
@* List of existing contact methods with actions to edit/remove. *@
<div class="ContactMethods">
<table class="sax-data"></table>
</div>
<table class="sax-panel-item-template">
<tr class="ContactMethod">
<td style="width:20px;"><div class="sax-label nowrap"></div></td>
<td class="sax-value " style="width:70%;word-break: break-all;"></td>
<td class="sax-actions right nowrap" style="width:10px;">
<input type="hidden" name="ContactMethod" />
<input type="hidden" name="ContactValue" />
<div class="nowrap">
<div class="inlineb sax-action sax-edit"><img src="~/img/action/edit16.png" alt="@(Localiser["label.edit"])" title="@(Localiser["label.edit"])" /></div>
<div class="inlineb sax-action sax-remove"><img src="~/img/action/delete16.png" alt="@(Localiser["label.remove"])" title="@(Localiser["label.remove"])" /></div>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<partial name="~/Views/Common/ContactMethods.cshtml" />
@@ -1,6 +1,8 @@
@model SaxModel_Admin
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/SelectCode")) return;
<link rel="stylesheet" href="~/css/sax-selectCode.css?@Model.HrefVersion" />
<script src="~/js/sax-sel-cod.js?@Model.HrefVersion"></script>
<script type="text/javascript">
@@ -1,6 +1,8 @@
@model SaxModel_Admin
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/SelectItem")) return;
<link rel="stylesheet" href="~/css/sax-selectItem.css?@Model.HrefVersion" />
<div id="dlgSelectItem" class="sax-dialog sax-form">
@@ -1,6 +1,8 @@
@model SaxModel_Admin
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/SelectOrganisation")) return;
<link rel="stylesheet" href="~/css/sax-selectOrganisation.css?@Model.HrefVersion" />
<script src="~/js/sax-sel-org.js?@Model.HrefVersion"></script>
<script type="text/javascript">
@@ -147,6 +147,9 @@
</div>
</div>
@* Contact Methods *@
<partial name="..\Common\Controls-ItemContactMethods.cshtml" />
@* Organisation Notes *@
<div class="sax-form-control OrganisationNotes">
<div class="row">
@@ -155,15 +155,17 @@
overflow-y: scroll;
}
.sax-form .sax-input:read-only, .sax-form .sax-textarea:read-only
.sax-form .sax-input:read-only, .sax-form .sax-textarea:read-only, .sax-form .sax-select:disabled
{
color: #202020;
opacity: 1;
background-color: #f8f8f8;
}
.sax-form .sax-form-control.sax-error .sax-input, .sax-form .sax-form-control.sax-error .sax-textarea, .sax-form .sax-form-control.sax-error .sax-select
{
color: #DC143C;
border-color: #DC143C;
color: #606060; /*#DC143C;*/
border-color: #606060; /*#DC143C;*/
}
/* Control messages */
Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

@@ -0,0 +1,69 @@
/*
* Contact Methods script.
*/
(function (win, doc, undef)
{
"use strict";
let cm = sax.mdl.contactMethods = { fn: {}, data: {}, ajax: {} };
let $dlg = cm.$dlg = {};
//--------------------------------------------------------------
/*
* Config:
* fnCallback Method to call to apply changes.
* methods Full list of methods.
* methodsUsed List of methods already in use.
* method Current selected method (if updating).
* value Current value.
*/
sax.editContactMethod = cm.fn.edit = function (cfg)
{
cm.fn.init();
cm.data.cfg = cfg || {};
cm.$mth.empty();
for (let mth of cfg.methods || [])
{
if (mth.code && mth.code == cfg.method || !(cfg.methodsUsed || []).includes(mth.code))
cm.$mth.append($('<option>').prop('value', mth.code).text(mth.desc));
}
cm.$mth.val(cfg.method).attr('disabled', cfg.method && cm.$mth.val() == cfg.method ? true : null);
cm.$val.val(cfg.value);
sax.openDialog($dlg.conMth, 600, 240);
}
//--------------------------------------------------------------
cm.fn.applyChanges = function ()
{
cm.ajax.applyChanges = cm.ajax.applyChanges || { url: sax.url.base + 'Reference/Ajax/ValidateContactMethod', callbackFn: cm.fn.onApplyChanges };
cm.ajax.applyChanges.formData = new FormData();
cm.ajax.applyChanges.formData.append("__RequestVerificationToken", $('#frmNavigate input[name="__RequestVerificationToken"]').val());
cm.ajax.applyChanges.formData.append("ContactMethod", $('select[name="ContactMethod"]', $dlg.conMth).val());
cm.ajax.applyChanges.formData.append("ContactValue", $('input[name="ContactValue"]', $dlg.conMth).val());
sax.doAjaxRequest(cm.ajax.applyChanges, 50);
}
cm.fn.onApplyChanges = function (response)
{
if (!response) return;
sax.refreshControlValues(response.controlValues, $dlg.conMth);
if (!response.success) return;
$dlg.conMth.dialog('close');
if (cm.data.cfg.fnCallback) cm.data.cfg.fnCallback(cm.$mth.val(), $('option:selected', cm.$mth).text(), cm.$val.val());
}
//--------------------------------------------------------------
cm.fn.init = function ()
{
if ($dlg.conMth) return;
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { cm.fn.applyChanges(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
$dlg.conMth = $('#dlgContactMethod').dialog(opt);
cm.$mth = $('.sax-select.ContactMethod', $dlg.conMth);
cm.$val = $('.sax-input.ContactValue', $dlg.conMth);
}
//--------------------------------------------------------------
}(window, window.document));
/* The End */
@@ -206,8 +206,8 @@
if (!response || !response.success || !response.user) return;
$mbrName.val(response.user.displayName);
}
om.ajax.userByEmail = om.ajax.userByEmail || { url: sax.url.base + 'User/Ajax/GetUserByEmail', formId: 'frmUserEmail', callbackFn: fn };
sax.doAjaxRequest(om.ajax.userByEmail, 100);
om.ajax.userByEmail = om.ajax.userByEmail || { url: sax.url.base + 'User/Ajax/GetUserByEmail', formId: 'frmUserEmail', callbackFn: fn, noWaitIcon: true };
sax.doAjaxRequest(om.ajax.userByEmail, 500);
}
//--------------------------------------------------------------
@@ -243,9 +243,8 @@
}
om.onRemoveItem = function (response)
{
sax.debug('onRemoveItem', response);
//sax.debug('onRemoveItem', response);
if (!response.success) return;
var item = response.member;
$('#' + om.itemIdPrefix + item.id).remove();
}
@@ -265,7 +264,7 @@
$frm.mbr = $('#frmMember');
$frm.mbr.on('input', '.sax-input', function () { sax.clearControlError(this); });
$frm.mbr.on('change', '.sax-select', function () { sax.clearControlError(this); });
$frm.mbr.on('change', '#ifMemberUserEmailAddress', function () { om.onChangeEmail(); });
$frm.mbr.on('input', '#ifMemberUserEmailAddress', function () { om.onChangeEmail(); });
$frm.mbr.on('dblclick', '#ifMemberRoles', om.selectMemberRoles);
$frm.mbr.on('click', '#pbMemberRolesSelect', om.selectMemberRoles);
+85 -10
View File
@@ -30,8 +30,9 @@
var $items = $('.sax-panel-item-list', $pnl.results).hide().empty();
sax.refreshPaging(response, '#frmOrganisationFilter', op.refreshResults);
if (!response.success) return;
// Reference data - Statuses.
if (response.defaultStatusCode) sax.data.defaultStatusCode = response.defaultStatusCode;
// Reference data.
op.data.contactMethods = response.contactMethods;
if (response.defaultStatusCode) op.data.defaultStatusCode = response.defaultStatusCode;
if (response.statuses)
sax.populateSelectCodeDesc('#cbOrganisationStatus', response.statuses);
// Menu.
@@ -241,7 +242,7 @@
{
let frm = $frm.org;
$('.OrganisationId,.OrganisationSportId,.OrganisationRegionIdCountry,input[type="text"],textarea,select', frm).val('');
$('.OrganisationStatus', frm).val(sax.data.defaultStatusCode);
$('.OrganisationStatus', frm).val(op.data.defaultStatusCode);
sax.clearControlErrors();
}
sax.openOrgDialog = function ()
@@ -279,11 +280,83 @@
$('.OrganisationFacilities', frm).val(item.facilities);
$('.OrganisationNotes', frm).val(item.notes);
$('.OrganisationStatus', frm).val(item.statusCode);
// Contact methods.
$pnl.tblconMths.empty();
let conMths = item.contactMethods || [];
for (let idx = 0; idx < conMths.length; idx++)
{
let conMth = conMths[idx];
$pnl.tblconMths.append(op.getConMthEl(conMth.method, conMth.methodCaption, conMth.value));
}
op.sortConMths();
// Address.
let address = item.address || {};
$('input.OrganisationAddressId', $frm.org).val(address.id);
$('input.OrganisationAddressLine1', $frm.org).val(address.line1);
$('input.OrganisationAddressLine2', $frm.org).val(address.line2);
$('input.OrganisationAddressLine3', $frm.org).val(address.line3);
$('input.OrganisationAddressTown', $frm.org).val(address.town);
$('input.OrganisationAddressProvince', $frm.org).val(address.province);
$('input.OrganisationAddressCountry', $frm.org).val(address.country);
$('input.OrganisationAddressPostalCode', $frm.org).val(address.postalCode);
sax.clearControlErrors();
$dlg.organisation.dialog('option', 'title', sax.dlg.title.updateOrganisation);
sax.openOrgDialog();
}
//--------------------------------------------------------------
op.getConMthCfg = function (usedMths, mth, val)
{
let cfg = { fnCallback: op.applyConMth, methods: op.data.contactMethods, methodsUsed: usedMths, method: mth, value: val };
return cfg;
}
op.getUsedMths = function ()
{
return $('input[name="Organisation.ContactMethod"]', $frm.org).map(function () { return $(this).val(); }).get();
}
op.addConMth = function ()
{
sax.editContactMethod(op.getConMthCfg(op.getUsedMths()));
}
op.editConMth = function (mth, val)
{
sax.editContactMethod(op.getConMthCfg(op.getUsedMths(), mth, val));
}
op.getConMthId = function (mth)
{
return 'ConMth_' + mth;
}
op.applyConMth = function (mth, mthDsc, val)
{
//sax.debug('applyConMth(\'' + mth + '\',\'' + mthDsc + '\',\'' + val + '\')');
$('#' + op.getConMthId(mth), $pnl.conMths).remove();
$pnl.tblconMths.append(op.getConMthEl(mth, mthDsc, val));
op.sortConMths();
}
op.sortConMths = function ()
{
let $rows = $pnl.tblconMths.find('tr').detach().sort(function (a, b)
{
return $('.sax-label', a).text().localeCompare($('.sax-label', b).text());
}).appendTo($pnl.tblconMths);
$('input[name="ContactMethods"]', $pnl.conMths).val($rows.length);
}
op.getConMthEl = function (mth, mthDsc, val)
{
let $conMth = $('.sax-panel-item-template .ContactMethod', $pnl.conMths).clone().prop('id', op.getConMthId(mth));
$('.sax-label', $conMth).text(mthDsc);
$('.sax-value', $conMth).text(val);
$('input[name="ContactMethod"]', $conMth).val(mth);
$('input[name="ContactValue"]', $conMth).val(val);
$conMth.on('click', '.sax-action.sax-edit', function () { op.editConMth(mth, val); });
$conMth.on('click', '.sax-action.sax-remove', function () { op.clearConMth(mth); });
return $conMth;
}
op.clearConMth = function (mth)
{
$('#' + op.getConMthId(mth), $pnl.conMths).remove();
}
//--------------------------------------------------------------
op.storeItem = function ()
{
@@ -336,7 +409,6 @@
let $orgMbrs = $('.OrganisationMembers', $dlg.activate).empty();
let $mbrTmpl = $('.sax-panel-item-template tr.sax-item.Member');
let members = response.members;
//sax.debug(members, $orgMbrs, $mbrTmpl);
for (let idx = 0; idx < members.length; idx++)
{
let item = members[idx];
@@ -346,7 +418,6 @@
$('.MemberEmail', $item).text(item.emailAddress);
$('.MemberName', $item).text(item.displayName);
$orgMbrs.append($item);
//sax.debug($item);
}
$('.MembersAwaitingActivation', $dlg.activate).toggle(!!members.length);
sax.openDialog($dlg.activate, 480, 420);
@@ -387,11 +458,6 @@
$('.FilterOrganisationCategory,.FilterOrganisationStatusCategory', $frm.filter).on('change', function () { op.refreshResults(50); });
$frm.filter.on('dblclick', '.FilterOrganisationSportCaption', op.selectFilterSport).on('click', '.FilterSportSelect', op.selectFilterSport).on('click', '.FilterSportClear', op.clearFilterSport);
$frm.filter.on('dblclick', '.FilterOrganisationRegionCaption', op.selectFilterRegion).on('click', '.FilterRegionSelect', op.selectFilterRegion).on('click', '.FilterRegionClear', op.clearFilterRegion);
$frm.orgId = $('#frmOrganisationId');
$frm.org = $('#frmOrganisation');
$frm.org.on('input', '.sax-input, .sax-textarea', function () { sax.clearControlError(this); }).on('change', '.sax-select', function () { sax.clearControlError(this); });
$frm.org.on('dblclick', '.OrganisationSportCaption', op.selectOrgSport).on('click', '#pbSelectSport', op.selectOrgSport).on('click', '.OrganisationSportClear', op.clearOrgSport);
$frm.org.on('dblclick', '.OrganisationRegionCaptionCountry', op.selectOrgRegion).on('click', '#pbSelectRegion', op.selectOrgRegion);
var opt = sax.dlgOpts();
opt.open = sax.onOpenOrgDialog;
@@ -399,6 +465,15 @@
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
$dlg.organisation = $('#dlgOrganisation').dialog(opt);
$frm.orgId = $('#frmOrganisationId');
$frm.org = $('#frmOrganisation');
$frm.org.on('input', '.sax-input, .sax-textarea', function () { sax.clearControlError(this); }).on('change', '.sax-select', function () { sax.clearControlError(this); });
$frm.org.on('dblclick', '.OrganisationSportCaption', op.selectOrgSport).on('click', '#pbSelectSport', op.selectOrgSport).on('click', '.OrganisationSportClear', op.clearOrgSport);
$frm.org.on('dblclick', '.OrganisationRegionCaptionCountry', op.selectOrgRegion).on('click', '#pbSelectRegion', op.selectOrgRegion);
$frm.org.on('click', '.ItemContactMethods .sax-action.sax-add', op.addConMth);
$pnl.conMths = $('.ItemContactMethods', $frm.org);
$pnl.tblconMths = $('table.sax-data', $pnl.conMths);
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { op.activateOrganisation(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
@@ -174,6 +174,9 @@
<data name="article.caption.articles" xml:space="preserve">
<value>Articles</value>
</data>
<data name="caption.contact.method" xml:space="preserve">
<value>Contact Method</value>
</data>
<data name="company.name" xml:space="preserve">
<value>Solum Forti</value>
</data>
@@ -237,6 +240,9 @@
<data name="label.address" xml:space="preserve">
<value>Address</value>
</data>
<data name="label.address.lines" xml:space="preserve">
<value>Address lines</value>
</data>
<data name="label.alternatively" xml:space="preserve">
<value>Alternatively</value>
</data>
@@ -273,9 +279,15 @@
<data name="label.comment" xml:space="preserve">
<value>Comment</value>
</data>
<data name="label.contact" xml:space="preserve">
<value>Contact</value>
</data>
<data name="label.contact.details" xml:space="preserve">
<value>Contact details</value>
</data>
<data name="label.contact.method" xml:space="preserve">
<value>Contact method</value>
</data>
<data name="label.country" xml:space="preserve">
<value>Country</value>
</data>
@@ -333,6 +345,9 @@
<data name="label.experience" xml:space="preserve">
<value>Experience</value>
</data>
<data name="label.facebook" xml:space="preserve">
<value>Facebook</value>
</data>
<data name="label.facilities" xml:space="preserve">
<value>Facilities</value>
</data>
@@ -363,6 +378,9 @@
<data name="label.headline" xml:space="preserve">
<value>Headline</value>
</data>
<data name="label.home" xml:space="preserve">
<value>Home</value>
</data>
<data name="label.image" xml:space="preserve">
<value>Image</value>
</data>
@@ -381,12 +399,24 @@
<data name="label.location" xml:space="preserve">
<value>Location</value>
</data>
<data name="label.logo" xml:space="preserve">
<value>Logo</value>
</data>
<data name="label.main" xml:space="preserve">
<value>Main</value>
</data>
<data name="label.member" xml:space="preserve">
<value>Member</value>
</data>
<data name="label.members" xml:space="preserve">
<value>Members</value>
</data>
<data name="label.method" xml:space="preserve">
<value>Method</value>
</data>
<data name="label.mobile" xml:space="preserve">
<value>Mobile</value>
</data>
<data name="label.month" xml:space="preserve">
<value>Month</value>
</data>
@@ -405,6 +435,9 @@
<data name="label.occurs" xml:space="preserve">
<value>Occurs</value>
</data>
<data name="label.office" xml:space="preserve">
<value>Office</value>
</data>
<data name="label.officiating" xml:space="preserve">
<value>Officiating</value>
</data>
@@ -423,9 +456,6 @@
<data name="label.organisation" xml:space="preserve">
<value>Organisation</value>
</data>
<data name="label.organisation.address" xml:space="preserve">
<value>Organisation address</value>
</data>
<data name="label.organsiation.details" xml:space="preserve">
<value>Organisation details</value>
</data>
@@ -546,6 +576,9 @@
<data name="label.town" xml:space="preserve">
<value>Town</value>
</data>
<data name="label.twitter" xml:space="preserve">
<value>Twitter</value>
</data>
<data name="label.type" xml:space="preserve">
<value>Type</value>
</data>
@@ -561,6 +594,9 @@
<data name="label.users" xml:space="preserve">
<value>Users</value>
</data>
<data name="label.value" xml:space="preserve">
<value>Value</value>
</data>
<data name="label.very.good" xml:space="preserve">
<value>Very Good</value>
</data>
@@ -570,6 +606,12 @@
<data name="label.views" xml:space="preserve">
<value>Views</value>
</data>
<data name="label.website" xml:space="preserve">
<value>Website</value>
</data>
<data name="label.wikipedia" xml:space="preserve">
<value>Wikipedia</value>
</data>
<data name="label.year" xml:space="preserve">
<value>Year</value>
</data>
@@ -25,7 +25,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
{
//-------------------------------------------------------------------
/// <summary>Organisation properteis for list population.</summary>
private class ProfileOrganisationData_List : AjaxResponse_Data.ItemData_Base
private class ProfileOrganisationListData : AjaxResponse_Data.ItemData_Base
{
public String Name { get; set; }
public String CategoryDesc { get; set; }
@@ -40,29 +40,20 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
public bool? ScheduleAdmin { get; set; } = null;
public bool? ArticleAdmin { get; set; } = null;
}
/// <summary>Address properties.</summary>
private class AddressData : AjaxResponse_Data.ItemData_Base
{
public String Line1 { get; set; }
public String Line2 { get; set; }
public String Line3 { get; set; }
public String Town { get; set; }
public String Province { get; set; }
public String RegionIdProvince { get; set; }
public String Country { get; set; }
public String PostalCode { get; set; }
}
/// <summary>Organisation properties for popup dialog and form.</summary>
private class ProfileOrganisationData : ProfileOrganisationData_List
private class ProfileOrganisationItemData : ProfileOrganisationListData
{
public String CategoryCode { get; set; }
public String TypeCode { get; set; }
public String SportId { get; set; }
public String RegionIdCountry { get; set; }
public AddressData Address { get; set; }
public String About { get; set; }
public String Facilities { get; set; }
public List<AjaxResponse_Data.ContactMethodData> ContactMethods { get; set; }
public AjaxResponse_Data.AddressData Address { get; set; }
}
/// <summary>Populate organisation properties for list.</summary>
private void PopulateOrganisationResponseData(SaxModel_Online model, SaxOrganisation organisation, SaxUserOrganisation userOrganisation, ProfileOrganisationData_List data)
private void PopulateOrganisationResponseListData(SaxModel_Online model, SaxOrganisation organisation, SaxUserOrganisation userOrganisation, ProfileOrganisationListData data)
{
data.Id = model.EncryptId(organisation.Id);
data.Name = organisation.Name;
@@ -89,18 +80,28 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
data.StatusDesc = organisation.StatusDesc;
}
/// <summary>Populate organisation properties for popup dialog and form.</summary>
private void PopulateOrganisationResponseData(SaxModel_Online model, SaxOrganisation organisation, SaxUserOrganisation userOrganisation, SaxItemAddress address, ProfileOrganisationData data)
private void PopulateOrganisationResponseItemData(SaxModel_Online model, SaxOrganisation organisation, SaxUserOrganisation userOrganisation, SaxItemAddress address, ProfileOrganisationItemData data)
{
PopulateOrganisationResponseData(model, organisation, userOrganisation, (ProfileOrganisationData_List)data);
PopulateOrganisationResponseListData(model, organisation, userOrganisation, (ProfileOrganisationListData)data);
data.CategoryCode = OrganisationCategoryCodes.GetCodeForType(organisation.OrganisationCategory);
data.CategoryDesc = Localiser.GetOrganisationCategoryCaption(organisation.OrganisationCategory);
data.TypeCode = OrganisationTypeCodes.GetCodeForType(organisation.OrganisationType);
data.TypeDesc = Localiser.GetOrganisationTypeCaption(organisation.OrganisationType);
data.SportId = model.GetEncryptedSportId(organisation.SportIdPrimary);
data.RegionIdCountry = model.GetEncryptedRegionId(organisation.RegionIdPrimary);
data.About = organisation.About;
data.Facilities = organisation.Facilities;
// Contact methods.
SaxContactData contactData = new SaxContactData(organisation.ContactData);
foreach (Sax.ContactMethod method in contactData.Methods)
{
if (data.ContactMethods == null) data.ContactMethods = new List<AjaxResponse_Data.ContactMethodData>();
data.ContactMethods.Add(new AjaxResponse_Data.ContactMethodData() { Method = method.ToString(), MethodCaption = Localiser.GetContactMethodCaption(method), Value = contactData.GetContactMethodValue(method) });
}
// Address.
if (address != null)
{
data.Address = new AddressData();
data.Address = new AjaxResponse_Data.AddressData();
data.Address.Id = model.EncryptId(address.Id);
data.Address.Line1 = address.Line1;
data.Address.Line2 = address.Line2;
@@ -119,8 +120,10 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
{
// Construction.
public AjaxResponse_ProfileOrganisationList(SaxModel_Online model) : base(model) { }
// Reference data.
public List<AjaxResponse_Data.ItemCodeDesc> ContactMethods { get; } = new List<ItemCodeDesc>();
// Organisation list.
public List<ProfileOrganisationData_List> Organisations { get; } = new List<ProfileOrganisationData_List>();
public List<ProfileOrganisationListData> Organisations { get; } = new List<ProfileOrganisationListData>();
}
// Ajax request.
[HttpPost]
@@ -137,6 +140,15 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Reference data - contact methods.
List<Sax.ContactMethod> validContactMethods = SaxOrganisation.ValidContactMethods;
foreach (TypeCodeDesc contactMethod in ContactMethodCodes)
{
// Skip methods that aren't associated with Organisations.
if (!validContactMethods.Contains((Sax.ContactMethod)contactMethod.Type)) continue;
responseData.ContactMethods.Add(new AjaxResponse_Data.ItemCodeDesc() { Code = contactMethod.Code, Desc = Localiser.GetContactMethodCaption((Sax.ContactMethod)contactMethod.Type) });
}
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposableItems = new DisposableCollection<SacsHierarchyItem>())
{
@@ -184,7 +196,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
NamedValue.Map values = resultSet.GetRecordValues();
Sax.OrganisationCategory organisationCategory = (Sax.OrganisationCategory)OrganisationCategoryCodes.GetTypeForCode(values.GetString(colOrganisationCategory.DataName));
Sax.OrganisationType organisationType = (Sax.OrganisationType)OrganisationTypeCodes.GetTypeForCode(values.GetString(colOrganisationType.DataName));
ProfileOrganisationData_List organisationData = new ProfileOrganisationData_List()
ProfileOrganisationListData organisationData = new ProfileOrganisationListData()
{
Id = model.EncryptId(new SysId(values.GetLong(colId.DataName))),
Name = values.GetString(colOrganisationName.DataName),
@@ -233,7 +245,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
public List<AjaxResponse_Data.ItemCodeDesc> Categories { get; } = new List<ItemCodeDesc>();
public List<AjaxResponse_Data.ItemCodeDesc> Types { get; } = new List<ItemCodeDesc>();
// Organisation list.
public ProfileOrganisationData Organisation { get; set; }
public ProfileOrganisationItemData Organisation { get; set; }
}
// Ajax request.
[HttpPost]
@@ -281,8 +293,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
// Construct response.
responseData.Organisation = new ProfileOrganisationData();
PopulateOrganisationResponseData(model, organisation, userOrganisation, address, responseData.Organisation);
responseData.Organisation = new ProfileOrganisationItemData();
PopulateOrganisationResponseItemData(model, organisation, userOrganisation, address, responseData.Organisation);
// Reference data.
foreach (TypeCodeDesc organisationCategory in OrganisationCategoryCodes)
@@ -311,7 +323,7 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
// Construction.
public AjaxResponse_StoreProfileOrganisation(SaxModel_Online model) : base(model) { }
// Organisation list.
public ProfileOrganisationData Organisation { get; set; }
public ProfileOrganisationItemData Organisation { get; set; }
}
// Ajax request.
[HttpPost]
@@ -429,8 +441,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
organisation.About = model.Organisation.About;
if (model.Organisation.Facilities != null)
organisation.Facilities = model.Organisation.Facilities;
if (model.Organisation.PhoneMain != null)
organisation.PhoneMain = model.Organisation.PhoneMain;
if (model.Organisation.ContactData != null)
organisation.ContactData = model.Organisation.ContactData.GetContactData();
if (!AccountMgr.UpdateOrganisation(organisation, DbUpdateInfo))
{
SaLogger.Warn(fn + " Failed to update organisation - " + AccountMgr.ErrorStateMessage);
@@ -487,8 +499,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
// Construct response.
responseData.Organisation = new ProfileOrganisationData();
PopulateOrganisationResponseData(model, organisation, userOrganisation, organisationAddress, responseData.Organisation);
responseData.Organisation = new ProfileOrganisationItemData();
PopulateOrganisationResponseItemData(model, organisation, userOrganisation, organisationAddress, responseData.Organisation);
}
// Complete response.
@@ -0,0 +1,64 @@
using Microsoft.AspNetCore.Mvc;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Core.Web.Base.Models;
using Saxonite.Net.Core.Web.Online.Models;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Helpers;
using System;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
//=======================================================================
// Online Reference Controller - Contact Method Ajax actions only.
//=======================================================================
partial class ReferenceController
{
//-------------------------------------------------------------------
// Validate Contact Method.
//-------------------------------------------------------------------
private class AjaxResponse_ValidateContactMethod : AjaxResponse_Data
{
public AjaxResponse_ValidateContactMethod(SaxModel_Base model) : base(model) { }
}
[HttpPost]
[Route("Reference/Ajax/ValidateContactMethod")]
public IActionResult Ajax_ValidateContactMethod(Model_ContactMethod model)
{
String fn = GetType().Name + ".Ajax_ValidateContactMethod";
String messageTitle = Localiser["caption.contact.method"];
AjaxResponse_ValidateContactMethod responseData = new AjaxResponse_ValidateContactMethod(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
// Validate method.
Sax.ContactMethod method = EnumUtil.ParseEnum(model.ContactMethod, Sax.ContactMethod.Unknown);
if (model.ContactMethod.IsEmpty() || (int)method < 1)
responseData.SetControlError(nameof(model.ContactMethod), Localiser["msg.validation.mandatory.value"]);
// Validate method.
if (model.ContactValue.IsEmpty())
responseData.SetControlError(nameof(model.ContactValue), Localiser["msg.validation.mandatory.value"]);
// Method specific value validation.
if (!SaxContactMethodHelper.IsValidContactMethodValue(method, model.ContactValue))
{
// Log invalid values so that the validation can be adjusted if needed.
SaLogger.Warn(fn + " Invalid contact method value. Mathod: " + method.ToString() + ". Value: " + model.ContactValue);
responseData.SetControlError(nameof(model.ContactValue), Localiser["msg.validation.invalid.value"]);
}
if (responseData.HasControlErrors())
return Json(responseData);
// Complete response.
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -15,6 +15,7 @@ using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Core.Web.Online.Helpers;
namespace Saxonite.Net.Core.Web.Online.Controllers
{
@@ -30,11 +31,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
{
public String Name { get; set; }
public String CategoryDesc { get; set; }
public String SportId { get; set; }
public String SportName { get; set; }
public String RegionId { get; set; }
public String RegionName { get; set; }
public String Location { get; set; }
}
private class AjaxResponse_Search_Organisations : AjaxResponse_Data
{
@@ -111,10 +109,8 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
Id = model.EncryptId(new SysId(values.GetLong(colId.DataName))),
Name = values.GetString(colName.DataName),
CategoryDesc = Localiser.GetOrganisationCategoryCaption(category),
//SportId = model.GetEncryptedSportId(new SysId(values.GetLong(colSportId.DataName))),
SportName = values.GetString(colSportName.DataName),
//RegionId = model.GetEncryptedRegionId(new SysId(values.GetLong(colRegionId.DataName))),
Location = values.GetString(colRegionName.DataName),
RegionName = values.GetString(colRegionName.DataName),
};
responseData.Organisations.Add(organisationData);
}
@@ -130,25 +126,21 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
//-------------------------------------------------------------------
// Account - Get Organisation.
//-------------------------------------------------------------------
private class OrganisationData : AjaxResponse_Data.ItemData_Base
private class OrganisationItemData : OrganisationListData
{
public String Name { get; set; }
public String Category { get; set; }
public String Type { get; set; }
public String Sport { get; set; }
public String Location { get; set; }
public String TypeDesc { get; set; }
public String About { get; set; }
public String Facilities { get; set; }
public List<AjaxResponse_Data.ItemLabelValue> Contacts { get; set; }
public String Address { get; set; }
public String PostalCode { get; set; }
public String Phone { get; set; }
}
private class AjaxResponse_Search_Organisation : AjaxResponse_Data
{
// Construction.
public AjaxResponse_Search_Organisation(SaxModel_Online model) : base(model) { }
// Organisation list.
public OrganisationData Organisation { get; set; }
public OrganisationItemData Organisation { get; set; }
}
// Ajax request.
[HttpPost]
@@ -185,20 +177,39 @@ namespace Saxonite.Net.Core.Web.Online.Controllers
}
disposableItems.Add(organisation);
// ToDo May-2022 TESTING.
//SaLogger.Info(fn + " Organisation: " + organisation.Name + "\nAbout: " + organisation.About + "\nFacilities: " + organisation.Facilities, true);
// Populate response.
OrganisationData organisationData = new OrganisationData()
OrganisationItemData organisationData = new OrganisationItemData()
{
Id = model.EncryptId(organisation.Id),
Name = organisation.Name,
Category = Localiser.GetOrganisationCategoryCaption(organisation.OrganisationCategory),
Type = Localiser.GetOrganisationTypeCaption(organisation.OrganisationType),
Sport = model.GetSportCaption(organisation.SportIdPrimary),
Location = model.GetRegionCaption(organisation.RegionIdPrimary),
CategoryDesc = Localiser.GetOrganisationCategoryCaption(organisation.OrganisationCategory),
TypeDesc = Localiser.GetOrganisationTypeCaption(organisation.OrganisationType),
SportName = model.GetSportCaption(organisation.SportIdPrimary),
RegionName = model.GetRegionCaption(organisation.RegionIdPrimary),
About = organisation.About,
Facilities = organisation.Facilities,
};
responseData.Organisation = organisationData;
// Contacts.
SaxContactData contactData = new SaxContactData(organisation.ContactData);
if (contactData.Methods.Count > 0)
{
responseData.Organisation.Contacts = new List<AjaxResponse_Data.ItemLabelValue>();
foreach (Sax.ContactMethod method in contactData.Methods)
{
AjaxResponse_Data.ItemLabelValue contact = new AjaxResponse_Data.ItemLabelValue()
{
Label = Localiser.GetContactMethodCaption(method),
Value = SaxContactMethodHelper_Online.GetContactMethodHtml(method, contactData.GetContactMethodValue(method), Localiser)
};
responseData.Organisation.Contacts.Add(contact);
}
}
// Organisation address.
SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId());
if (address != null)
@@ -0,0 +1,63 @@
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Online.Helpers
{
//=======================================================================
public static class SaxContactMethodHelper_Online
{
//-------------------------------------------------------------------
public static String GetContactMethodHtml(Sax.ContactMethod method, String value, SaxLocaliser localiser)
{
// Qualify any URL value to ensure that it can be used as the href attribute in an anchor tag.
String url = (SaxContactMethodHelper.GetContactMethodType(method) == Sax.ContactMethodType.WebUrl) ? SacsDataValidationHelper.QualifyAbsoluteUrl(value) : value;
switch (method)
{
// Phone numbers.
case Sax.ContactMethod.PhoneMain:
return ConstructImageElement("icon/contact/phone-24.png") + localiser["label.main"] + ": " + value;
case Sax.ContactMethod.PhoneMobile:
return ConstructImageElement("icon/contact/mobile-24.png") + localiser["label.mobile"] + ": " + value;
case Sax.ContactMethod.PhoneHome:
return ConstructImageElement("icon/contact/phone-24.png") + localiser["label.home"] + ": " + value;
case Sax.ContactMethod.PhoneOffice:
return ConstructImageElement("icon/contact/phone-24.png") + localiser["label.office"] + ": " + value;
// Online.
case Sax.ContactMethod.Email:
return "<a href='mailto:" + value + "'>" + ConstructImageElement("action/mail24.png") + value + " </a>";
case Sax.ContactMethod.Website:
return "<a href='" + url + "' target='" + Sax.Config.Online.Links.Targets.Website + "'>" + ConstructImageElement("icon/contact/www-24.png") + value + " </a>";
case Sax.ContactMethod.Wikipedia:
return "<a href='" + url + "' target='" + Sax.Config.Online.Links.Targets.Wikipedia + "'>" + ConstructImageElement("icon/contact/wikipedia-24.png") + value + " </a>";
// Social media.
case Sax.ContactMethod.LinkedIn:
return "<a href='" + url + "' target='" + Sax.Config.Online.Links.Targets.LinkedIn + "'>" + ConstructImageElement("icon/contact/linkedin-24.png") + value + " </a>";
case Sax.ContactMethod.Twitter:
return "<a href='" + url + "' target='" + Sax.Config.Online.Links.Targets.Twitter + "'>" + ConstructImageElement("icon/contact/twitter-24.png") + value + " </a>";
case Sax.ContactMethod.Facebook:
return "<a href='" + url + "' target='" + Sax.Config.Online.Links.Targets.Facebook + "'>" + ConstructImageElement("icon/contact/facebook-24.png") + value + " </a>";
case Sax.ContactMethod.Instagram:
return "<a href='" + url + "' target='" + Sax.Config.Online.Links.Targets.Instagram + "'>" + ConstructImageElement("icon/contact/instagram-24.png") + value + " </a>";
}
return method.ToString() + ": " + value;
}
//-------------------------------------------------------------------
// Utilities.
public static String ConstructImageElement(String imageFilepath, String alt = "", String title = "")
{
return "<img src='../img/" + imageFilepath + "' alt='" + StringUtil.EmptyOnNull(alt) + "' title='" + StringUtil.EmptyOnNull(title) + "' />";
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -42,6 +42,16 @@ namespace Saxonite.Net.Core.Web.Online.Models
public String Country { get; set; }
public String PostalCode { get; set; }
//-------------------------------------------------------------------
// Utilities.
/// <summary>Have any address values been supplied by the form.</summary>
public bool IsSpecified()
{
if (Id != null || Line1 != null || Town != null || Province != null || Country != null || PostalCode != null)
return true;
return false;
}
//-------------------------------------------------------------------
// Validation.
//-------------------------------------------------------------------
@@ -49,12 +59,13 @@ namespace Saxonite.Net.Core.Web.Online.Models
public bool ValidateAddressData(SaxController_Base.AjaxResponse_Data responseData)
{
// Address Line 1 - mandatory.
// Address Line 1 - optional.
if (Line1 != null)
{
responseData.SetControlValue(ControlNameSuffix + "Line1", Line1);
if (StringUtil.IsEmpty(Line1))
responseData.SetControlError(ControlNameSuffix + "Line1", Model.Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(Line1) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1))
if (StringUtil.GetLength(Line1) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1))
responseData.SetControlError(ControlNameSuffix + "Line1", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1)]);
}
// Address Line 2 - optional.
if (Line2 != null)
@@ -79,11 +90,14 @@ namespace Saxonite.Net.Core.Web.Online.Models
}
// Address Town - mandatory.
if (Town != null)
{
responseData.SetControlValue(ControlNameSuffix + "Town", Town);
if (StringUtil.IsEmpty(Town))
responseData.SetControlError(ControlNameSuffix + "Town", Model.Localiser["msg.validation.mandatory.value"]);
else if (StringUtil.GetLength(Town) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town))
responseData.SetControlError(ControlNameSuffix + "Town", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town)]);
}
// Address Province - optional.
if (Province != null)
@@ -4,14 +4,11 @@ using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Helpers;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Base.App;
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Controllers;
using Saxonite.Net.Standard.Base.App;
using Saxonite.Net.Standard.Base.Bus;
using Saxonite.Net.Standard.Base.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Online.Models
{
@@ -44,6 +41,13 @@ namespace Saxonite.Net.Core.Web.Online.Models
public String About { get; set; }
public String Facilities { get; set; }
public String PhoneMain { get; set; }
// Contact Methods.
/// <summary>Placeholder field value to indicate the number of Contact Methods in form (even if none are populated).</summary>
public String ContactMethods { get; set; }
public String[] ContactMethod { get; set; }
public String[] ContactValue { get; set; }
/// <summary>Contact methods to be populated during validation.</summary>
public SaxContactData ContactData { get; set; }
// Address.
public ModelData_Address Address { get; }
@@ -53,6 +57,7 @@ namespace Saxonite.Net.Core.Web.Online.Models
// Organisation.
public bool ValidateOrganisationData(SaxController_Base.AjaxResponse_Data responseData)
{
String fn = this.GetType().Name + ".ValidateOrganisationData";
// Name - mandatory.
responseData.SetControlValue(ControlNameSuffix + "Name", Name);
@@ -103,6 +108,29 @@ namespace Saxonite.Net.Core.Web.Online.Models
if (StringUtil.GetLength(Facilities) > Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Facilities))
responseData.SetControlError(ControlNameSuffix + "Facilities", Model.Localiser["msg.validation.maximum.length", Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Facilities)]);
// Contact Methods.
if (ContactMethods != null)
{
ContactData = new SaxContactData("");
ContactMethod = ContactMethod ?? new String[0];
ContactValue = ContactValue ?? new String[0];
for (int idx = 0; idx < ContactMethod.Length && idx < ContactValue.Length; idx++)
{
String methodValue = ContactMethod[idx];
String value = ContactValue[idx];
if (methodValue == null & value == null) continue;
Sax.ContactMethod method = EnumUtil.ParseEnum(methodValue, Sax.ContactMethod.Unknown);
if (method > 0 && !value.IsEmpty() && SaxContactMethodHelper.IsValidContactMethodValue(method, value))
ContactData.SetContactMethodValue(method, value);
else SaLogger.Warn(fn + " Invalid Contact Method data. Method: " + methodValue + ". Value: " + value);
}
if (ContactData.Methods.Count != ContactMethods.ToInt())
{
SaLogger.Warn(fn + " Inconsistent Contact Methods received. Expected: " + ContactMethods + ". Received: " + ContactData.Methods.Count);
responseData.SetMessage("caption.contact.method", "System error");
}
}
// Phone Main - optional.
if (PhoneMain != null)
{
@@ -119,7 +147,7 @@ namespace Saxonite.Net.Core.Web.Online.Models
// Address.
Address.ValidateAddressData(responseData);
return !responseData.HasControlErrors();
return !responseData.HasControlErrors() && responseData.Message == null;
}
//-------------------------------------------------------------------
@@ -0,0 +1,28 @@
using Saxonite.Net.Core.Web.Base.App;
using Saxonite.Net.Core.Web.Base.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Saxonite.Net.Core.Web.Online.Models
{
//=======================================================================
public class Model_ContactMethod : SaxModel_Online
{
//-------------------------------------------------------------------
// Construction.
public Model_ContactMethod(SaxLocaliser localiser) :
base(localiser)
{
}
//-------------------------------------------------------------------
// Form properties.
public String ContactMethod { get; set; }
public String ContactValue { get; set; }
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -25,7 +25,6 @@
<ItemGroup>
<Folder Include="Online\Core\" />
<Folder Include="Online\Helpers\" />
</ItemGroup>
<ItemGroup>
@@ -1,6 +1,5 @@
@model Model_Account
@inject SaxLocaliser Localiser
@* Profile Organisations *@
<div class="sax-panel-section ProfileOrganisations sax-populating">
@@ -82,13 +81,54 @@
@* Profile Organisation dialog *@
<div id="dlgProfileOrganisation" class="sax-dialog" title="@Localiser["label.organisation"]">
<div class="spacer"></div>
<div class="spacer2"></div>
@using (Html.BeginForm(FormMethod.Post, new { @id = "frmProfileOrganisation", @class = "sax-form", @onSubmit = "return false;" }))
{
@Html.HiddenFor(model => model.Organisation.Id, new { @id = "", @class = "OrganisationId" })
@Html.HiddenFor(model => model.Organisation.Address.Id, new { @id = "", @class = "OrganisationAddressId" })
<partial name="~/Views/Common/OrganisationControls.cshtml" />
@* Core controls - name, category, sport, region *@
<partial name="~/Views/Common/OrganisationControls-Core.cshtml" />
@* Organisation About *@
<div class="sax-form-control OrganisationAbout">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for="ifOrganisationAbout"><span>@Localiser["label.about"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
@Html.TextAreaFor(model => model.Organisation.About, new { @id = "ifOrganisationAbout", @class = "OrganisationAbout sax-input", @rows = 6, @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_About) })
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation Facilities *@
<div class="sax-form-control OrganisationFacilities">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for="ifOrganisationFacilities"><span>@Localiser["label.facilities"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
@Html.TextAreaFor(model => model.Organisation.Facilities, new { @id = "ifOrganisationFacilities", @class = "OrganisationFacilities sax-input", @rows = 6, @maxlength = @Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Facilities) })
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Contact controls *@
<partial name="~/Views/Common/OrganisationControls-Contact.cshtml" />
@* ModelData_Address controls *@
<partial name="~/Views/Common/OrganisationControls-Address.cshtml" />
}
<div class="spacer"></div>
@@ -1,6 +1,8 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/CodeSelect")) return;
<link rel="stylesheet" href="~/css/sax-code-sel.css?@Model.HrefVersion" />
<script src="~/js/sax-code-sel.js?@Model.HrefVersion"></script>
<script type="text/javascript">
@@ -0,0 +1,50 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/ContactMethods")) return;
<script src="~/js/sax-cnt-mth.js?@Model.HrefVersion"></script>
<script type="text/javascript">
</script>
<div id="dlgContactMethod" class="sax-dialog sax-form" title="@Localiser["caption.contact.method"]">
<div class="spacer4"></div>
@* Method *@
<div class="sax-form-control ContactMethod">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.method"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<select name="ContactMethod" class="ContactMethod sax-select" style="max-width:240px;" ></select>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<div class="spacer"></div>
@* Value *@
<div class="sax-form-control ContactValue">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.value"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" name="ContactValue" class="ContactValue sax-input" />
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<div class="spacer"></div>
</div>
@@ -0,0 +1,99 @@
@* Organisation controls - Address *@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/OrganisationControls-Address")) return;
@* Organisation address - Line 1 *@
<div class="sax-form-control OrganisationAddressLine1">
<div class="row">
<div class="col-sm-3">
<div class="sax-caption">
<label for=""><span>@Localiser["label.address"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Line1" class="OrganisationAddressLine1 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Line 2 *@
<div class="sax-form-control OrganisationAddressLine2">
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Line2" class="OrganisationAddressLine2 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line2)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Line 3 *@
<div class="sax-form-control OrganisationAddressLine3">
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Line3" class="OrganisationAddressLine3 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line3)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Town *@
<div class="sax-form-control OrganisationAddressTown">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.town"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Town" class="OrganisationAddressTown sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Province *@
<div class="sax-form-control OrganisationAddressProvince">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.province"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Province" class="OrganisationAddressProvince sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Province)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - PostalCode *@
<div class="sax-form-control OrganisationAddressPostalCode">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.postalCode"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.PostalCode" class="OrganisationAddressPostalCode sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_PostalCode)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@@ -0,0 +1,75 @@
@* Organisation controls - Contact *@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/OrganisationControls-Contact")) return;
<style>
.OrganisationContactMethods .ContactMethods
{
min-height: 32px;
max-height: 64px;
background-color: #fff;
border: 1px solid #808080;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
overflow-y: scroll;
}
.OrganisationContactMethods .ContactMethods table.sax-data tr:hover
{
background-color: #f0f0f0;
}
.OrganisationContactMethods .ContactMethods table.sax-data .sax-label
{
margin: 0;
padding: 0 8px 0 0;
}
</style>
@* Organisation Contact Methods *@
<div class="sax-form-control OrganisationContactMethods">
<input type="hidden" name="Organisation.ContactMethods" value="0" />
<div class="row">
<div class="col-sm-3 row">
<div class="col">
<div class="sax-label">
<label for=""><span>@Localiser["label.contact"]</span></label>
</div>
</div>
<div class="fixed">
@* Action to add new contact method. *@
<div class="sax-actions">
<div class="sax-action sax-add pr4"><img src="~/img/action/add24.png" alt="@(Localiser["label.add"])" title="@(Localiser["label.add"])" /></div>
</div>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col">
@* List of existing contact methods with actions to edit/remove. *@
<div class="ContactMethods">
<table class="sax-data"></table>
</div>
<table class="sax-panel-item-template">
<tr class="ContactMethod">
<td style="width:20px;"><div class="sax-label nowrap"></div></td>
<td class="sax-value " style="width:70%;word-break: break-all;"></td>
<td class="sax-actions right nowrap" style="min-width:10px;">
<input type="hidden" name="Organisation.ContactMethod" />
<input type="hidden" name="Organisation.ContactValue" />
<div class="nowrap">
<div class="inlineb sax-action sax-edit"><img src="~/img/action/edit16.png" alt="@(Localiser["label.edit"])" title="@(Localiser["label.edit"])" /></div>
<div class="inlineb sax-action sax-remove"><img src="~/img/action/delete16.png" alt="@(Localiser["label.remove"])" title="@(Localiser["label.remove"])" /></div>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<partial name="~/Views/Common/ContactMethods.cshtml" />
@@ -0,0 +1,94 @@
@* Organisation controls - Core *@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/OrganisationControls-Core")) return;
@* Organisation name *@
<div class="sax-form-control OrganisationName">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.name"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" name="Organisation.Name" class="OrganisationName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name)" />
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3"></div>
<div class="col-sm row">
@* Organisation category *@
<div class="col-sm-6">
<div class="sax-form-control OrganisationCategory pr4">
<div class="sax-label">
<label for=""><span>@Localiser["label.category"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationCategoriesForSelect, Localiser["label.select"] + ":", new { @id = "", @name = "Organisation.Category", @class = "OrganisationCategory sax-select" })
</div>
<div class="sax-message"></div>
</div>
</div>
@* Organisation type *@
<div class="col-sm-6">
<div class="sax-form-control OrganisationType">
<div class="sax-label">
<label for=""><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationTypesForSelect, Localiser["label.select"] + ":", new { @id = "", @name = "Organisation.Type", @class = "OrganisationType sax-select" })
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
</div>
@* Organisation sport *@
<div class="sax-form-control OrganisationSportId">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.sport"]</span><span class="required">&nbsp;(*)</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<input type="hidden" name="Organisation.SportId" OrganisationSportId"" class="OrganisationSportId" />
<div class="col"><input type="text" class="OrganisationSportCaption sax-input" readonly="readonly" /> </div>
<div class="fixed"><button class="SelectSport sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation primary region *@
<div class="sax-form-control OrganisationRegionIdCountry">
<div class="row">
<div class="col-sm-3">
<div class="sax-label">
<label for=""><span>@Localiser["label.country"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<input type="hidden" name="Organisation.RegionIdCountry" OrganisationRegionIdCountry"" class="OrganisationRegionIdCountry" />
<div class="col"><input type="text" class="OrganisationRegionCaptionCountry sax-input" readonly="readonly" /> </div>
<div class="fixed"><button class="SelectRegionCountry sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@@ -1,208 +0,0 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
<div class="sax-form-control">
<div class="sax-caption">
<label for=""><span>@Localiser["label.organsiation.details"]</span></label>
</div>
</div>
@* Organisation name *@
<div class="sax-form-control OrganisationName">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.name"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control">
<input type="text" name="Organisation.Name" class="OrganisationName sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_Name)" />
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm row">
@* Organisation category *@
<div class="col-sm-6">
<div class="sax-form-control OrganisationCategory pr4">
<div class="sax-label">
<label for=""><span>@Localiser["label.category"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationCategoriesForSelect, Localiser["label.select"] + ":", new { @id = "", @name = "Organisation.Category", @class = "OrganisationCategory sax-select" })
</div>
<div class="sax-message"></div>
</div>
</div>
@* Organisation type *@
<div class="col-sm-6">
<div class="sax-form-control OrganisationType">
<div class="sax-label">
<label for=""><span>@Localiser["label.type"]</span><span class="required">&nbsp;*</span></label>
</div>
<div class="sax-control">
@Html.DropDownList("", Model.OrganisationTypesForSelect, Localiser["label.select"] + ":", new { @id = "", @name = "Organisation.Type", @class = "OrganisationType sax-select" })
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
</div>
@* Organisation sport *@
<div class="sax-form-control OrganisationSportId">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.sport"]</span><span class="required">&nbsp;(*)</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<input type="hidden" name="Organisation.SportId" OrganisationSportId"" class="OrganisationSportId" />
<div class="col"><input type="text" class="OrganisationSportCaption sax-input" readonly="readonly" /> </div>
<div class="fixed"><button class="SelectSport sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation country *@
<div class="sax-form-control OrganisationRegionIdCountry">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.country"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<input type="hidden" name="Organisation.RegionIdCountry" OrganisationRegionIdCountry"" class="OrganisationRegionIdCountry" />
<div class="col"><input type="text" class="OrganisationRegionCaptionCountry sax-input" readonly="readonly" /> </div>
<div class="fixed"><button class="SelectRegionCountry sax-button" style="min-width:auto;margin-left:4px;padding:4px 6px">@Localiser["label.select"]</button></div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation PhoneMain *@
<div class="sax-form-control OrganisationPhoneMain">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.phone"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.PhoneMain" class="OrganisationPhoneMain sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.Organisation_PhoneMain)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Line 1 *@
<div class="sax-form-control OrganisationAddressLine1">
<div class="row">
<div class="col-sm-4">
<div class="sax-caption">
<label for=""><span>@Localiser["label.organisation.address"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Line1" class="OrganisationAddressLine1 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line1)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Line 2 *@
<div class="sax-form-control OrganisationAddressLine2">
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Line2" class="OrganisationAddressLine2 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line2)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Line 3 *@
<div class="sax-form-control OrganisationAddressLine3">
<div class="row">
<div class="col-sm-4"></div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Line3" class="OrganisationAddressLine3 sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Line3)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Town *@
<div class="sax-form-control OrganisationAddressTown">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.town"]</span><span class="required">&nbsp;*</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Town" class="OrganisationAddressTown sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Town)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - Province *@
<div class="sax-form-control OrganisationAddressProvince">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.province"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.Province" class="OrganisationAddressProvince sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_Province)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@* Organisation address - PostalCode *@
<div class="sax-form-control OrganisationAddressPostalCode">
<div class="row">
<div class="col-sm-4">
<div class="sax-label">
<label for=""><span>@Localiser["label.postalCode"]</span></label>
</div>
</div>
<div class="col-sm">
<div class="sax-control row">
<div class="col"><input type="text" name="Organisation.Address.PostalCode" class="OrganisationAddressPostalCode sax-input" autocomplete="off" maxlength="@Model.GetControlMaxLength(SaxDbDfn_Core.ColumnIdx.ItemAddress_PostalCode)" /> </div>
</div>
<div class="sax-message"></div>
</div>
</div>
</div>
@@ -1,5 +1,8 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/OrganisationRequest")) return;
@{
Microsoft.AspNetCore.Html.HtmlString regionIdCountry = new Microsoft.AspNetCore.Html.HtmlString(Model.ValidUserSession ? Model.GetEncryptedRegionId(Model.SessionData.User.RegionIdCountry) : "");
String regionNameCountry = Model.ValidUserSession ? Localiser.EscapeJavascriptText(Model.GetRegionCaption(Model.SessionData.User.RegionIdCountry)) : "";
@@ -29,7 +32,7 @@
@* Contact Email Address *@
<div class="sax-form-control ContactEmailAddress">
<div class="row">
<div class="col-sm-4">
<div class="col-sm-3">
<div class="sax-label">
<label for="ifContactEmailAddress"><span>@Localiser["label.email"]</span><span class="required">&nbsp;*</span></label>
</div>
@@ -44,7 +47,7 @@
</div>
<div class="row">
<div class="col-sm-4">@* No label. *@</div>
<div class="col-sm-3">@* No label. *@</div>
<div class="col-sm row">
@* Contact First Name *@
@@ -78,7 +81,16 @@
}
<partial name="~/Views/Common/OrganisationControls.cshtml" />
@* Organisation core details - name, category, sport, region etc *@
<div class="sax-form-control">
<div class="sax-caption">
<label for=""><span>@Localiser["label.organsiation.details"]</span></label>
</div>
</div>
<partial name="~/Views/Common/OrganisationControls-Core.cshtml" />
@* Organisation Address *@
<partial name="~/Views/Common/OrganisationControls-Address.cshtml" />
}
@@ -1,6 +1,8 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/OrganisationSelect")) return;
<link rel="stylesheet" href="~/css/sax-org-sel.css?@Model.HrefVersion" />
<script type="text/javascript">
sax.selectOrganisation = {};
@@ -1,6 +1,8 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/RegionSelect")) return;
<link rel="stylesheet" href="~/css/sax-reg-sel.css?@Model.HrefVersion" />
<script type="text/javascript">
</script>
@@ -1,6 +1,8 @@
@model SaxModel_Online
@inject SaxLocaliser Localiser
@if (!Model.RegisterView("Views/Common/SportSelect")) return;
<link rel="stylesheet" href="~/css/sax-spt-sel.css?@Model.HrefVersion" />
<script type="text/javascript">
</script>
@@ -4,6 +4,22 @@
/* Organisation dialog panel */
}
<style>
#dlgOrganisation .OrganisationContact .sax-value img
{
margin-right: 8px;
}
#dlgOrganisation .OrganisationAbout .sax-value, #dlgOrganisation .OrganisationFacilities .sax-value
{
min-height: 40px;
max-height: 170px;
padding:2px 4px;
border: 1px solid #a0a0a0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
overflow-y: scroll;
}
</style>
<script type="text/javascript">
</script>
@@ -13,7 +29,7 @@
}
<div id="dlgOrganisation" class="sax-dialog" title="">
<div class="spacer"></div>
<div class="spacer"><a href="#"></a>"</div>
<div class="row OrganisationCategory">
<div class="col-sm-3"><div class="sax-label text-sm-right">@Localiser["label.type"]</div></div>
@@ -29,11 +45,15 @@
</div>
<div class="row OrganisationAbout">
<div class="col-sm-3"><div class="sax-label text-sm-right">@Localiser["label.about"]</div></div>
<div class="col-sm"><div class="sax-value" style="max-height:240px;overflow-y:auto;"></div></div>
<div class="col-sm"><div class="sax-value"></div></div>
</div>
<div class="row OrganisationFacilities">
<div class="col-sm-3"><div class="sax-label text-sm-right">@Localiser["label.facilities"]</div></div>
<div class="col-sm"><div class="sax-value" style="max-height:240px;overflow-y:auto;"></div></div>
<div class="col-sm"><div class="sax-value"></div></div>
</div>
<div class="row OrganisationContact">
<div class="col-sm-3"><div class="sax-label text-sm-right">@Localiser["label.contact"]</div></div>
<div class="col-sm"><div class="sax-value"></div></div>
</div>
<div class="row OrganisationAddress">
<div class="col-sm-3"><div class="sax-label text-sm-right">@Localiser["label.address"]</div></div>
@@ -238,8 +238,8 @@
.sax-panel-item > .sax-content
{
margin: 4px 8px;
padding: 4px 4px;
margin: 4px 8px 2px 8px;
padding: 2px 2px;
}
.sax-panel-item .sax-note
@@ -193,8 +193,10 @@
overflow-y: scroll;
}
.sax-form .sax-input:read-only, .sax-form .sax-textarea:read-only
.sax-form .sax-input:read-only, .sax-form .sax-textarea:read-only, .sax-form .sax-select:disabled
{
color: #202020;
opacity: 1;
background-color: #f8f8f8;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,69 @@
/*
* Contact Methods script.
*/
(function (win, doc, undef)
{
"use strict";
let cm = sax.mdl.contactMethods = { fn: {}, data: {}, ajax: {} };
let $dlg = cm.$dlg = {};
//--------------------------------------------------------------
/*
* Config:
* fnCallback Method to call to apply changes.
* methods Full list of methods.
* methodsUsed List of methods already in use.
* method Current selected method (if updating).
* value Current value.
*/
sax.editContactMethod = cm.fn.edit = function (cfg)
{
cm.fn.init();
cm.data.cfg = cfg || {};
cm.$mth.empty();
for (let mth of cfg.methods || [])
{
if (mth.code && mth.code == cfg.method || !(cfg.methodsUsed || []).includes(mth.code))
cm.$mth.append($('<option>').prop('value', mth.code).text(mth.desc));
}
cm.$mth.val(cfg.method).attr('disabled', cfg.method && cm.$mth.val() == cfg.method ? true : null);
cm.$val.val(cfg.value);
sax.openDialog($dlg.conMth, 600, 240);
}
//--------------------------------------------------------------
cm.fn.applyChanges = function ()
{
cm.ajax.applyChanges = cm.ajax.applyChanges || { url: sax.url.base + 'Reference/Ajax/ValidateContactMethod', callbackFn: cm.fn.onApplyChanges };
cm.ajax.applyChanges.formData = new FormData();
cm.ajax.applyChanges.formData.append("__RequestVerificationToken", $('#frmNavigate input[name="__RequestVerificationToken"]').val());
cm.ajax.applyChanges.formData.append("ContactMethod", $('select[name="ContactMethod"]', $dlg.conMth).val());
cm.ajax.applyChanges.formData.append("ContactValue", $('input[name="ContactValue"]', $dlg.conMth).val());
sax.doAjaxRequest(cm.ajax.applyChanges, 50);
}
cm.fn.onApplyChanges = function (response)
{
if (!response) return;
sax.refreshControlValues(response.controlValues, $dlg.conMth);
if (!response.success) return;
$dlg.conMth.dialog('close');
if (cm.data.cfg.fnCallback) cm.data.cfg.fnCallback(cm.$mth.val(), $('option:selected', cm.$mth).text(), cm.$val.val());
}
//--------------------------------------------------------------
cm.fn.init = function ()
{
if ($dlg.conMth) return;
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.ok] = function () { cm.fn.applyChanges(); };
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
$dlg.conMth = $('#dlgContactMethod').dialog(opt);
cm.$mth = $('.sax-select.ContactMethod', $dlg.conMth);
cm.$val = $('.sax-input.ContactValue', $dlg.conMth);
}
//--------------------------------------------------------------
}(window, window.document));
/* The End */
@@ -50,7 +50,7 @@
$('.OrganisationName', $item).text(item.name);
$('.OrganisationCategory', $item).text(item.categoryDesc);
$('.OrganisationSport', $item).text(item.sportName);
$('.OrganisationLocation', $item).text(item.location);
$('.OrganisationLocation', $item).text(item.regionName);
let $bgr = $('.sax-burger', $item);
let $mnu = $('ul.sax-dropdown-menu', $bgr).empty();
{
@@ -134,16 +134,20 @@
}
so.onViewItem = function (response)
{
sax.debug('onViewItem',response);
//sax.debug('onViewItem', response);
if (!response.success) return;
let dlg = $dlg.org;
let item = so.data.organisation = response.organisation;
$('.OrganisationName', dlg).val(item.name);
$('.OrganisationCategory', dlg).toggle(!!item.category).find('.sax-value').text(item.category);
$('.OrganisationSport', dlg).toggle(!!item.sport).find('.sax-value').text(item.sport);
$('.OrganisationLocation', dlg).toggle(!!item.location).find('.sax-value').text(item.location);
$('.OrganisationAbout', dlg).toggle(!!item.about).find('.sax-value').html(item.about.replace('\n','<br/>'));
$('.OrganisationFacilities', dlg).toggle(!!item.facilities).find('.sax-value').html(item.facilities.replace('\n', '<br/>'));
$('.OrganisationCategory', dlg).toggle(!!item.categoryDesc).find('.sax-value').text(item.categoryDesc);
$('.OrganisationSport', dlg).toggle(!!item.sportName).find('.sax-value').text(item.sportName);
$('.OrganisationLocation', dlg).toggle(!!item.regionName).find('.sax-value').text(item.regionName);
$('.OrganisationAbout', dlg).toggle(!!item.about).find('.sax-value').html((item.about || '').replace('\n', '<br/>'));
$('.OrganisationFacilities', dlg).toggle(!!item.facilities).find('.sax-value').html((item.facilities || '').replace('\n', '<br/>'));
let contact = [];
for (let cnt of item.contacts || [])
contact.push(cnt.value);
$('.OrganisationContact', dlg).toggle(!!contact.length).find('.sax-value').html(contact.join('<br/>'));
$('.OrganisationAddress', dlg).toggle(!!item.address).find('.sax-value').html(item.address ? item.address.replace('\n', '<br/>') : '');
$('.OrganisationPostalCode', dlg).toggle(!!item.postalCode).find('.sax-value').text(item.postalCode);
sax.clearControlErrors();
@@ -166,7 +170,7 @@
$('.FilterCategory', $frm.filter).on('change', function () { so.refreshResults(); });
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
opt.buttons[sax.dlg.btn.close] = function () { $(this).dialog('close'); };
$dlg.org = $('#dlgOrganisation').dialog(opt);
$frm.orgId = $('#frmOrganisationId');
@@ -157,7 +157,7 @@
$('.FilterCategory', $frm.filter).on('change', function () { su.refreshResults(); });
var opt = sax.dlgOpts();
opt.buttons[sax.dlg.btn.cancel] = function () { $(this).dialog('close'); };
opt.buttons[sax.dlg.btn.close] = function () { $(this).dialog('close'); };
$dlg.usr = $('#dlgUser').dialog(opt);
$frm.usrId = $('#frmUserId');
+76 -10
View File
@@ -5,8 +5,8 @@
(function (win, doc, undef)
{
"use strict";
let po = sax.mdl.profileOrganisations = sax.mdl.profileOrganisations || { $pnl: {}, $dlg: {}, $frm: {} };
let $pnl = po.$pnl, $dlg = po.$dlg, $frm = po.$frm;
let po = sax.mdl.profileOrganisations = sax.mdl.profileOrganisations || { data: {}, ajax: {} };
let $pnl = po.$pnl = {}, $dlg = po.$dlg = {}, $frm = po.$frm = {};
//--------------------------------------------------------------
sax.refreshProfileOrganisationsInfo = function (delay)
@@ -20,16 +20,16 @@
{
//sax.debug('refreshProfileOrganisations');
delete sax.page.profileOrganisationsChanged;
sax.ajax.profileOrganisations = sax.ajax.profileOrganisations || { url: sax.url.base + 'Account/Ajax/GetProfileOrganisations', formId: 'frmNavigate', noWaitIcon: true };
sax.ajax.profileOrganisations.callbackFn = callbackFn;
sax.doAjaxRequest(sax.ajax.profileOrganisations, 50);
po.ajax.profileOrganisations = po.ajax.profileOrganisations || { url: sax.url.base + 'Account/Ajax/GetProfileOrganisations', formId: 'frmNavigate', noWaitIcon: true };
po.ajax.profileOrganisations.callbackFn = callbackFn;
sax.doAjaxRequest(po.ajax.profileOrganisations, 50);
}
po.onRefreshProfileOrganisationsInfo = function (response)
{
//sax.debug('onRefreshProfileOrganisationsInfo', response);
if (!response || !response.success) return;
$('.sax-message', $pnl.section).stop(true, false).fadeOut(200).empty();
po.data.contactMethods = response.contactMethods;
let items = response.organisations;
if (!items) return;
let $items = $('.sax-panel-results.Organisations', $pnl.section).empty();
@@ -95,12 +95,12 @@
//sax.debug('po.updateOrganisation', $item, item);
$('.OrganisationId', $frm.orgId).val(item.id);
sax.ajax.profileOrganisation = sax.ajax.profileOrganisation || { url: sax.url.base + 'Account/Ajax/GetProfileOrganisation', formId: 'frmProfileOrganisationId', callbackFn: po.doUpdateOrganisation };
sax.doAjaxRequest(sax.ajax.profileOrganisation, 50);
po.ajax.profileOrganisation = po.ajax.profileOrganisation || { url: sax.url.base + 'Account/Ajax/GetProfileOrganisation', formId: 'frmProfileOrganisationId', callbackFn: po.doUpdateOrganisation };
sax.doAjaxRequest(po.ajax.profileOrganisation, 50);
}
po.doUpdateOrganisation = function (response)
{
sax.debug('doUpdateOrganisation', response);
//sax.debug('doUpdateOrganisation', response);
if (!response || !response.success) return;
let item = response.organisation;
if (!item) return;
@@ -114,6 +114,16 @@
$('.OrganisationSportCaption', $frm.org).val(item.sportName);
$('.OrganisationRegionIdCountry', $frm.org).val(item.regionIdCountry);
$('.OrganisationRegionCaptionCountry', $frm.org).val(item.regionNameCountry);
$('.OrganisationAbout', $frm.org).val(item.about);
$('.OrganisationFacilities', $frm.org).val(item.facilities);
$pnl.tblconMths.empty();
let conMths = item.contactMethods || [];
for (let idx = 0; idx < conMths.length; idx++)
{
let conMth = conMths[idx];
$pnl.tblconMths.append(po.getConMthEl(conMth.method, conMth.methodCaption, conMth.value));
}
po.sortConMths();
let address = item.address || {};
$('input.OrganisationAddressId', $frm.org).val(address.id);
$('input.OrganisationAddressLine1', $frm.org).val(address.line1);
@@ -123,7 +133,7 @@
$('input.OrganisationAddressProvince', $frm.org).val(address.province);
$('input.OrganisationAddressCountry', $frm.org).val(address.country);
$('input.OrganisationAddressPostalCode', $frm.org).val(address.postalCode);
sax.openDialog($dlg.org, 600, 600);
sax.openDialog($dlg.org, 640, 800);
}
po.storeOrganisation = function ()
{
@@ -165,6 +175,59 @@
$('.OrganisationRegionCaptionCountry', $frm.org).val(region ? region.name : '');
}
//--------------------------------------------------------------
po.getConMthCfg = function (usedMths, mth, val)
{
let cfg = { fnCallback: po.applyConMth, methods: po.data.contactMethods, methodsUsed: usedMths, method: mth, value: val };
return cfg;
}
po.getUsedMths = function ()
{
return $('input[name="Organisation.ContactMethod"]', $frm.org).map(function () { return $(this).val(); }).get();
}
po.addConMth = function ()
{
sax.editContactMethod(po.getConMthCfg(po.getUsedMths()));
}
po.editConMth = function (mth, val)
{
sax.editContactMethod(po.getConMthCfg(po.getUsedMths(), mth, val));
}
po.getConMthId = function (mth)
{
return 'ConMth_' + mth;
}
po.applyConMth = function (mth, mthDsc, val)
{
//sax.debug('applyConMth(\'' + mth + '\',\'' + mthDsc + '\',\'' + val + '\')');
$('#' + po.getConMthId(mth), $pnl.conMths).remove();
$pnl.tblconMths.append(po.getConMthEl(mth, mthDsc, val));
po.sortConMths();
}
po.sortConMths = function ()
{
let $rows = $pnl.tblconMths.find('tr').detach().sort(function (a, b)
{
return $('.sax-label', a).text().localeCompare($('.sax-label', b).text());
}).appendTo($pnl.tblconMths);
$('input[name="Organisation.ContactMethods"]', $pnl.conMths).val($rows.length);
}
po.getConMthEl = function (mth, mthDsc, val)
{
let $conMth = $('.sax-panel-item-template .ContactMethod', $pnl.conMths).clone().prop('id', po.getConMthId(mth));
$('.sax-label', $conMth).text(mthDsc);
$('.sax-value', $conMth).text(val);
$('input[name="Organisation.ContactMethod"]', $conMth).val(mth);
$('input[name="Organisation.ContactValue"]', $conMth).val(val);
$conMth.on('click', '.sax-action.sax-edit', function () { po.editConMth(mth, val); });
$conMth.on('click', '.sax-action.sax-remove', function () { po.clearConMth(mth); });
return $conMth;
}
po.clearConMth = function (mth)
{
$('#' + po.getConMthId(mth), $pnl.conMths).remove();
}
//--------------------------------------------------------------
$(function ()
{
@@ -178,6 +241,9 @@
$frm.org = $('#frmProfileOrganisation', $dlg.org);
$frm.org.on('dblclick', 'input.OrganisationSportCaption', po.selectOrgSport).on('click', 'button.SelectSport', po.selectOrgSport);
$frm.org.on('dblclick', 'input.OrganisationRegionCaptionCountry', po.selectOrgRegionCountry).on('click', 'button.SelectRegionCountry', po.selectOrgRegionCountry);
$frm.org.on('click', '.OrganisationContactMethods .sax-action.sax-add', po.addConMth);
$pnl.conMths = $('.OrganisationContactMethods', $frm.org);
$pnl.tblconMths = $('table.sax-data', $pnl.conMths);
});
//--------------------------------------------------------------
@@ -84,6 +84,19 @@ namespace Saxonite.Net.Standard.Base.App
}
}
}
public static class Links
{
public static class Targets
{
public static String Website { get; } = "sax-lnk-web";
public static String Wikipedia { get; } = "sax-lnk-wikip";
public static String Facebook { get; } = "sax-lnk-fbook";
public static String Twitter { get; } = "sax-lnk-twit";
public static String Instagram { get; } = "sax-lnk-insta";
public static String LinkedIn { get; } = "sax-lnk-lnkin";
public static String Article { get; } = "sax-art-lnk";
}
}
public static class Articles
{
public static class Segments
+2 -1
View File
@@ -18,7 +18,7 @@ namespace Saxonite.Net.Standard.Base.App
//-------------------------------------------------------------------
public static class Version
{
private static String version { get; } = "1.2.6.1";
private static String version { get; } = "1.2.6.2";
// Retrieve version.
public static String GetFullVersion () { return version; }
public static String GetAppVersion ()
@@ -43,6 +43,7 @@ namespace Saxonite.Net.Standard.Base.App
// 1.2.6 16-May-2022 Image resizing
// - Profile and article images resized to maximum width/height.
// - Organisation About and Facilities properties.
// - Online profile organisation contact methods.
// 1.2.5 20-Apr-2022 Article feedback
// - Online Activity/Article feedback 5 stars, summary on Article list/popup.
// - Online Activity filter.
+30
View File
@@ -30,6 +30,7 @@ namespace Saxonite.Net.Standard.Base.App
OrganisationCategory,
OrganisationRole,
AddressType,
ContactMethod,
EventType,
OpportunityType,
ActivityReaction,
@@ -253,6 +254,35 @@ namespace Saxonite.Net.Standard.Base.App
Delivery = 60,
}
//-------------------------------------------------------------------
public enum ContactMethodType
{
Unknown,
Phone,
Email,
WebUrl,
}
//-------------------------------------------------------------------
public enum ContactMethod
{
Unknown = 0,
/* Do not change the numeric values or names - tied to database. */
PhoneMain = 10,
PhoneMobile = 20,
PhoneHome = 30,
PhoneOffice = 40,
// Online.
Email = 100,
Website = 200,
Wikipedia = 210,
// Social media.
LinkedIn = 300,
Twitter = 310,
Facebook = 320,
Instagram = 330,
}
//-------------------------------------------------------------------
/// <summary>Event Type</summary>
public enum EventType
@@ -100,6 +100,7 @@ namespace Saxonite.Net.Standard.Base.App
public List<TypeCodeDesc> OrganisationCategoryCodes { get { return GetCodesOfType(Sax.CodeType.OrganisationCategory); } }
public List<TypeCodeDesc> OrganisationRoleCodes { get { return GetCodesOfType(Sax.CodeType.OrganisationRole); } }
public List<TypeCodeDesc> AddressTypeCodes { get { return GetCodesOfType(Sax.CodeType.AddressType); } }
public List<TypeCodeDesc> ContactMethodCodes { get { return GetCodesOfType(Sax.CodeType.ContactMethod); } }
public List<TypeCodeDesc> EventTypeCodes { get { return GetCodesOfType(Sax.CodeType.EventType); } }
public List<TypeCodeDesc> OpportunityTypeCodes { get { return GetCodesOfType(Sax.CodeType.OpportunityType); } }
public List<TypeCodeDesc> ActivityReactionCodes { get { return GetCodesOfType(Sax.CodeType.ActivityReaction); } }
@@ -1,4 +1,5 @@
using System;
using Sarand.Net.Standard.Base.Core;
using System;
using System.Collections.Generic;
using System.Text;
@@ -11,8 +12,244 @@ namespace Saxonite.Net.Standard.Base.App
{
//-------------------------------------------------------------------
// Data members.
// Code types.
private static readonly List<TypeCodeDesc> yesNoCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> dataItemTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> genderCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> sportSpecialityLabelCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> sportParticipationCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> sportOfficiatingCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> regionTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> userRoleCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> titleCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> imageTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> organisationTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> organisationCategoryCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> organisationRoleCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> addressTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> contactMethodCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> eventTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> opportunityTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> activityReactionCodes = new List<TypeCodeDesc>();
//-------------------------------------------------------------------
// C o d e T y p e s
//-------------------------------------------------------------------
public static List<TypeCodeDesc> GetCodesOfType(Sax.CodeType codeType)
{
// Lists are cloned to avoid modifications to the internal static lists.
switch (codeType)
{
case Sax.CodeType.YesNo:
return new List<TypeCodeDesc>(yesNoCodes);
case Sax.CodeType.DataItemType:
return new List<TypeCodeDesc>(dataItemTypeCodes);
case Sax.CodeType.Gender:
return new List<TypeCodeDesc>(genderCodes);
case Sax.CodeType.SportSpecialityLabel:
return new List<TypeCodeDesc>(sportSpecialityLabelCodes);
case Sax.CodeType.SportParticipation:
return new List<TypeCodeDesc>(sportParticipationCodes);
case Sax.CodeType.SportOfficiating:
return new List<TypeCodeDesc>(sportOfficiatingCodes);
case Sax.CodeType.RegionType:
return new List<TypeCodeDesc>(regionTypeCodes);
case Sax.CodeType.UserRole:
return new List<TypeCodeDesc>(userRoleCodes);
case Sax.CodeType.Title:
return new List<TypeCodeDesc>(titleCodes);
case Sax.CodeType.ImageType:
return new List<TypeCodeDesc>(imageTypeCodes);
case Sax.CodeType.OrganisationType:
return new List<TypeCodeDesc>(organisationTypeCodes);
case Sax.CodeType.OrganisationCategory:
return new List<TypeCodeDesc>(organisationCategoryCodes);
case Sax.CodeType.OrganisationRole:
return new List<TypeCodeDesc>(organisationRoleCodes);
case Sax.CodeType.AddressType:
return new List<TypeCodeDesc>(addressTypeCodes);
case Sax.CodeType.ContactMethod:
return new List<TypeCodeDesc>(contactMethodCodes);
case Sax.CodeType.EventType:
return new List<TypeCodeDesc>(eventTypeCodes);
case Sax.CodeType.OpportunityType:
return new List<TypeCodeDesc>(opportunityTypeCodes);
case Sax.CodeType.ActivityReaction:
return new List<TypeCodeDesc>(activityReactionCodes);
default:
throw new NotSupportedException(nameof(SaxSystem) + ".GetCodesOfType Unexpected code type: " + codeType.ToString());
}
}
//-------------------------------------------------------------------
/// <summary>Static code type initialisation.</summary>
private static void InitCodeTypes()
{
//---------------------------------------------------------------
// Yes No options.
yesNoCodes.Add(Sax.YesNo.Yes, "YES", "Yes");
yesNoCodes.Add(Sax.YesNo.No, "NO", "No");
//---------------------------------------------------------------
// Data item types.
// Reference data.
dataItemTypeCodes.Add(Sax.DataItemType.Region, "Region", "Region");
dataItemTypeCodes.Add(Sax.DataItemType.Sport, "Sport", "Sport");
// Accounts.
dataItemTypeCodes.Add(Sax.DataItemType.UserAccount, "UserAccount", "User Account");
dataItemTypeCodes.Add(Sax.DataItemType.UserRole, "UserRole", "User Role");
dataItemTypeCodes.Add(Sax.DataItemType.UserOrganisation, "UserOrganisation", "User Organisation");
dataItemTypeCodes.Add(Sax.DataItemType.UserSport, "UserSport", "User Sport");
dataItemTypeCodes.Add(Sax.DataItemType.Organisation, "Organisation", "Organisation");
// Activty data.
dataItemTypeCodes.Add(Sax.DataItemType.ActivityIndex, "ActivityIndex", "Activity Index");
dataItemTypeCodes.Add(Sax.DataItemType.UserActivity, "UserActivity", "User Activity");
dataItemTypeCodes.Add(Sax.DataItemType.Article, "Article", "Article");
dataItemTypeCodes.Add(Sax.DataItemType.OrganisationOpportunity, "OrganisationOpportunity", "Organisation Opportunity");
dataItemTypeCodes.Add(Sax.DataItemType.OrganisationEvent, "OrganisationEvent", "Organisation Event");
// Item link components.
dataItemTypeCodes.Add(Sax.DataItemType.ItemSport, "ItemSport", "Item Sport");
dataItemTypeCodes.Add(Sax.DataItemType.ItemImage, "ItemImage", "Item Image");
//---------------------------------------------------------------
// Gender.
genderCodes.Add(Sax.Gender.Female, "Female", "Female");
genderCodes.Add(Sax.Gender.Male, "Male", "Male");
genderCodes.Add(Sax.Gender.TransFemale, "TransFemale", "TransFemale");
genderCodes.Add(Sax.Gender.TransMale, "TransMale", "TransMale");
genderCodes.Add(Sax.Gender.Nonconforming, "Nonconforming", "Nonconforming");
genderCodes.Add(Sax.Gender.PreferNotToSay, "PreferNotToSay", "Prefer not to say");
//---------------------------------------------------------------
// Sport speciality label.
sportSpecialityLabelCodes.Add(Sax.SportSpecialityLabel.Positon, "POS", "Positon");
sportSpecialityLabelCodes.Add(Sax.SportSpecialityLabel.Discipline, "DIS", "Discipline");
sportSpecialityLabelCodes.Add(Sax.SportSpecialityLabel.NotRelevant, "NRE", "Not relevant");
//---------------------------------------------------------------
// Sport participation.
sportParticipationCodes.Add(Sax.SportParticipation.Professional, "PRO", "Professional");
sportParticipationCodes.Add(Sax.SportParticipation.Regular, "REG", "Regular");
sportParticipationCodes.Add(Sax.SportParticipation.Occasional, "OCC", "Occasional");
sportParticipationCodes.Add(Sax.SportParticipation.Spectator, "SPC", "Spectator");
sportParticipationCodes.Add(Sax.SportParticipation.Interested, "INT", "Interested");
//---------------------------------------------------------------
// Sport officiating.
sportOfficiatingCodes.Add(Sax.SportParticipation.Professional, "PRO", "Professional");
sportOfficiatingCodes.Add(Sax.SportParticipation.Regular, "REG", "Regular");
sportOfficiatingCodes.Add(Sax.SportParticipation.Occasional, "OCC", "Occasional");
//---------------------------------------------------------------
// Region types.
regionTypeCodes.Add(Sax.RegionType.Universe, "UNIV", "Universe");
regionTypeCodes.Add(Sax.RegionType.Galaxy, "GALAX", "Galaxy");
regionTypeCodes.Add(Sax.RegionType.World, "WORLD", "World");
regionTypeCodes.Add(Sax.RegionType.Continent, "CONT", "Continent");
regionTypeCodes.Add(Sax.RegionType.SubContinent, "SUBC", "Sub-Continent");
regionTypeCodes.Add(Sax.RegionType.Country, "COUN", "Country");
regionTypeCodes.Add(Sax.RegionType.State, "STAT", "State");
regionTypeCodes.Add(Sax.RegionType.Province, "PROV", "Province");
//---------------------------------------------------------------
// User roles.
userRoleCodes.Add(Sax.UserRole.Journalist, "JRNLST", "Journalist");
userRoleCodes.Add(Sax.UserRole.SystemAdmin, "SYSADM", "System Admin");
//---------------------------------------------------------------
// Titles.
titleCodes.Add(Sax.Title.Mr, "Mr", "Mr");
titleCodes.Add(Sax.Title.Mrs, "Mrs", "Mrs");
titleCodes.Add(Sax.Title.Miss, "Miss", "Miss");
titleCodes.Add(Sax.Title.Mx, "Mx", "Mx");
titleCodes.Add(Sax.Title.Dr, "Dr", "Dr");
titleCodes.Add(Sax.Title.Sir, "Sir", "Sir");
titleCodes.Add(Sax.Title.Lord, "Lord", "Lord");
titleCodes.Add(Sax.Title.Lady, "Lady", "Lady");
//---------------------------------------------------------------
// Image types.
imageTypeCodes.Add(Sax.ImageType.Avatar, "Avatar", "Avatar");
imageTypeCodes.Add(Sax.ImageType.AvatarUpload, "AvatarUpload", "Avatar - upload");
imageTypeCodes.Add(Sax.ImageType.Article, "Article", "Article");
imageTypeCodes.Add(Sax.ImageType.ArticleUpload, "ArticleUpload", "Article - upload");
//---------------------------------------------------------------
// Organisation types.
organisationTypeCodes.Add(Sax.OrganisationType.SocialEnterprise, "SEN", "Social Enterprise");
organisationTypeCodes.Add(Sax.OrganisationType.CommunityGroup, "CGR", "Community Group");
organisationTypeCodes.Add(Sax.OrganisationType.Charity, "CTY", "Charity");
organisationTypeCodes.Add(Sax.OrganisationType.Commercial, "CMC", "Commercial");
organisationTypeCodes.Add(Sax.OrganisationType.PublicSector, "PBS", "Public Sector");
//---------------------------------------------------------------
// Organisation categories.
organisationCategoryCodes.Add(Sax.OrganisationCategory.Association, "ASC", "Association");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Club, "CLB", "Club");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Society, "SOC", "Society");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Education, "EDU", "Education");
organisationCategoryCodes.Add(Sax.OrganisationCategory.SportDepartment, "SPD", "Sport Department");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Syndicate, "SYN", "Syndicate");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Partner, "PRT", "Partner");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Other, "OTH", "Other");
//---------------------------------------------------------------
// Organisation roles.
organisationRoleCodes.Add(Sax.OrganisationRole.Member, "MBR", "Member");
organisationRoleCodes.Add(Sax.OrganisationRole.Admin, "ADM", "Admin");
organisationRoleCodes.Add(Sax.OrganisationRole.MemberAdmin, "MBA", "Members");
organisationRoleCodes.Add(Sax.OrganisationRole.ScheduleAdmin, "SCA", "Schedule");
organisationRoleCodes.Add(Sax.OrganisationRole.OpportunityAdmin, "OPA", "Opportunities");
organisationRoleCodes.Add(Sax.OrganisationRole.ArticleAdmin, "ARA", "Articles");
//---------------------------------------------------------------
// Address Types.
addressTypeCodes.Add(Sax.AddressType.Location, "Location", "Location");
addressTypeCodes.Add(Sax.AddressType.Home, "Home", "Home");
addressTypeCodes.Add(Sax.AddressType.Office, "Office", "Office");
addressTypeCodes.Add(Sax.AddressType.Delivery, "Delivery", "Delivery");
//---------------------------------------------------------------
// Contact methods.
contactMethodCodes.Add(Sax.ContactMethod.PhoneMain, Sax.ContactMethod.PhoneMain.ToString(), "Phone - main");
contactMethodCodes.Add(Sax.ContactMethod.PhoneMobile, Sax.ContactMethod.PhoneMobile.ToString(), "Phone - mobile");
contactMethodCodes.Add(Sax.ContactMethod.PhoneHome, Sax.ContactMethod.PhoneHome.ToString(), "Phone - home");
contactMethodCodes.Add(Sax.ContactMethod.PhoneOffice, Sax.ContactMethod.PhoneOffice.ToString(), "Phone - office");
// Online.
contactMethodCodes.Add(Sax.ContactMethod.Email, Sax.ContactMethod.Email.ToString(), "Email");
contactMethodCodes.Add(Sax.ContactMethod.Website, Sax.ContactMethod.Website.ToString(), "Website");
contactMethodCodes.Add(Sax.ContactMethod.Wikipedia, Sax.ContactMethod.Wikipedia.ToString(), "Wikipedia");
// Social media.
contactMethodCodes.Add(Sax.ContactMethod.LinkedIn, Sax.ContactMethod.LinkedIn.ToString(), "LinkedIn");
contactMethodCodes.Add(Sax.ContactMethod.Twitter, Sax.ContactMethod.Twitter.ToString(), "Twitter");
contactMethodCodes.Add(Sax.ContactMethod.Facebook, Sax.ContactMethod.Facebook.ToString(), "Facebook");
contactMethodCodes.Add(Sax.ContactMethod.Instagram, Sax.ContactMethod.Instagram.ToString(), "Instagram");
//---------------------------------------------------------------
// Event types.
eventTypeCodes.Add(Sax.EventType.Playing, "PLG", "Playing");
eventTypeCodes.Add(Sax.EventType.Training, "TRN", "Training");
eventTypeCodes.Add(Sax.EventType.Organisation, "ORG", "Organisation");
eventTypeCodes.Add(Sax.EventType.Social, "SCL", "Social");
//---------------------------------------------------------------
// Opportunity types.
opportunityTypeCodes.Add(Sax.OpportunityType.Playing, "PLG", "Playing");
opportunityTypeCodes.Add(Sax.OpportunityType.Official, "OFL", "Official");
opportunityTypeCodes.Add(Sax.OpportunityType.Coaching, "CHG", "Coaching");
opportunityTypeCodes.Add(Sax.OpportunityType.Volunteer, "VTR", "Volunteer");
opportunityTypeCodes.Add(Sax.OpportunityType.Staff, "STF", "Staff");
opportunityTypeCodes.Add(Sax.OpportunityType.Board, "BRD", "Board");
//---------------------------------------------------------------
// Activity Reactions.
activityReactionCodes.Add(Sax.ActivityReaction.Good, "Good", "Good");
activityReactionCodes.Add(Sax.ActivityReaction.VeryGood, "VeryGood", "Very Good");
activityReactionCodes.Add(Sax.ActivityReaction.Exceptional, "Exceptional", "Exceptional");
//---------------------------------------------------------------
}
//-------------------------------------------------------------------
}
@@ -13,174 +13,14 @@ namespace Saxonite.Net.Standard.Base.App
{
//-------------------------------------------------------------------
// Data members.
// Code types.
private static readonly List<TypeCodeDesc> yesNoCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> dataItemTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> genderCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> sportSpecialityLabelCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> sportParticipationCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> sportOfficiatingCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> regionTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> userRoleCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> titleCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> imageTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> organisationTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> organisationCategoryCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> organisationRoleCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> addressTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> eventTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> opportunityTypeCodes = new List<TypeCodeDesc>();
private static readonly List<TypeCodeDesc> activityReactionCodes = new List<TypeCodeDesc>();
//-------------------------------------------------------------------
/// <summary>Static initialisation.</summary>
static SaxSystem()
{
//---------------------------------------------------------------
// Yes No options.
yesNoCodes.Add(Sax.YesNo.Yes, "YES", "Yes");
yesNoCodes.Add(Sax.YesNo.No, "NO", "No");
//---------------------------------------------------------------
// Data item types.
// Reference data.
dataItemTypeCodes.Add(Sax.DataItemType.Region, "Region", "Region");
dataItemTypeCodes.Add(Sax.DataItemType.Sport, "Sport", "Sport");
// Accounts.
dataItemTypeCodes.Add(Sax.DataItemType.UserAccount, "UserAccount", "User Account");
dataItemTypeCodes.Add(Sax.DataItemType.UserRole, "UserRole", "User Role");
dataItemTypeCodes.Add(Sax.DataItemType.UserOrganisation, "UserOrganisation", "User Organisation");
dataItemTypeCodes.Add(Sax.DataItemType.UserSport, "UserSport", "User Sport");
dataItemTypeCodes.Add(Sax.DataItemType.Organisation, "Organisation", "Organisation");
// Activty data.
dataItemTypeCodes.Add(Sax.DataItemType.ActivityIndex, "ActivityIndex", "Activity Index");
dataItemTypeCodes.Add(Sax.DataItemType.UserActivity, "UserActivity", "User Activity");
dataItemTypeCodes.Add(Sax.DataItemType.Article, "Article", "Article");
dataItemTypeCodes.Add(Sax.DataItemType.OrganisationOpportunity, "OrganisationOpportunity", "Organisation Opportunity");
dataItemTypeCodes.Add(Sax.DataItemType.OrganisationEvent, "OrganisationEvent", "Organisation Event");
// Item link components.
dataItemTypeCodes.Add(Sax.DataItemType.ItemSport, "ItemSport", "Item Sport");
dataItemTypeCodes.Add(Sax.DataItemType.ItemImage, "ItemImage", "Item Image");
//---------------------------------------------------------------
// Gender.
genderCodes.Add(Sax.Gender.Female, "Female", "Female");
genderCodes.Add(Sax.Gender.Male, "Male", "Male");
genderCodes.Add(Sax.Gender.TransFemale, "TransFemale", "TransFemale");
genderCodes.Add(Sax.Gender.TransMale, "TransMale", "TransMale");
genderCodes.Add(Sax.Gender.Nonconforming, "Nonconforming", "Nonconforming");
genderCodes.Add(Sax.Gender.PreferNotToSay, "PreferNotToSay", "Prefer not to say");
//---------------------------------------------------------------
// Sport speciality label.
sportSpecialityLabelCodes.Add(Sax.SportSpecialityLabel.Positon, "POS", "Positon");
sportSpecialityLabelCodes.Add(Sax.SportSpecialityLabel.Discipline, "DIS", "Discipline");
sportSpecialityLabelCodes.Add(Sax.SportSpecialityLabel.NotRelevant, "NRE", "Not relevant");
//---------------------------------------------------------------
// Sport participation.
sportParticipationCodes.Add(Sax.SportParticipation.Professional, "PRO", "Professional");
sportParticipationCodes.Add(Sax.SportParticipation.Regular, "REG", "Regular");
sportParticipationCodes.Add(Sax.SportParticipation.Occasional, "OCC", "Occasional");
sportParticipationCodes.Add(Sax.SportParticipation.Spectator, "SPC", "Spectator");
sportParticipationCodes.Add(Sax.SportParticipation.Interested, "INT", "Interested");
//---------------------------------------------------------------
// Sport officiating.
sportOfficiatingCodes.Add(Sax.SportParticipation.Professional, "PRO", "Professional");
sportOfficiatingCodes.Add(Sax.SportParticipation.Regular, "REG", "Regular");
sportOfficiatingCodes.Add(Sax.SportParticipation.Occasional, "OCC", "Occasional");
//---------------------------------------------------------------
// Region types.
regionTypeCodes.Add(Sax.RegionType.Universe, "UNIV", "Universe");
regionTypeCodes.Add(Sax.RegionType.Galaxy, "GALAX", "Galaxy");
regionTypeCodes.Add(Sax.RegionType.World, "WORLD", "World");
regionTypeCodes.Add(Sax.RegionType.Continent, "CONT", "Continent");
regionTypeCodes.Add(Sax.RegionType.SubContinent, "SUBC", "Sub-Continent");
regionTypeCodes.Add(Sax.RegionType.Country, "COUN", "Country");
regionTypeCodes.Add(Sax.RegionType.State, "STAT", "State");
regionTypeCodes.Add(Sax.RegionType.Province, "PROV", "Province");
//---------------------------------------------------------------
// User roles.
userRoleCodes.Add(Sax.UserRole.Journalist, "JRNLST", "Journalist");
userRoleCodes.Add(Sax.UserRole.SystemAdmin, "SYSADM", "System Admin");
//---------------------------------------------------------------
// Titles.
titleCodes.Add(Sax.Title.Mr, "Mr", "Mr");
titleCodes.Add(Sax.Title.Mrs, "Mrs", "Mrs");
titleCodes.Add(Sax.Title.Miss, "Miss", "Miss");
titleCodes.Add(Sax.Title.Mx, "Mx", "Mx");
titleCodes.Add(Sax.Title.Dr, "Dr", "Dr");
titleCodes.Add(Sax.Title.Sir, "Sir", "Sir");
titleCodes.Add(Sax.Title.Lord, "Lord", "Lord");
titleCodes.Add(Sax.Title.Lady, "Lady", "Lady");
//---------------------------------------------------------------
// Image types.
imageTypeCodes.Add(Sax.ImageType.Avatar, "Avatar", "Avatar");
imageTypeCodes.Add(Sax.ImageType.AvatarUpload, "AvatarUpload", "Avatar - upload");
imageTypeCodes.Add(Sax.ImageType.Article, "Article", "Article");
imageTypeCodes.Add(Sax.ImageType.ArticleUpload, "ArticleUpload", "Article - upload");
//---------------------------------------------------------------
// Organisation types.
organisationTypeCodes.Add(Sax.OrganisationType.SocialEnterprise, "SEN", "Social Enterprise");
organisationTypeCodes.Add(Sax.OrganisationType.CommunityGroup, "CGR", "Community Group");
organisationTypeCodes.Add(Sax.OrganisationType.Charity, "CTY", "Charity");
organisationTypeCodes.Add(Sax.OrganisationType.Commercial, "CMC", "Commercial");
organisationTypeCodes.Add(Sax.OrganisationType.PublicSector, "PBS", "Public Sector");
//---------------------------------------------------------------
// Organisation categories.
organisationCategoryCodes.Add(Sax.OrganisationCategory.Association, "ASC", "Association");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Club, "CLB", "Club");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Society, "SOC", "Society");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Education, "EDU", "Education");
organisationCategoryCodes.Add(Sax.OrganisationCategory.SportDepartment, "SPD", "Sport Department");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Syndicate, "SYN", "Syndicate");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Partner, "PRT", "Partner");
organisationCategoryCodes.Add(Sax.OrganisationCategory.Other, "OTH", "Other");
//---------------------------------------------------------------
// Organisation roles.
organisationRoleCodes.Add(Sax.OrganisationRole.Member, "MBR", "Member");
organisationRoleCodes.Add(Sax.OrganisationRole.Admin, "ADM", "Admin");
organisationRoleCodes.Add(Sax.OrganisationRole.MemberAdmin, "MBA", "Members");
organisationRoleCodes.Add(Sax.OrganisationRole.ScheduleAdmin, "SCA", "Schedule");
organisationRoleCodes.Add(Sax.OrganisationRole.OpportunityAdmin, "OPA", "Opportunities");
organisationRoleCodes.Add(Sax.OrganisationRole.ArticleAdmin, "ARA", "Articles");
//---------------------------------------------------------------
// Event types.
eventTypeCodes.Add(Sax.EventType.Playing, "PLG", "Playing");
eventTypeCodes.Add(Sax.EventType.Training, "TRN", "Training");
eventTypeCodes.Add(Sax.EventType.Organisation, "ORG", "Organisation");
eventTypeCodes.Add(Sax.EventType.Social, "SCL", "Social");
//---------------------------------------------------------------
// Opportunity types.
opportunityTypeCodes.Add(Sax.OpportunityType.Playing, "PLG", "Playing");
opportunityTypeCodes.Add(Sax.OpportunityType.Official, "OFL", "Official");
opportunityTypeCodes.Add(Sax.OpportunityType.Coaching, "CHG", "Coaching");
opportunityTypeCodes.Add(Sax.OpportunityType.Volunteer, "VTR", "Volunteer");
opportunityTypeCodes.Add(Sax.OpportunityType.Staff, "STF", "Staff");
opportunityTypeCodes.Add(Sax.OpportunityType.Board, "BRD", "Board");
//---------------------------------------------------------------
// Address Types.
addressTypeCodes.Add(Sax.AddressType.Location, "Location", "Location");
addressTypeCodes.Add(Sax.AddressType.Home, "Home", "Home");
addressTypeCodes.Add(Sax.AddressType.Office, "Office", "Office");
addressTypeCodes.Add(Sax.AddressType.Delivery, "Delivery", "Delivery");
//---------------------------------------------------------------
// Activity Reactions.
activityReactionCodes.Add(Sax.ActivityReaction.Good, "Good", "Good");
activityReactionCodes.Add(Sax.ActivityReaction.VeryGood, "VeryGood", "Very Good");
activityReactionCodes.Add(Sax.ActivityReaction.Exceptional, "Exceptional", "Exceptional");
// Code types.
InitCodeTypes();
//---------------------------------------------------------------
}
@@ -28,54 +28,6 @@ namespace Saxonite.Net.Standard.Base.App
public abstract SaxItemDataMgr CreateItemDataMgr(SaxSessionContext sessionContext, SaxInternals internals);
public abstract SaxActivityMgr CreateActivityMgr(SaxSessionContext sessionContext, SaxInternals internals);
//-------------------------------------------------------------------
// S y s t e m C o d e s
//-------------------------------------------------------------------
public static List<TypeCodeDesc> GetCodesOfType(Sax.CodeType systemCode)
{
// Lists are cloned to avoid modifications to the internal static lists.
switch (systemCode)
{
case Sax.CodeType.YesNo:
return new List<TypeCodeDesc>(yesNoCodes);
case Sax.CodeType.DataItemType:
return new List<TypeCodeDesc>(dataItemTypeCodes);
case Sax.CodeType.Gender:
return new List<TypeCodeDesc>(genderCodes);
case Sax.CodeType.SportSpecialityLabel:
return new List<TypeCodeDesc>(sportSpecialityLabelCodes);
case Sax.CodeType.SportParticipation:
return new List<TypeCodeDesc>(sportParticipationCodes);
case Sax.CodeType.SportOfficiating:
return new List<TypeCodeDesc>(sportOfficiatingCodes);
case Sax.CodeType.RegionType:
return new List<TypeCodeDesc>(regionTypeCodes);
case Sax.CodeType.UserRole:
return new List<TypeCodeDesc>(userRoleCodes);
case Sax.CodeType.Title:
return new List<TypeCodeDesc>(titleCodes);
case Sax.CodeType.ImageType:
return new List<TypeCodeDesc>(imageTypeCodes);
case Sax.CodeType.OrganisationType:
return new List<TypeCodeDesc>(organisationTypeCodes);
case Sax.CodeType.OrganisationCategory:
return new List<TypeCodeDesc>(organisationCategoryCodes);
case Sax.CodeType.OrganisationRole:
return new List<TypeCodeDesc>(organisationRoleCodes);
case Sax.CodeType.AddressType:
return new List<TypeCodeDesc>(addressTypeCodes);
case Sax.CodeType.EventType:
return new List<TypeCodeDesc>(eventTypeCodes);
case Sax.CodeType.OpportunityType:
return new List<TypeCodeDesc>(opportunityTypeCodes);
case Sax.CodeType.ActivityReaction:
return new List<TypeCodeDesc>(activityReactionCodes);
default:
throw new NotSupportedException(nameof(SaxSystem) + ".GetCodesOfType Unexpected code type: " + systemCode.ToString());
}
}
//-------------------------------------------------------------------
}
//=======================================================================
@@ -0,0 +1,151 @@
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Standard.Base.App;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Saxonite.Net.Standard.Base.Bus
{
//=======================================================================
// Contact data - associated with Organisations, Users etc.
//=======================================================================
public class SaxContactData
{
//-------------------------------------------------------------------
// Definitions.
private static readonly String ElementName_ContactMethods = "contactMethods";
private static readonly String ElementName_ContactMethod = "contactMethod";
private static readonly String AttributeName_Method = "method";
//-------------------------------------------------------------------
// Data members.
private class ContactMethodData
{
public Sax.ContactMethod Method { get; set; }
public String Value { get; set; }
}
private Dictionary<Sax.ContactMethod, ContactMethodData> contactMethods { get; } = new Dictionary<Sax.ContactMethod, ContactMethodData>();
//-------------------------------------------------------------------
// Construction - from serialised data.
public SaxContactData(String contactData = "")
{
ExtractContactData(contactData);
}
//-------------------------------------------------------------------
// Properties.
public List<Sax.ContactMethod> Methods { get { return contactMethods.Keys.ToList(); } }
//-------------------------------------------------------------------
// Contact Methods.
//-------------------------------------------------------------------
/// <summary>Extract the value associated with the specified method.</summary>
public String GetContactMethodValue(Sax.ContactMethod method)
{
return contactMethods.GetValueOrDefault(method, new ContactMethodData()).Value;
}
/// <summary>Set the value associated with the specified method.</summary>
public bool SetContactMethodValue(Sax.ContactMethod method, String value)
{
if ((int)method < 1 || value.IsEmpty()) return false;
ContactMethodData contactMethod = contactMethods.GetValueOrDefault(method, null);
if (contactMethod == null)
contactMethods.Add(method, contactMethod = new ContactMethodData() { Method = method });
contactMethod.Value = value;
return true;
}
/// <summary>Clear the value associated with the specified method.</summary>
public bool ClearContactMethod(Sax.ContactMethod method)
{
return contactMethods.Remove(method);
}
/// <summary>Clear all contact methods.</summary>
public void ClearContactMethods(Sax.ContactMethod method)
{
contactMethods.Clear();
}
//-------------------------------------------------------------------
// Serialisation.
//-------------------------------------------------------------------
/// <summary>
/// Extract contact methods from serialised data.
/// </summary>
private void ExtractContactData(String contactData)
{
String fn = typeof(SaxContactData).FullName + ".ExtractContent";
contactMethods.Clear();
if (StringUtil.IsEmpty(contactData)) return;
try
{
// Load XML data.
XDocument doc = XDocument.Parse(contactData);
XElement rootElement = doc.Root;
foreach (XElement rootChildElement in rootElement.GetChildElements())
{
String rootChildElementName = rootChildElement.GetLocalName();
if (rootChildElementName.EqualsCI(ElementName_ContactMethod))
{
// Contact Method.
String methodValue = rootChildElement.GetAttributeValue(AttributeName_Method);
Sax.ContactMethod method = EnumUtil.ParseEnum(methodValue, Sax.ContactMethod.Unknown);
if (method != Sax.ContactMethod.Unknown)
{
ContactMethodData contactMethod = new ContactMethodData()
{
Method = method,
Value = rootChildElement.Value
};
contactMethods.Add(method, contactMethod);
}
else SaLogger.Warn(fn + " Unrecognised contact method: " + methodValue);
}
else SaLogger.Warn(fn + " Unexpected 'Root' child element: " + rootChildElementName);
}
}
catch (Exception exc)
{
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
}
}
//-------------------------------------------------------------------
/// <summary>
/// Convert to serialised data.
/// </summary>
public String GetContactData()
{
String fn = typeof(SaxContactData).FullName + ".GetContactData";
try
{
XDocument doc = new XDocument();
XElement contactMethodsElement = doc.AppendElement(ElementName_ContactMethods);
foreach (ContactMethodData contactMethod in contactMethods.Values)
{
if ((int)contactMethod.Method < 1 || contactMethod.Value.IsEmpty()) continue;
XElement contactMethodElement = contactMethodsElement.AppendElement(ElementName_ContactMethod, contactMethod.Value);
contactMethodElement.SetAttribute(AttributeName_Method, contactMethod.Method.ToString());
}
return doc.GetXml();
}
catch (Exception exc)
{
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
}
return "";
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -1,5 +1,6 @@
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using Saxonite.Net.Standard.Base.App;
using System;
using System.Collections.Generic;
@@ -212,6 +213,21 @@ namespace Saxonite.Net.Standard.Base.Bus
if (organisationCategory == Sax.OrganisationCategory.SportDepartment) return true;
return false;
}
private static List<Sax.ContactMethod> validContactMethods = new List<Sax.ContactMethod>
{
Sax.ContactMethod.PhoneMain,
Sax.ContactMethod.PhoneOffice,
// Online.
Sax.ContactMethod.Email,
Sax.ContactMethod.Website,
Sax.ContactMethod.Wikipedia,
// Social media.
Sax.ContactMethod.LinkedIn,
Sax.ContactMethod.Twitter,
Sax.ContactMethod.Facebook,
Sax.ContactMethod.Instagram,
};
public static List<Sax.ContactMethod> ValidContactMethods { get { return new List<Sax.ContactMethod>(validContactMethods); } }
//-------------------------------------------------------------------
// Properties.
@@ -0,0 +1,94 @@
using Sarand.Net.Standard.Base.Helpers;
using Saxonite.Net.Standard.Base.App;
using System;
using System.Collections.Generic;
using System.Text;
namespace Saxonite.Net.Standard.Base.Helpers
{
//=======================================================================
public static class SaxContactMethodHelper
{
//-------------------------------------------------------------------
// Utilities.
//-------------------------------------------------------------------
public static Sax.ContactMethodType GetContactMethodType(Sax.ContactMethod contactMethod)
{
switch (contactMethod)
{
case Sax.ContactMethod.PhoneMain:
case Sax.ContactMethod.PhoneMobile:
case Sax.ContactMethod.PhoneHome:
case Sax.ContactMethod.PhoneOffice:
return Sax.ContactMethodType.Phone;
case Sax.ContactMethod.Email:
return Sax.ContactMethodType.Email;
case Sax.ContactMethod.Website:
case Sax.ContactMethod.Wikipedia:
case Sax.ContactMethod.LinkedIn:
case Sax.ContactMethod.Twitter:
case Sax.ContactMethod.Facebook:
case Sax.ContactMethod.Instagram:
return Sax.ContactMethodType.WebUrl;
}
return Sax.ContactMethodType.Unknown;
}
//-------------------------------------------------------------------
/// <summary>Validate Contact Method value.</summary>
public static bool IsValidContactMethodValue(Sax.ContactMethod method, String value)
{
Sax.ContactMethodType contactMethodType = GetContactMethodType(method);
// Method specific value validation.
if (contactMethodType == Sax.ContactMethodType.Phone)
{
// Phone number.
return SacsDataValidationHelper.IsValidPhone(value);
}
else if (contactMethodType == Sax.ContactMethodType.Email)
{
// Email address.
return SacsDataValidationHelper.IsValidEmailAddress(value);
}
else if (contactMethodType == Sax.ContactMethodType.WebUrl)
{
if (method == Sax.ContactMethod.Wikipedia)
{
// Wikipedia.
return SacsDataValidationHelper.IsValidWikipediaUrl(value);
}
else if (method == Sax.ContactMethod.LinkedIn)
{
// LinkedIn.
return SacsDataValidationHelper.IsValidLinkedInUrl(value);
}
else if (method == Sax.ContactMethod.Twitter)
{
// Twitter.
return SacsDataValidationHelper.IsValidTwitterUrl(value);
}
else if (method == Sax.ContactMethod.Facebook)
{
// Facebook.
return SacsDataValidationHelper.IsValidFacebookUrl(value);
}
else if (method == Sax.ContactMethod.Instagram)
{
// Instagram.
return SacsDataValidationHelper.IsValidInstagramUrl(value);
}
else
{
// Generic URL.
return SacsDataValidationHelper.IsValidUrl(value);
}
}
return true;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -76,6 +76,7 @@ namespace Saxonite.Net.Standard.Base.Mgr
public List<TypeCodeDesc> OrganisationCategoryCodes { get { return Internals.OrganisationCategoryCodes; } }
public List<TypeCodeDesc> OrganisationRoleCodes { get { return Internals.OrganisationRoleCodes; } }
public List<TypeCodeDesc> AddressTypeCodes { get { return Internals.AddressTypeCodes; } }
public List<TypeCodeDesc> ContactMethodCodes { get { return Internals.ContactMethodCodes; } }
public List<TypeCodeDesc> EventTypeCodes { get { return Internals.EventTypeCodes; } }
public List<TypeCodeDesc> OpportunityTypeCodes { get { return Internals.OpportunityTypeCodes; } }
public List<TypeCodeDesc> ActivityReactionCodes { get { return Internals.ActivityReactionCodes; } }