Recently I was building a custom SXA component and I have made that by cloning the Default Event List Component given by SXA .
I have to get the data in json
format from a controller and bind it with html structure. Can I do it using rendering variants? If yes, how?
And if not, how can I use SXA to create the component?
Controller
namespace Feature.Events.Controllers
{
public class EventsController : StandardController
{
private readonly IEventsRepository _eventsRepository;
public EventsController(IEventsRepository eventsRepository)
{
_eventsRepository = eventsRepository;
}
protected override object GetModel()
{
return _eventsRepository.GetModel();
}
public override ActionResult Index()
{
return View("~/Views/Events/Event List.cshtml", GetModel());
}
public JsonResult GetEvents(string datasourceId)
{
var listItems = new List<Item>();
if (!string.IsNullOrEmpty(datasourceId))
{
var datasourceItem = Sitecore.Context.Database.GetItem(new ID(datasourceId));
if (datasourceItem != null)
{
if (datasourceItem.Children.Count > 0)
{
var eventItems = datasourceItem.GetChildren();
var response = eventItems.Where(x => x != null).Select(x => new EventsModel
{
EventName = x.Fields["CustomEventName"].Value,
Presenter = x.Fields["PresentedBy"].Value,
EventStartDate = Sitecore.DateUtil.IsoDateToDateTime(((DateField)x.Fields["CustomEventStart"]).Value),
EventEndDate = Sitecore.DateUtil.IsoDateToDateTime(((DateField)x.Fields["CustomEventEnd"]).Value),
Location = x.Fields["City"].Value,
LearnMoreLink = HSHelper.LinkUrl(x.Fields["LearnMoreLink"])
}).ToList();
return Json(response, JsonRequestBehavior.AllowGet);
}
}
}
return Json("", JsonRequestBehavior.AllowGet);
}
}
}
Repository
namespace Feature.Events.Repositories.Concrete
{
public class EventsRepository : VariantsRepository, IEventsRepository
{
public override IRenderingModelBase GetModel()
{
EventsListModel eventsListModel = new EventsListModel();
FillBaseProperties(eventsListModel);
eventsListModel.EventItems = FillEventsProperties(eventsListModel);
return eventsListModel;
}
public IEnumerable<EventsModel> FillEventsProperties(EventsListModel eventsListModel)
{
var listItems = new List<EventsModel>();
var datasourceId = RenderingContext.Current.Rendering.DataSource;
if(!string.IsNullOrEmpty(datasourceId))
{
var datasourceItem = Sitecore.Context.Database.GetItem(new ID(datasourceId));
if(datasourceItem != null)
{
if(datasourceItem.Children.Count > 0)
{
var eventItems = datasourceItem.GetChildren();
listItems = eventItems.Select(x => new EventsModel(x, eventsListModel.RenderingWebEditingParams)).ToList();
}
}
}
return listItems;
}
}
}
Models
namespace Feature.Events.Models
{
public class EventsModel : VariantsRenderingModel
{
public Item InnterItem
{
get;
set;
}
public bool IsFromComposite
{
get;
set;
}
public EventsModel()
{ }
public EventsModel(Item item, RenderingWebEditingParams renderingParams)
{
this.InnterItem = item;
base.RenderingWebEditingParams = renderingParams;
base.IsControlEditable = !renderingParams.DisableWebEditing;
this.IsFromComposite = renderingParams.SkipCommonButtons;
}
public string EventName { get; set; }
public string EventDescription { get; set; }
public string EventType { get; set; }
public string EventDetailsLink { get; set; }
public string Presenter { get; set; }
public DateTime EventStartDate { get; set; }
public DateTime EventEndDate { get; set; }
public string Location { get; set; }
public string CECredits { get; set; }
public string LearnMoreLink { get; set; }
}
public class EventsListModel : VariantListsRenderingModel
{
public JObject EventItemsList { get; set; }
public IEnumerable<EventsModel> EventItems
{
get;
set;
}
public EventsListModel()
{
}
}
}
View
@using Feature.Events.Models
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.RenderingVariants.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@model Feature.Events.Models.EventsListModel
@{
bool isVisible = (ViewData["eventListVisible"] == null || (bool)ViewData["eventListVisible"]);
int index = 0;
}
@if (isVisible)
{
if (!(Model.Rendering.DataSourceItem == null && !Html.Sxa().IsEdit))
{
<div @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "event-list", Model.Attributes)>
<div class="component-content">
@Html.Sxa().RenderHeading(Model.HeadingTag, Model.DataSourceItem, "Title", Model.GetRenderingWebEditingParams())
@if (Html.Sxa().IsEdit && Model.Rendering.DataSourceItem == null)
{
@Model.MessageIsEmpty
}
@if (Model.Rendering.DataSourceItem != null && !Model.EventItems.Any())
{
using (Html.Sxa().BeginEditFrame(Html.Sitecore().CurrentRendering.DataSource, "Event Empty", Model.IsControlEditable))
{
<span class="is-empty-hint">@Sitecore.Globalization.Translate.Text("Create A New Event List")</span>
}
}
@if (Model.Rendering.DataSourceItem != null)
{
<ul>
@foreach (EventsModel item in Model.EventItems)
{
{
Html.RenderPartial("EventListEvent", item, new ViewDataDictionary
{
{ "cssClass", ListsHelper.BuildCssClass(index, Model.EventItems.Count()) },
{ "variantFields", Model.VariantFields }
});
}
index++;
}
</ul>
}
</div>
</div>
}
}
<script type="text/javascript">
$(document).ready(function () {
let datasourceItemId = $(".datasourceitem").val();
$.ajax({
type: 'POST',
url: 'api/Sitecore/Events/GetEvents',
dataType: "json",
data: {
datasourceId: datasourceItemId
},
success: function (data) {
var len = data.length;
var txt = "";
if (len > 0) {
for (var i = 0; i < len; i++) {
txt = "<tr><td>" + data[i].EventName +
"</td><td>" + data[i].Presenter +
"</td><td>" + new Date(parseInt(data[i].EventStartDate.substr(6))) +
"</td><td>" + new Date(parseInt(data[i].EventEndDate.substr(6))) +
"</td><td>" + data[i].Location +
"</td><td>" + data[i].LearnMoreLink +
"</td></tr>";
$(".event-content-wrapper").append(txt);
}
}
console.log("Success");
}
});
$('.hidemonth').hide();
$("#1-month").show();
});
$('div div a').click(function () {
$('.hidemonth').hide();
$("#" + $(this).attr('data-title')).show();
});
</script>
I want to use the json data returned from the controller to bind with the html structure created by using the my custom rendering variants structure .