DVWP Accordion list view

Forums Requests DVWP Accordion list view

This topic contains 24 replies, has 2 voices, and was last updated by  Alexander Bautz 2 weeks, 3 days ago.

  • Author
    Posts
  • #18951

    Nichols Family
    Participant

    Please help;

    I have a custom list on a subsite, my requirement is to show a accordion list view on another subsite. I want to use the “Title” column for the header and the “Narrative” column for body. I have tried multiple times make this work but has failed every time. Help will be rewarded in lots of beer 😀

  • #18972

    Alexander Bautz
    Keymaster

    Hi,
    Unfortunately I don’t have any code ready, but if you can tell me which SharePoint version you use I might be able to help you with a code snippet to get you started.

    Alexander

  • #18982

    Nichols Family
    Participant

    I am working with sharepoint 2013. Any help is much appreciated.

  • #18993

    Alexander Bautz
    Keymaster

    OK, I’ll try to get something made during the weekend.

    Could you give me some more details about how you want it to work? – is it just a list with all the “Title” elements that you can click to expand the “Narrative” text?

    Alexander

  • #18997

    Nichols Family
    Participant

    Exactly what I want to do. There is a faq accordion floating around but really whatever you come up with I would be much appreciative. Again this has bugged me for two months now. So to round up the list lives on one sub site and I want to view the display on another subsite. When the title is clicked the narrative should display below it. Thank you so much for your help and all of the great solutions to date.

  • #19011

    Alexander Bautz
    Keymaster

    I have attached a code snippet. Change the “WEB_BASE_URL” and “LIST_NAME” and ensure the “Narrative” field name is correct. Put the code in a HTML for web part or script editor web part or link it in from a file using the Content Editor Web Parts “Content link” option.

    The end result should look like the attached image.

    Hope you can use this as a starting point for your solution.

    Alexander

  • #19015

    Nichols Family
    Participant

    This works great thank you so much. How would I go about filtering it so only the last 25 hours (yes last 25 hours) of created items show up?

  • #19027

    Nichols Family
    Participant

    The only thing I need is a 25 hour filtering option and the ability to use list views other then that this solution is spot on.

  • #19029

    Alexander Bautz
    Keymaster

    Sorry for the delay – change the function like this:

    function getFaqItems(){
        var date = new Date(), dateISO = "";
        date.setDate(date.getDate()-25);
        dateISO = String(date.getFullYear()) + "-" + String(date.getMonth()+1) + "-" + String(date.getDate()) + "T00:00:00Z";
        var endpoint = "/WEB_BASE_URL/_api/web/lists/getbytitle('LIST_NAME')/items?$filter=(Created ge datetime'"+dateISO+"')";
        jQuery.ajax({
            url: endpoint,
            method: "GET",
            ...
            ...
            ...

    Alexander

  • #19037

    Nichols Family
    Participant

    Awesome. One more request, with a provided latitude and longitude in its respective columns, can I display a google map below the narrative with a icon on the lat long center point?

  • #19061

    Nichols Family
    Participant

    And maybe a edit icon to modify the narrative that would be amazing.

  • #19082

    Alexander Bautz
    Keymaster

    Hi,
    Yes, all is possible, but unfortunately I’m a bit to busy to help you with this right now. I might find time to do it after the holidays, but if you want to give it a go you can find information about the Google map api here (please note that you must register to get your API key – it’s free for up to 25K hits per day): https://developers.google.com/chart/interactive/docs/gallery/map#geocoded-locations

    The edit icon can be added using something like this example:

    <!-- Style -->
    <style type="text/css">
    .item-title-clickable{
        font-size:1.1em;
        background-color: #c7e0f4;
        padding:2px 5px;
        margin-top:2px;
        cursor:pointer;
    }
    .item-narrative{
        display: none;
        border-right:3px #c7e0f4 solid;
        border-bottom:3px #c7e0f4 solid;
        border-left:3px #c7e0f4 solid;
        padding:3px;
    }
    </style>
    <!-- HTML placeholder -->
    <div id="faq_placeholder"></div>
    <!-- Script -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript">
    function getFaqItems(){
        var date = new Date(), dateISO = "";
        date.setDate(date.getDate()-25);
        dateISO = String(date.getFullYear()) + "-" + String(date.getMonth()+1) + "-" + String(date.getDate()) + "T00:00:00Z";
        var endpoint = "/DFFS/_api/web/lists/getbytitle('title_click_to_expand_text')/items?$select=*,FileDirRef&$filter=(Created ge datetime'"+dateISO+"')";
        jQuery.ajax({
            url: endpoint,
            method: "GET",
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/jsom;odata=verbose",
                "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value
            }
        }).done(function (data) {
            var b = [], url;
            jQuery.each(data.d.results,function(i,item){
                b.push("<div class='item-title-clickable' onclick='jQuery(this).next().slideToggle(100);'>"+item.Title+"</div>");
                url = item.FileDirRef+"/EditForm.aspx?ID="+item.Id;
                b.push("<div class='item-narrative'>");
                    b.push("<span style='cursor:pointer;' onclick='openItemInDlg(\""+url+"\");'><img src='"+_spPageContextInfo.webServerRelativeUrl+"/_layouts/15/images/edititem.gif'></span><br>");
                    b.push(item.Narrative);
                b.push("</div>");
            });
            jQuery("#faq_placeholder").html(b.join(""));
        }).fail(function (err) {
            jQuery("#faq_placeholder").html(JSON.stringify(err));
        });
    }
    
    function openItemInDlg(url){
        SP.UI.ModalDialog.showModalDialog({"url":url,"dialogReturnValueCallback":function(a){
            if(a === 1){
                location.href = location.href;
            }
        }});
    }
    // Call function
    getFaqItems();
    </script>

    Alexander

  • #19104

    Nichols Family
    Participant

    You are the man thank you so much. heres a quick question if there are no results to display how would a send a “no results” message to the view?

  • #19210

    Alexander Bautz
    Keymaster

    Sorry – I missed your question. If you haven’t already figured it out you can do it like this:

    function getFaqItems(){
        var date = new Date(), dateISO = "";
        date.setDate(date.getDate()-25);
        dateISO = String(date.getFullYear()) + "-" + String(date.getMonth()+1) + "-" + String(date.getDate()) + "T00:00:00Z";
        var endpoint = "/DFFS/_api/web/lists/getbytitle('title_click_to_expand_text')/items?$select=*,FileDirRef&$filter=(Created ge datetime'"+dateISO+"')";
        jQuery.ajax({
            url: endpoint,
            method: "GET",
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/jsom;odata=verbose",
                "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value
            }
        }).done(function (data) {
            var b = [], url;
    		if(data.d.results.length > 0){
    			jQuery.each(data.d.results,function(i,item){
    				b.push("<div class='item-title-clickable' onclick='jQuery(this).next().slideToggle(100);'>"+item.Title+"</div>");
    				url = item.FileDirRef+"/EditForm.aspx?ID="+item.Id;
    				b.push("<div class='item-narrative'>");
    					b.push("<span style='cursor:pointer;' onclick='openItemInDlg(\""+url+"\");'><img src='"+_spPageContextInfo.webServerRelativeUrl+"/_layouts/15/images/edititem.gif'></span><br>");
    					b.push(item.Narrative);
    				b.push("</div>");
    			});
    		}else{
    			b.push("No result");
    		}
            jQuery("#faq_placeholder").html(b.join(""));
        }).fail(function (err) {
            jQuery("#faq_placeholder").html(JSON.stringify(err));
        });
    }

    Alexander

  • #20040

    Nichols Family
    Participant

    Here’s another question, hate to be a pain. If the list produces ten items how do I highlight odd rows blue and even rows red. Also If Item name contains the word bad how do I highlight that word specifically yellow?

  • #20075

    Alexander Bautz
    Keymaster

    You can modify your code like in the attached image.

    Alexander

  • #20081

    Nichols Family
    Participant

    It seems the alternating row colors is preventing the titles from expanding any thoughts?

  • #20083

    Nichols Family
    Participant

    Disregard I found the problem this awesome thank you so much. Beer is coming your way at my next check.

  • #20100

    Alexander Bautz
    Keymaster

    I’m glad it worked.

    Best regards,
    Alexander

  • #20254

    Nichols Family
    Participant

    How would I make this asynchronous. So if a new list item is added it should appear without refreshing.

  • #20281

    Alexander Bautz
    Keymaster

    You can use a setInterval function like this to reload it every 5 seconds:

    setInterval(function(){
        getFaqItems();
    },5000);

    To ensure only new items are drawn you must change the code like highlighted on the attached image.

    Please note that I haven’t tested this code, but I think it should work.

    Alexander

    Attachments:
  • #20304

    Nichols Family
    Participant

    Doesn’t seem to be working, it will load on page execution. But if I change a list time in a second window the information doesn’t redraw on the other. Any help you can provide will be greatly appreciated.

    Original code;

    <input type=”button” value=”Click here to create a new case” onclick=”javascript:OpenPopUpPage(‘https://intelshare.intelink.gov/sites/sccnola/CDO/_layouts/15/listform.aspx?PageType=8&ListId=%7B17B1BD80%2D5B62%2D4510%2DBF0C%2DE1C22781E2DE%7D&RootFolder=’)” />
    <!– Style –>
    <style type=”text/css”>
    .item-name2-clickableNOLA{
    border-top:1px #000000 solid;
    border-right:1px #000000 solid;
    border-bottom:1px #000000 solid;
    border-left:1px #000000 solid;
    font-size:1.1em;
    padding:2px 5px;
    margin-top:2px;
    cursor:pointer;
    }
    .item-narative{
    display: none;
    border-right:2px #000000 solid;
    border-bottom:2px #000000 solid;
    border-left:2px #000000 solid;
    padding:3px;
    }

    </style>
    <!– HTML placeholder –>

    <!– Script –>
    https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js

    function getMSItems(){
    var date = new Date(), dateISO = “”;
    date.setDate(date.getDate()-1);
    dateISO = String(date.getUTCFullYear()) + “-” + String(date.getUTCMonth()+1) + “-” + String(date.getUTCDate()) + “T00:00:00Z”;
    var endpoint = “https://intelshare.intelink.gov/sites/sccnola/CDO/_api/web/lists/getbytitle(‘Marine%20Safety%20Log’)/items?$select=*,FileDirRef&$filter=((Case_x0020_Status eq ‘PENDS’) or (Date_x0020_Case_x0020_Status_x00 ge datetime'”+dateISO+”‘))&$orderby= Created desc”;
    jQuery.ajax({
    url: endpoint,
    method: “GET”,
    headers: {
    “accept”: “application/json; odata=verbose”,
    “content-type”: “application/jsom;odata=verbose”,
    “X-RequestDigest”: document.getElementById(“__REQUESTDIGEST”).value
    }
    }).done(function (data) {
    var b = [], url;
    jQuery.each(data.d.results,function(i,item){
    var bgstyle = i % 2 === 0 ? “#dce0e8” : “#f2f4f7”;
    url = item.FileDirRef+”/EditForm.aspx?ID=”+item.Id;
    b.push(“”+item.name2+””);
    });
    jQuery(“#MS_placeholder”).html(b.join(“”));
    }).fail(function (err) {
    jQuery(“#MS_placeholder”).html(JSON.stringify(err));
    });
    }

    function openItemInDlg(url){
    SP.UI.ModalDialog.showModalDialog({“url”:url,”dialogReturnValueCallback”:function(a){
    if(a === 1){
    location.href = location.href;
    }
    }});
    }
    // Call function
    getMSItems();

    New code;

    <input type=”button” value=”Click here to create a new case” onclick=”javascript:OpenPopUpPage(‘https://intelshare.intelink.gov/sites/sccnola/CDO/_layouts/15/listform.aspx?PageType=8&ListId=%7B17B1BD80%2D5B62%2D4510%2DBF0C%2DE1C22781E2DE%7D&RootFolder=’)” />
    <!– Style –>
    <style type=”text/css”>
    .item-name2-clickableNOLA{
    border-top:1px #000000 solid;
    border-right:1px #000000 solid;
    border-bottom:1px #000000 solid;
    border-left:1px #000000 solid;
    font-size:1.1em;
    padding:2px 5px;
    margin-top:2px;
    cursor:pointer;
    }
    .item-narative{
    display: none;
    border-right:2px #000000 solid;
    border-bottom:2px #000000 solid;
    border-left:2px #000000 solid;
    padding:3px;
    }

    </style>
    <!– HTML placeholder –>

    <!– Script –>
    https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js

    var itemsAlreadyDrawn = {};
    function getMSItems(){
    var date = new Date(), dateISO = “”;
    date.setDate(date.getDate()-1);
    dateISO = String(date.getUTCFullYear()) + “-” + String(date.getUTCMonth()+1) + “-” + String(date.getUTCDate()) + “T00:00:00Z”;
    var endpoint = “https://intelshare.intelink.gov/sites/sccnola/CDO/_api/web/lists/getbytitle(‘Marine%20Safety%20Log’)/items?$select=*,FileDirRef&$filter=((Case_x0020_Status eq ‘PENDS’) or (Date_x0020_Case_x0020_Status_x00 ge datetime'”+dateISO+”‘))&$orderby= Created desc”;
    jQuery.ajax({
    url: endpoint,
    method: “GET”,
    headers: {
    “accept”: “application/json; odata=verbose”,
    “content-type”: “application/jsom;odata=verbose”,
    “X-RequestDigest”: document.getElementById(“__REQUESTDIGEST”).value
    }
    }).done(function (data) {
    var b = [], url;
    jQuery.each(data.d.results,function(i,item){
    if (itemsAlreadyDrawn[item.Id]) {
    //Already drawn
    return;
    }
    itemsAlreadyDrawn[item.Id] = true;
    var bgstyle = i % 2 === 0 ? “#dce0e8” : “#f2f4f7”;
    url = item.FileDirRef+”/EditForm.aspx?ID=”+item.Id;
    b.push(“”+item.name2+””);
    });
    jQuery(“#MS_placeholder”).append(b.join(“”));
    }).fail(function (err) {
    jQuery(“#MS_placeholder”).html(JSON.stringify(err));
    });
    }

    function openItemInDlg(url){
    SP.UI.ModalDialog.showModalDialog({“url”:url,”dialogReturnValueCallback”:function(a){
    if(a === 1){
    location.href = location.href;
    }
    }});
    }
    // Call function
    getMSItems();
    setInterval(function(data){
    },500);

  • #20331

    Alexander Bautz
    Keymaster

    Hi,
    My original reply was intended for new items and not modified items. I have changed it to detect if the item has been modified since last draw – and in case, it will replace the item.

    Keep in mind that this snippet will not reflect your local changes to look over it and modify your original.

    var itemsAlreadyDrawn  = {};
    function getFaqItems(){
        var date = new Date(), dateISO = "";
        // Set start 25 hours back in time
        // date.setHours(date.getHours()-25);
        // Set start 25 days back in time
        date.setDate(date.getDate()-25);
        dateISO = String(date.getFullYear()) + "-" + String(date.getMonth()+1) + "-" + String(date.getDate()) + "T00:00:00Z";
        var endpoint = "/DFFS/_api/web/lists/getbytitle('title_click_to_expand_text')/items?$select=*,FileDirRef&$filter=(Created ge datetime'"+dateISO+"')";
        jQuery.ajax({
            url: endpoint,
            method: "GET",
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/jsom;odata=verbose",
                "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value
            }
        }).done(function (data) {
            var b = [], c, url;
            jQuery.each(data.d.results,function(i,item){
                if (itemsAlreadyDrawn[item.Id] !== undefined && itemsAlreadyDrawn[item.Id] === item.Modified) {
                    // Already drawn
                    return;
                }
                itemsAlreadyDrawn[item.Id] = item.Modified;
                var bgStyle = i % 2 === 0 ? "#f6f6f6" : "#ffffff";
                item.Narrative = item.Narrative.split(" bad ").join(" <span style='background-color:yellow;'>bad</span> ");
                c = [];
                c.push("<div id='faq_wrapper_"+item.Id+"'>");
                c.push("<div class='item-title-clickable' style='background-color:"+bgStyle+";' onclick='jQuery(this).next().slideToggle(100);'>"+item.Title+"</div>");
                url = item.FileDirRef+"/EditForm.aspx?ID="+item.Id;
                c.push("<div class='item-narrative'>");
                c.push("<span style='cursor:pointer;' onclick='openItemInDlg(\""+url+"\");'><img src='"+_spPageContextInfo.webServerRelativeUrl+"/_layouts/15/images/edititem.gif'></span><br>");
                c.push(item.Narrative);
                c.push("</div>");
                c.push("</div>");
                if(jQuery("#faq_wrapper_"+item.Id).length > 0){
                    jQuery("#faq_wrapper_"+item.Id).replaceWith(c.join(""));
                }else{
                    b.push(c.join(""));
                }
            });
            if(b.length > 0){
                jQuery("#faq_placeholder").html(b.join(""));
            }
        }).fail(function (err) {
            jQuery("#faq_placeholder").html(JSON.stringify(err));
        });
    }
    
    function openItemInDlg(url){
        SP.UI.ModalDialog.showModalDialog({"url":url,"dialogReturnValueCallback":function(a){
            if(a === 1){
                location.href = location.href;
            }
        }});
    }
    // Call function
    getFaqItems();
    // Set interval
    setInterval(function(){
        getFaqItems();
    },5000);
  • #20431

    Nichols Family
    Participant

    How would I work these into tabs? I have three accordion lists each separate from each other. I would like all three to be in a tab with the accordion. The site is setup for three web part zones and would like to have three tabs with three accordions each going across? Any ideas?

  • #20466

    Alexander Bautz
    Keymaster

    I’ve rewritten the snippet to build some tabs, but please not that it has been thrown together without much though so use it as a starting point and see where you can get it with a little tinkering. Keep in mind that this snippet will not reflect your local changes to look over it and modify your original.

    Alexander

    <!-- Style -->
    <style type="text/css">
    .item-title-clickable{
        font-size:1.1em;
        padding:5px 10px;
        margin-top:2px;
        cursor:pointer;
    }
    .item-narrative{
        display: none;
        border:1px #c7e0f4 solid;
        padding:3px;
    }
    .narrativeTabWrapper{
        overflow:auto;
    }
    .narrativeTab{
        float: left;
        margin-right:2px;
        background-color: #c7e0f4;
    }
    .selectedTab{
        background-color: green;
        color:white;
    }
    </style>
    <!-- HTML placeholder -->
    <div id="faq_placeholder"></div>
    <!-- Script -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript">
    var itemsAlreadyDrawn  = {};
    function getFaqItems(){
        var date = new Date(), dateISO = "";
        // Set start 25 hours back in time
        // date.setHours(date.getHours()-25);
        // Set start 25 days back in time
        date.setDate(date.getDate()-25);
        dateISO = String(date.getFullYear()) + "-" + String(date.getMonth()+1) + "-" + String(date.getDate()) + "T00:00:00Z";
        var endpoint = "/DFFS/_api/web/lists/getbytitle('title_click_to_expand_text')/items?$select=*,FileDirRef&$filter=(Created ge datetime'"+dateISO+"')";
        jQuery.ajax({
            url: endpoint,
            method: "GET",
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/jsom;odata=verbose",
                "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value
            }
        }).done(function (data) {
            var b = [], c, url;
            // First build the tabs
            jQuery.each(data.d.results,function(i,item){
                if (itemsAlreadyDrawn[item.Id] !== undefined && itemsAlreadyDrawn[item.Id] === item.Modified) {
                    // Already drawn
                    return;
                }
                c = [];
                c.push("<div class='narrativeTab' id='faq_wrapper_"+item.Id+"'>");
                c.push("<div class='item-title-clickable' onclick='toggleNarrative(this,"+item.Id+");'>"+item.Title+"</div>");
                c.push("</div>");
                if(jQuery("#faq_wrapper_"+item.Id).length > 0){
                    jQuery("#faq_wrapper_"+item.Id).replaceWith(c.join(""));
                }else{
                    b.push(c.join(""));
                }
            });
            if(b.length > 0){
                jQuery("#faq_placeholder").html("<div class='narrativeTabWrapper'>" + b.join("") + "</div>");
            }
            b = [];
            // Then build the narrative placeholders
            jQuery.each(data.d.results,function(i,item){
                if (itemsAlreadyDrawn[item.Id] !== undefined && itemsAlreadyDrawn[item.Id] === item.Modified) {
                    // Already drawn
                    return;
                }
                itemsAlreadyDrawn[item.Id] = item.Modified;
                item.Narrative = item.Narrative.split(" bad ").join(" <span style='background-color:yellow;'>bad</span> ");
                c = [];
                url = item.FileDirRef+"/EditForm.aspx?ID="+item.Id;
                c.push("<div id='narrative_contents_"+item.Id+"' class='item-narrative'>");
                c.push("<span style='cursor:pointer;' onclick='openItemInDlg(\""+url+"\");'><img src='"+_spPageContextInfo.webServerRelativeUrl+"/_layouts/15/images/edititem.gif'></span><br>");
                c.push(item.Narrative);
                c.push("</div>");
                if(jQuery("#narrative_contents_"+item.Id).length > 0){
                    jQuery("#narrative_contents_"+item.Id).replaceWith(c.join(""));
                }else{
                    b.push(c.join(""));
                }
            });
            if(b.length > 0){
                jQuery("#faq_placeholder").append(b.join(""));
            }
        }).fail(function (err) {
            jQuery("#faq_placeholder").html(JSON.stringify(err));
        });
    }
    
    function toggleNarrative(elm,index){
        // hide all first
        jQuery(".selectedTab").removeClass("selectedTab");
        jQuery(".item-narrative").hide();
        // Show correct item
        jQuery(elm).parent().addClass("selectedTab");
        jQuery("#narrative_contents_"+index).show();
    }
    
    function openItemInDlg(url){
        SP.UI.ModalDialog.showModalDialog({"url":url,"dialogReturnValueCallback":function(a){
            if(a === 1){
                location.href = location.href;
            }
        }});
    }
    // Call function
    getFaqItems();
    // Set interval
    setInterval(function(){
        getFaqItems();
    },5000);
    </script>

You must be logged in to reply to this topic.