set selected items of GenericPageSelector in SiteFinity 5
Hi,
I need help please. I need to know how to set the selected items of a GenericPageSelector from client side, like inside
refreshUI: function ()
...
Thank you
I forgot to mention that I would like to set the selected items by using a set of guid.
I'm working with Ernest on this issue. We are having an issue binding a list of GUID's to the GenericPageSelector. We currently have the GenericPageSelector in our widget, and our goal is to select multiple pages, and return their ID's to our widget. We need to, once "Edit" is clicked, rebind this list of page IDs to the GenericPageSelector, and we are having trouble accomplishing this. There are methods on the PageSelector (retrieves this._PageSelector), within the refreshUI function. We get the reference to our page selector, and can use the set_selectedItemID function, to pass one GUID, but, passing an array of GUID's to the set_selectedItemIDs function doesn't seem to have any effect. Can anyone offer advice as to how to bind this data to the GenericPageSelector control?
Thanks
Hello,
Have you tried using the set_selectedItems function instead of the set_selectedItemsIds function? Also, can you give me the code of how exactly are you doing the preselection inside refreshUI? Thanks in advance.
Greetings,Hi Svetoslav,
I've just tried the set_selectedItems function to no avail. Our code within refreshUI currently looks like this:
var
controlData =
this
._propertyEditor.get_control();
this
.resizeEvents();
var
p =
this
.get_PageSelector();
var
pages = controlData.PageValue;
if
(pages !=
null
)
var
list = controlData.PageValue.split(
','
);
alert(list);
p.set_selectedItems(list);
var
controlData =
this
._propertyEditor.get_control();
var
pageSelector =
this
.get_PageSelector();
if
(pageSelector !=
null
)
var
tree = pageSelector.get_itemsTree();
if
(tree !=
null
)
var
items = tree.get_selectedItems();
if
(items !=
null
)
if
(items.length > 0)
var
idList =
""
;
var
i = 0;
for
(i = 0; i < items.length; i++)
idList += items[i].Id +
","
;
if
(idList !=
""
)
idList = idList.substring(0, idList.lastIndexOf(
','
));
controlData.PageValue = idList;
Any ideas? The built in page selector is great and it looks as though the functionality to bind many items is there, we just need to know how to leverage it properly.
Hi Ernest,
I just checked and set_selectedItemIDs is used only internally by the set_selectedItems function. As for the latter, here's how we use it in our navigation:
var
data =
this
.get_controlData();
//Deserialize the SelectedPages property
var
selectedPages = Sys.Serialization.JavaScriptSerializer.deserialize(data.CustomSelectedPages);
if
(!selectedPages) selectedPages = [];
this
.get_pagesSelector().get_extPagesSelector().set_selectedItems(selectedPages);
public
string
CustomSelectedPages
get
return
this
.SelectedPagesConverter.ConvertToString(
this
.CustomSelectedPagesInternal);
set
var deserialized =
this
.SelectedPagesConverter.ConvertFrom(value);
this
.selectedPages = deserialized
as
Collection<SelectedPage>;
private
CollectionJsonTypeConverter<SelectedPage> SelectedPagesConverter
get
if
(
this
.selectedPagesConverter ==
null
)
this
.selectedPagesConverter =
new
CollectionJsonTypeConverter<SelectedPage>();
return
this
.selectedPagesConverter;
[TypeConverter(
typeof
(CollectionJsonTypeConverter<SelectedPage>))]
protected
Collection<SelectedPage> CustomSelectedPagesInternal
get
if
(
this
.selectedPages ==
null
)
this
.selectedPages =
new
Collection<SelectedPage>();
return
this
.selectedPages;
set
this
.selectedPages = value;
Hello,
We are having issues with the code above. Firstly, when calling the function get_extPagesSelector(), we get an exception. Secondly, when attempting to bind our value back to our property, the following line throws an exception:
var deserialized =
this
.SelectedPagesConverter.ConvertFrom(value);
The error being thrown is as follows
Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' to type 'Telerik.Sitefinity.Web.UI.NavigationControls.SelectedPage'.
our value that we were passing to the ConvertFrom function is as follows:
"[\"AdditionalUrlsRedirectToDefaultOne\":true,\"AllowMultipleUrls\":false,\"AllowParameterValidation\":true,\"AvailableLanguages\":[],\"FullUrl\":\"/FyiDoctorsCMS/home\",\"HasChildren\":false,\"HasTranslationSiblings\":false,\"Id\":\"fd0057c6-74b1-4861-8552-17053df982fd\",\"IsExternal\":false,\"LinkedNodeFullUrl\":null,\"LinkedNodeId\":\"00000000-0000-0000-0000-000000000000\",\"LinkedNodeProvider\":null,\"LinkedNodeTitle\":null,\"LocalizationStrategy\":0,\"MultipleNavigationNodes\":null,\"NodeType\":0,\"OpenNewWindow\":false,\"ParentId\":\"f669d9a7-009d-4d83-ddaa-000000000002\",\"Path\":\"home\",\"RedirectUrl\":null,\"Title\":\"PersistedValue\":\"Home\",\"Value\":\"Home\",\"ValuesPerCulture\":[\"Key\":\"\",\"Value\":\"Home\"],\"TitlesPath\":\"Home\",\"CurrentTemplateId\":\"00000000-0000-0000-0000-000000000000\",\"DateCreated\":\"\\/Date(1332261640987)\\/\",\"IsContentEditable\":true,\"IsEditable\":true,\"IsGroup\":false,\"IsHomePage\":false,\"IsSubPageCreationAllowed\":true,\"LevelOrdinal\":2,\"Location\":\" <span class='sfSep'>|</span> on <strong>top level</strong>\",\"Owner\":\"Ernest Ariola\",\"PageDataId\":\"a37f56af-1fa1-4cbf-9a48-819fea7d75bb\",\"PageEditUrl\":\"/FyiDoctorsCMS/home/Action/Edit\",\"PageLifecycleStatus\":\"ErrorMessage\":null,\"IsAdmin\":true,\"IsLocked\":false,\"IsLockedByMe\":false,\"IsPublished\":true,\"LastModified\":\"\\/Date(1332261658917)\\/\",\"LastModifiedBy\":null,\"LockedByUsername\":\"\",\"LockedSince\":null,\"Message\":null,\"PublicationDate\":\"\\/Date(1332261640793)\\/\",\"SupportsContentLifecycle\":true,\"WorkflowStatus\":null,\"PageLiveUrl\":\"localhost:57925/.../home\",\"Status\":\"Published\",\"StatusText\":\"Published\",\"Template\":null,\"UrlName\":\"home\",\"VersioningId\":\"a37f56af-1fa1-4cbf-9a48-819fea7d75bb\",\"Visible\":true,\"WorkflowOperations\":null]"
We also modified our code for saving the value to our property, to hold a serialized list of the values like so:
controlData.PageValue = Sys.Serialization.JavaScriptSerializer.serialize(sel);
as opposed to it being an array of Guids. This was not explicitly mentioned by you, but made sense in the context.
Should we be serializing our values as I outlined above? How do we need to prepare our attribute for receiving that value? Do we require the call to get_extPagesSelector() and if so, how do we access that method?
Any ideas? Does our data need serialization, if so, does passing the result of get_selectedItems (from the PagesSelector) to Sys.Serialization.JavaScriptSerializer.serialize serialize it properly? what is "get_extPagesSelector()" and how can i access it?
Thanks
Hi Travis,
What I meant by showing you this code is that the set_SelectedItems function should take a deserialized input in order to work properly. However, this internally calls the set_SelectedItemIds by passing an array of the IDs to it. I notice that i wrote passing an array to the "set_SelectedItems" function - I apologize - what I meant was the set_SelectedItemIds. As for the other functions in the code, I just meant to show you how this works, but I don't think you will be able to directly use this code in your project. As for the input that you need to pass to the set_SelectedItemIds, here's how the array should be created:
this
._selectedItemIds = [];
if
(!items)
return
;
for
(
var
i = 0; i < items.length; i++)
var
item = items[i];
this
._selectedItemIds.push(item.Id);
I've changed my code to return a comma separated list of guids, representing the pageIDs. A
sample value is:
"fd0057c6-74b1-4861-8552-17053df982fd,06f579b5-f5bc-4e4c-9420-3d09313049cc,6535f02f-260d-44da-bc4e-5a933b1066ef"
I then changed my code to bind the values, to reflect what you've specified below:
var
items = controlData.PageValue.split(
','
);
//Comma separated list of page guids
var
p =
this
.get_PageSelector();
p._selectedItemIds = [];
if
(!items)
return
;
for
(
var
i = 0; i < items.length; i++)
var
item = items[i];
p._selectedItemIds.push(item);
var
controlData =
this
._propertyEditor.get_control();
var
pageSelector =
this
.get_PageSelector();
if
(pageSelector !=
null
)
var
sel =
this
.get_PageSelector().get_selectedItems();
var
i = 0;
var
idList =
""
;
for
(i = 0; i < sel.length; i++)
idList += sel[i].Id +
","
;
if
(idList !=
""
)
idList = idList.substring(0, idList.lastIndexOf(
','
));
controlData.PageValue = idList;
try
var
items = Sys.Serialization.JavaScriptSerializer.deserialize(controlData.PageValue)
catch
(exx)
items = [];
var
p =
this
.get_PageSelector();
p._selectedItemIds = [];
if
(!items)
return
;
for
(
var
i = 0; i < items.length; i++)
var
item = items[i];
p._selectedItemIds.push(item.Id);
var
controlData =
this
._propertyEditor.get_control();
var
pageSelector =
this
.get_PageSelector();
if
(pageSelector !=
null
)
var
sel =
this
.get_PageSelector().get_selectedItems();
if
(!sel)
sel = [];
controlData.PageValue = Sys.Serialization.JavaScriptSerializer.serialize(sel);
@Travis
I believe that selectedItem is the result from running the PageSelector web-service.
Wouldn't you need to be able to invoke the webservice and have it process/return values ??
@MB I'm not entirely sure. The method we're currently using to retrieve values does seem to be working without invoking the web service, but, binding our data back does not work. Perhaps invoking the web service will remedy this? Do you have any resources that outline this process?
@Travis
I'm not sure what it is you are trying to do here, but it looks similar to a blind-path I headed down a while ago, until (after a few questions to support) it became apparent that I couldn't set the selecteditem value and expect anything to happen - as it's the returned value of the webservice invoked by the component's UI.
Here's exactly what we're doing:
We have a navigation control. We want to give the option to specify pages to include. We're using the GenericPageSelector to select an array of pages to include in the Navigation. Our control has a custom designer, and we have an instance of the GenericPageSelector on our control designer. We are currently having issues specifically with binding the pages that were selected back to the GenericPageSelector control. We are able to get the ID's of the pages, without invoking any sort of web service call, but, binding may be another story altogether.
Does this situation sound similar to yours MB? If so, how did you get around it?
@Travis
"Does this situation sound similar to yours MB?"
Hmmm... sort of. My control already knew a page Guid and in the designer I tried to set it into the PageSelector, thinking that I could make it 'automagically' retrieve the details of that Guid, so I could suck out and display of its properties. However, it became apparent that the webservice is only invoked by using the Component's UI, and not as a result of setting any client-component properties - a big Doh! moment.
"how did you get around it?"
Basically, I didn't.
@MB Hmm... I see. Something I don't really understand is that I was able to get it to bind to one page, but trying to bind to multiples is where it started to fall apart. Did you experience this issue? Using the set_selectedItemId function, i am able to pass a guid and have it show up in as selected in the PageSelector, however, if I pass multiples to the set_selectedItemIds function, it does not work.
No, that sounds like a different scenario to mine, but I suspect that it's possibly related to the fact that the client component needs to communicate with the server (via the webservice) and that is normally only invoked by the UI.
I'm not sure how useful this will be since you posted this several months ago, but I ran into the same issue today. I'm running Sitefinity 5.1 and I was trying to set the selected items on the PagesSelector control. It just wasn't working. I starting debugging and digging around in Sitefinity's javascript (particularly the set_selectedItemdIds method) and found a small bug preventing this from working.
I wrote a blog post about my fix. See here: www.benramey.com/.../
I'm also struggling with this same issue in Sitefinity version 7.
Svetoslav instructed to pass an array of selected guids to set_selectedItems method but for some reason its just not working. I guess the same problem that Ben Ramey pointed out still exists?
In Widget code behind I have the property for Guid array:
private Guid[] _selectedPageIDs;
public Guid[] SelectedPageIDs
get
if (_selectedPageIDs == null) _selectedPageIDs = new Guid[] ;
return _selectedPageIDs;
set _selectedPageIDs = value;
And in Widget designer js file I set the items for the page selector reference in refreshUI event:
pagesSelectorPageReference.set_selectedItems(controlData.SelectedPageIDs);
but when this call is made to the PageService.svc it doesn't return references to these page objects and when this next call (in the same event) is made the selectedPages does not include ids for selected pages
pagesSelectorPageReference.add_selectionApplied(function (o, args)
var selectedPages = pagesSelectorPageReference.get_selectedItems();
if (selectedPages)
// loop selected pages and look for guids (ids)
$.each(selectedPages, function (index, page)
$.each(page, function (key, value)
if (key == "Id")
alert("key: " + key + ", value: " + value);
);
);
);
When pages are selected in PageSelector this js code is fired
_pageSelectedPageReferenceHandler: function (items)
var controlData = this._propertyEditor.get_control();
var pagesSelector = this.get_pageSelectorPageReference().get_pageSelector();
this._PageReferenceDialog.dialog("close");
jQuery("#designerLayoutRoot").show();
dialogBase.resizeToContent();
if (items == null)
return;
// items contains references to selected pages ids and names
if (items)
var arrayOfPageGuids = [];
var label = this.get_selectedPageReferenceLabel();
label.innerHTML = "";
$.each(items, function (index, page)
jQuery(label).show();
label.innerHTML += page.Title + "<br />";
arrayOfPageGuids.push(page.Id);
);
this.get_pageSelectButtonPageReference().innerHTML = '<span>Change</span>';
// set array of selected pages' guids
controlData.SelectedPageIDs = arrayOfPageGuids;
Any thoughts on how to solve this? Now it works so that if user selects pages they are listed in the edit view but after saving the selections and coming back to modify (edit view) the selected pages list is empty. This is because ControlData.SelectedPageIDs has lost the references to page guids for some reason and everything points now to this problem using set_selectedItems method.
For one reference to page guid it works
pagesSelectorPageReference.set_selectedItems([ Id: controlData.SelectedPageIDs[0] ]);
For array of page guids not
pagesSelectorPageReference.set_selectedItems(controlData.SelectedPageIDs);
Its either this or there's a problem in _pageSelectedPageReferenceHandler when setting the array of guids to this property (controlData.SelectedPageIDs).
Okay, got this figured out.
Basically, when setting an array of guids to pageselector you have to provide the Id (key) like for instance
..
var arrayOfPageGuids = [];
$.each(items, function (index, page)
..
arrayOfPageGuids.push( Id: page.Id);
);
And then set the array of selected pages' guids to controldata just as previously
controlData.SelectedPageIDs = arrayOfPageGuids;
Also worth mentioning is that in refreshUI function you have to set the selected pages for pageselector using an intermediary property (eg controlData.PageValue, check this article www.sitefinity.com/.../selecting_sitefinity_4_content_inside_widget_desi - similar to the CategoryValue property in that example) but later on you can use the "normal way"
pagesSelectorPageReference.set_selectedItems(controlData.SelectedPageIDs);