Expanding ListViewByQuery Web Part stuck on “Working on it…”
-
10-12-2019 - |
Question
I am using a ListViewByQuery
in a custom web-part. If I set the CAML GroupBy
to <GroupBy Collapse='FALSE'>
(i.e. expanded), the webpart works fine. However, if I set it to <GroupBy Collapse='TRUE'>
, the item will expand, but then is stuck/hangs on the "Working on it..." message:
(I believe the old message in SharePoint 2010 was "Loading...").
Here's the working copy when it's pre-expanded:
This doesn't appear to be a JavaScript issue (tested on multiple browsers).
How do I fix this?
Aside: Karine mentions a very similar issue on her blog using the ListViewByQuery
Web Part here. I will test the suggested JavaScript fix and report back, but I believe this is only a workaround - what is the underlying cause and solution?
Update: I can't get the JS fix working. I'm dynamically generating the ListViewByQuery
control in my custom webpart (as seemingly required) and while the JS seems to fire, I can't determine how to debug it.
Update 2: Finally got the JS fix working - the collapse was being called twice (so it would jsut expand again). Will suggest this as possible answer soon, but won't accept it as actual answer.
Solution
This is simply how I got the JavaScript fix/kludge working. Firstly, you must pre-expand the ListViewByQuery
CAML group (Collapse='FALSE'
). Secondly, the suggested JavaScript runs twice and simply collapses/expands the result, so it doesn't seem to work in 2013. So here's how I got working:
I create the ListViewByQuery
control dynamically (as required/recommend in doco):
Panel pnlDiv = new Panel();
pnlDiv.ID = "pnlDiv";
pnlDiv.CssClass = "ms-authoringcontrols";
ListViewByQuery lvPdfs = new ListViewByQuery();
..
EnsureChildControls();
pnlDiv.Controls.Add(lvPdfs);
pnlDiv.RenderControl(writer);
RenderChildren(writer);
As I had trouble with JavaScript I emitted it server-side:
private void RegisterExpandJavascriptFix()
{
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsClientScriptBlockRegistered(this.GetType(), "CollapseFunc"))
{
cs.RegisterClientScriptBlock(this.GetType(), "CollapseFunc", JSExpandFix, true);
}
if (!cs.IsStartupScriptRegistered(this.GetType(), "Collapse"))
{
cs.RegisterStartupScript(this.GetType(), "CollapseFunc", "collapseDiv();", true);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RegisterExpandJavascriptFix();
}
}
And here's the JavaScript:
private const string JSExpandFix = @"function collapseDiv() {
var div = document.getElementById('pnlDiv');
//alert(div);
if (div != null) {
var links = div.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
if (links[i].href == 'javascript:' && links[i].onclick.toString().indexOf('ExpCollGroup') > -1 && links[i].previousSibling.tagName == 'IMG') {
//alert(links[i].onclick.toString());
links[i].click();
}
}
}
}";
Note the links[i].previousSibling.tagName == 'IMG')
check - this is just my way to ensure it only clicks the first collapse link (i.e. the plus/minus image, rather than the text).