4

Scenario:

In our project we have a requirement that load items in pageload by ajax call and if there are more items, click on "LoadMore" button then load rest of the items by the same ajax call.

Issue:

The items which are loaded in page load are editable in experience editor.But the items which are loaded by "LoadMore" button are not editable.

Kindly advise on this.

Controller:

public class CategoryController : Controller
{
    CategoryRepository categoryRepository = new CategoryRepository();

    public ActionResult Index()
    {
         var categoryViewModel = new CategoryViewModel();
         categoryViewModel.ContextDatabase = PageContext.Current.Database.Name;
         categoryViewModel.ContextItem = PageContext.Current.Item;
         return View(categoryViewModel);
    }

    public PartialViewResult GetCategories(int size, string itemID, string itemDB)
    {
         var model = categoryRepository.GetCategories(itemID, itemDB).Skip(size).Take(9);
         return PartialView("_Category", model);
    }
}

View:

@model CategoryViewModel
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        var loadCount = 0;
        var itemId = $("#contextItemId").val();
        var itemDb = $("#contextDb").val();
        LoadCategoires(loadCount, itemId, itemDb);
        loadCount += 1;
        $("#loadMore").click(function () {
            LoadCategoires(loadCount, itemId, itemDb);
            loadCount += 1;
        });
    });

    function LoadCategoires(loadCount, itemId, itemDb) {
        $.ajax({
            url: '/api/sitecore/Category/GetCategories',
            type: 'POST',
            dataType: 'html',
            async: true,
            data: { size: loadCount * 9, itemID: itemId, itemDB: itemDb },
            success: function (data) {
                if (data.length !== 0) {
                    $("#loadMore").show();
                    $("#catContainer").append(data);
                }
                else {
                    $("#loadMore").hide();
                }
            },
            error: function (data) {
                alert(data.responseText);
            }
        });
    }
</script>
<div class="row" id="catContainer">
</div>
<input type="hidden" value="@Model.ContextItem.ID.ToString()" id="contextItemId" />
<input type="hidden" value="@Model.ContextDatabase" id="contextDb" />
<div class="col-md-12">
    <button id="loadMore" style="display:none;" class="center-block" value="Load More">Load More</button>
</div>

Partial View:

@model IEnumerable<Category>

@foreach (var item in Model)
{

    <div>
        <h4 class="text-center" style="font-weight: 600; margin-bottom: 1px;">@Html.Sitecore().Field("Title", item.InnerItem)</h4>
    </div>

}
4
  • When you call a load more ajax call it basically appending the html sting a the end of the current result and since its a html string so you can't edit it in the Experience editor. I would say you should ask suggestion from Sitecore support for this type functionality because we generally don't provide Experience editor support for this. Thanks Mahendra Commented May 23, 2017 at 8:13
  • 1
    Because the content is loaded asynchronously, Sitecore isn't aware that the content is actually from Sitecore. I'd suggest an Experience Editor specific view that loads the content the "normal" way.
    – sestocker
    Commented May 23, 2017 at 12:36
  • If you want to edit those items with the experience editor, you can locate them in the Content Editor and then go in the ribbon to Publish > Experience Editor Commented May 24, 2017 at 8:48
  • I'm not sure why you would load the page and then load the first 9 using ajax, seems like an inefficient way of handling it, since you already have a request returning a result, just return the first 9 in that. Then you can use the ajax in subsequent pagination requests. Commented May 24, 2017 at 16:07

2 Answers 2

3

In your GetCategories function, instead of returning items, return an HTML string. Then the editor will render the html with the js/html to make editable fields.

public List<HtmlString> GetCategories()
{
    var rtn = new List<HtmlString>();
    var items = new List<Item>();
    foreach (var item in items)
    {
        rtn.Add(new HtmlString(Sitecore.Web.UI.WebControls.FieldRenderer.Render(item, "title")));
    }

    return rtn;
 }

Then in your markup

@foreach (var itemHtml in Model)
{
    <div>
        <h4 class="text-center" style="font-weight: 600; margin-bottom: 1px;">@Html.Raw(itemHtml)</h4>
    </div>
}
1

Another option you could do, is handle the experience editor interface differently than the rest of the page. You can get knowledge from the page by using the page mode detection methods, which can be done from within Javascript:

var isPageEditor = function(){
    return !!(Sitecore && Sitecore.PageModes && Sitecore.PageModes.PageEditor);
};

if(isPageEditor()) {
    // Logic for when in the experience editor
}

Or you can determine the page mode via c# razor syntax like this:

@if (Sitecore.Context.PageMode.IsExperienceEditor) 
{
    // Load a unique interface that contains all items 
    // (not paginated using ajax so you can use experience editor to make changes)
} else {
    // Load existing logic (for when not in experience editor
}

Now there is a slight issue with loading everything all at once, if you have a lot of data (since that's the reason you are paginating the data in the first place). You could build some sort of custom speak interface to manipulate the large data set of information. Also in this situation is when I would think it would make more sense to edit the data in the content editor, if the user might be editing 1 item on page 100 out of 1000 pages of data. Even if you could get the data to paginate and be editable via the experience editor with the use of ajax, there would be usability concerns with this scenario.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.