November Happy Hour will be moved to Thursday December 5th.

Programmatically move ContentAreaItem from one Content Area to other Content Area

Vote:
 

I am trying to programmatically move content area item from one content area to the other content area but with no luck. 

I made web api controller that sends the page Id from the DOJO widget.

From that page ID I loaded the page detatils via IContentRepository and made a writable clone. Then I load block by content reference and insert that block as new content area item and that part is ok. Than I try to remove the content area item from the other content area and ii debug that is done but on the site it is still there. I am certan that this has something to do with the page versions (drafts).

Part of the code (one version of the code):

var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();

var pageRef = new PageReference(data.Id);
var page = contentRepository.Get<LayoutPage>(pageRef);
var pageClone = (LayoutPage)page.CreateWritableClone();

if (pageClone.SecondColumnContentArea != null)
{
     foreach (var areaItem in page.SecondColumnContentArea.Items)
    {
         var block = contentRepository.Get<IContent>(areaItem.ContentLink);
         pageClone.FirstColumnContentArea.Items.Add(new ContentAreaItem
        {
             ContentLink = block.ContentLink
         });
     }

     pageClone.SecondColumnContentArea.Items.Clear();

}

contentRepository.Save((IContent)pageClone, SaveAction.Default | SaveAction.ForceCurrentVersion, AccessLevel.Edit);

I tried all combinations with SaveAction flags and always is the same result.

Any ideas? Did somebody tried something similar?

#204915
Jun 20, 2019 17:46
Vote:
 

Hi,

The reason is, calling Clear() doesn't automatically set the IsModified boolean for the property to true, so ultimately the change isn't persisted in the database.

You can either remove the items individually:

while (layoutPage.SecondColumnContentArea.Items.Any())
{
    layoutPage.SecondColumnContentArea.Items.RemoveAt(0);
}

or, set IsModified yourself:

layoutPage.SecondColumnContentArea.Items.Clear();
layoutPage.SecondColumnContentArea.IsModified = true;

Unless there is a reason for it you stipped out of your snippet there is also no need to get each block from the content repository. The following should work:

var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();

var pageLink = new PageReference(id);

if (ContentReference.IsNullOrEmpty(pageLink))
{
    return;
}

LayoutPage layoutPage;

if (!contentRepository.TryGet(pageLink, out layoutPage))
{
    return;
}

var items = layoutPage?.SecondColumnContentArea?.Items;

if (items == null || !items.Any())
{
    return;
}

layoutPage = (LayoutPage)layoutPage.CreateWritableClone();

if (layoutPage.FirstColumnContentArea == null)
{
    layoutPage.FirstColumnContentArea = new ContentArea();
}

foreach (var item in items)
{
    layoutPage.FirstColumnContentArea.Items.Add(item);
}

while (layoutPage.SecondColumnContentArea.Items.Any())
{
    layoutPage.SecondColumnContentArea.Items.RemoveAt(0);
}

contentRepository.Save(layoutPage, SaveAction.Publish, AccessLevel.NoAccess);
#204925
Edited, Jun 20, 2019 23:55
Mark Rullo - Apr 21, 2021 15:49
Thank you so much for the IsModified comment. That was a lifesaver!
Vote:
 

Hi Jake, 

Thank you for your time and your response. In the meantime I figureout why the Clear() is not woriking and to set IsModifid property so that the changes are registered.

And your code is helpfull :) . 

So now the moving items is working but I have another big problem: page versions.

I am trying to achive the same effect when the editor click on the second content area item and drag&drop that item to the first content area and the change is instantly visible and the page draft is saved (autosave).

I manage to move content items but those chages are saved in the previous page draft or on the new page draft and the previous draft is set to Primary Draft.

I tried this in two ways:
1. change event is fired from the DOJO widget and the web api method is called (code snipped in my first post). I tried every combination with SaveAction flags and with versionRepository.SetCommonDraft(saveReference) to force the new page draft to bi set as a Primary Draft.

2. hooked on the content events : tried with SavingContent, CheckingOut, SavedContent and CheckedContent (I know how this events works and what is their function/role) but the result is the same.

In the first approach the changes are instantly visible but I have manually to change to the page draft that have changes and republish them.

In the second apporach the changes are not instantly visibile and I have to refresh the page, of with F5 or just publish the page and then the changes are visible.

Any ideas? Did somebody tried something similar?

#204929
Jun 21, 2019 11:33
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.