function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
thatheraherethatherahere 

Re-rendering removing SVG-USE tags from Visuaforce page

Hi,

I'm using Lightning Design System with a Visualforce page and using <svg> tag to get SLDS Icons on Page header and Buttons. Initially on page load all works fine but when I try to re-render any <apex:outputPanel> that have <svg> icons inside it, on complete of rerendering it vanish my all <svg> icons.
I tried to debbug it by Inspect element in chrome and found after re-rendering any block my <svg> icon tags are not there.

anyone else experiencing this issue?

Any advise or guidance would be greatly appreciated.

Thanks,
@thatherahere
Mohith Kumar ShrivastavaMohith Kumar Shrivastava
This is known limitation of the browser .Since the SVG use xlink as below you cant rerender SVG component and its obvious that you wont be able to get around this issue .

<html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

SLDS should not be combined with actionfunction reRender if SVG is involved and instead i would rewrite my Visuaforce page using angular or jquery or React using mordern world SPA framework .

Hope this helps !


 
Steve NelsonSteve Nelson
Hi thatherahere,

Did you ever find a work-around? I am having a similar issue.  My icon is in a repeating table row that is re-rendered upon a button click. The re-rendering stops completely when I have have the use xlink tag in the table.

Thanks
Jeff​​
Mohith Kumar ShrivastavaMohith Kumar Shrivastava
This seems to have fixed in the latest build .I am using the latest 0102 release of SLDS package and no more able to replicate .Let me know if anybody faces this in future .
thatheraherethatherahere
Hi Mohith,

I tried it with build 0102 but didn't find it working. Can you please share your experience how you achieved it. 
I simply created a method in apex class and a Visualforce page with one SVG Icon and CommandButton. Using CommandButton I reRendered my form and the result was same, After completion of that action SVG was not on my page. Its crazy. Am I missing something here?


Thanks,
@thatherahere
thatheraherethatherahere
Hi Mohith,

Here is my code for Visualforce page and Apex class:


SVGRerendering.cls
public with sharing class SVGRerendering{
    public String helloUser{get;set;}

    public SVGRerendering(){
        helloUser = '';
    }
    
    public void HelloWorld(){
        helloUser = 'Hello '+UserInfo.getName();
    }
}

SVGRerendering.page
<apex:page controller="SVGRerendering" standardStylesheets="false" showHeader="false">
    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <head>
            <apex:stylesheet value="{!URLFOR($Resource.SLDS0102, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
        </head>
        <body>
            <apex:form id="frm">
                
                <div class="slds">
                    <svg aria-hidden="true" class="slds-icon slds-icon--large slds-icon-standard-user">
                        <use xlink:href="{!URLFOR($Resource.SLDS0102, 'assets/icons/standard-sprite/svg/symbols.svg#user')}" />
                    </svg>
                    <apex:outputText value="{!helloUser}"></apex:outputText><br/><br/>
                    <apex:commandButton value="Rerender Form" styleClass="slds-button slds-button--neutral" reRender="frm" action="{!HelloWorld}"/>
                </div>
            </apex:form>
        </body>
    </html>
</apex:page>

Please review and let me know what I'm missing here.


Thanks,
@thatherahere
Mohith Kumar ShrivastavaMohith Kumar Shrivastava
One of the ways that I have got working is as below ,It required little modification 
 
<apex:page controller="SVGRerendering" standardStylesheets="false" showHeader="false">
    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <head>
            <apex:stylesheet value="{!URLFOR($Resource.SLDS0102, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
        </head>
        <body>
        
            <apex:form id="frm">
              <apex:outputPanel id="SVGIcon">  
                <div class="slds">
                    <svg aria-hidden="true" class="slds-icon slds-icon--large slds-icon-standard-user">
                        <use xlink:href="{!URLFOR($Resource.SLDS0102, 'assets/icons/standard-sprite/svg/symbols.svg#user')}" />
                    </svg>
                    <apex:outputText value="{!helloUser}"></apex:outputText><br/><br/>
                    <apex:commandButton value="Rerender Form" styleClass="slds-button slds-button--neutral" onclick="reRenderSVG();" reRender="SVGIcon"/>
                    <apex:actionFunction name="reRenderSVG"  action="{!HelloWorld}"/>
                </div>
                </apex:outputPanel>
            </apex:form>
            
        </body>
    </html>
</apex:page>

For your markup .I am looking into browser to see what stops it from being rendered .Looks for more detailed response from me .Thanks
Mohith Kumar ShrivastavaMohith Kumar Shrivastava
So final thought on this is it looks a bug to me from Salesforce .With bit of jquery on the page you can literally rewrite missing DOM on the Oncomplete call

Here is working code for worst case scenario
 
<apex:page controller="SVGRerendering" standardStylesheets="false" showHeader="false" id="thepage">
    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <head>
            <apex:stylesheet value="{!URLFOR($Resource.SLDS0102, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
             <apex:includeScript value="//code.jquery.com/jquery-2.1.4.min.js" />
        </head>
        <body>
            <apex:form id="frm">
                <apex:outputPanel id="SVGIcon" layout="block">
                <div class="slds" id="Icon">
                    <svg aria-hidden="true" class="slds-icon slds-icon--large slds-icon-standard-user">
                        <use xlink:href="{!URLFOR($Resource.SLDS0102, 'assets/icons/standard-sprite/svg/symbols.svg#user')}" />
                    </svg>
                    <apex:outputText value="{!helloUser}"></apex:outputText><br/><br/>
                    <apex:commandButton value="Rerender Form" styleClass="slds-button slds-button--neutral" reRender="frm" action="{!HelloWorld}" oncomplete="renderSVG();"/>
                </div>
                </apex:outputPanel>
            </apex:form>
            <script>
            var j$ = jQuery.noConflict();
              function renderSVG(){
                var imageURL = '{!URLFOR($Resource.SLDS0102, 'assets/icons/standard-sprite/svg/symbols.svg#user')}';
                var SVG = j$('<svg/>', {
                   class: 'slds-icon slds-icon--large slds-icon-standard-user',
                });

                var SVGUse = j$('<use/>');
                SVGUse.attr('xlink:href',imageURL);
                j$('#Icon').prepend(SVG.append(SVGUse));
                j$('#Icon' ).html(j$('#Icon').html());
              }
            </script>
        </body>
    </html>
</apex:page>



 
thatheraherethatherahere
Yes, I feel the same, It is a bug from Salesforce. On rerender they do not consider set of tags like svg, use, section etc.

Thanks for your help. I already tried this jquery. It works fine for small pages but for large there will be many oncomplete calls so I avoided this trick.
udaykumar kudaykumar k
Hi Mohith, thanks for your code..But I have absorved that the reRendering is hiding the svg component.. Let me know what I am missing??
 
<apex:page controller="SVGRerendering" standardStylesheets="false" showHeader="false" id="thepage">
    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <head>
            <apex:stylesheet value="{!URLFOR($Resource.SLDS104, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
              <apex:includeScript value="{!$Resource.jquery1}"/>
        </head>
        <body>
            <apex:form id="frm">
             <apex:outputText value="{!helloUser}"></apex:outputText><br/><br/>
                <apex:outputPanel id="SVGIcon" layout="block">
                <div class="slds" id="Icon">
                    <svg aria-hidden="true" class="slds-icon slds-icon--large slds-icon-standard-user">
                        <use xlink:href="{!URLFOR($Resource.SLDS104, 'assets/icons/standard-sprite/svg/symbols.svg#user')}" />
                    </svg>
                   
                 <!--   <apex:commandButton value="Rerender Form" styleClass="slds-button slds-button--neutral" reRender="frm" action="{!HelloWorld}" oncomplete="renderSVG();"/>-->
                 
                </div>
                </apex:outputPanel>
                <div>Click me! <apex:actionSupport event="onclick" action="{!HelloWorld}"  reRender="frm"  /> </div>
            </apex:form>
            
            <script>
            var j$ = jQuery.noConflict();
              function renderSVG(){
                var imageURL = '{!URLFOR($Resource.SLDS104, 'assets/icons/standard-sprite/svg/symbols.svg#user')}';
                var SVG = j$('<svg/>', {
                   class: 'slds-icon slds-icon--large slds-icon-standard-user',
                });

                var SVGUse = j$('<use/>');
                SVGUse.attr('xlink:href',imageURL);
                j$('#Icon').prepend(SVG.append(SVGUse));
                j$('#Icon' ).html(j$('#Icon').html());
              }
            </script>
        </body>
    </html>
</apex:page>

 
John HutchinsonJohn Hutchinson
This is an old thread but adding my experience to it regardless. I've found that the SVG re-rendering doesn't quite qork as expected when you are using it with Date pickers. The previous code will replace the first matched SVGs tags on all subsequent svgs and this then stops date pickers initialising properly. I modified it to use the jquery .each function.

Thank you to those who wrote the original fix! With some messing it worked like a charm.
 
function reRenderSVG(){             // On panel rerender SVGs are lost,(sf bug) so have to re-draw them.
                var imageURL = "{!URLFOR($Resource.ltngDS, 'assets/icons/utility-sprite/svg/symbols.svg#event')}";
                var SVG = j$("<svg/>", {
                class: "slds-input__icon slds-icon-text-default",
                });
                var SVGUse = j$("<use/>");
                SVGUse.attr("xlink:href",imageURL);
                var SVGComplete = SVG.append(SVGUse);

                j$(".slds-input-has-icon--right").each(function() {
                    j$( this ).prepend(SVGComplete);
                    j$( this ).html(j$( this ) .html());
                });
                initDatePickers(true);              // Once SVGs are re-drawn re-initialise date pickers.
            }

 
Magesh Mani YadavMagesh Mani Yadav
Hello guys,
Just set you apex:page  attribute  docType="html-5.0" and this will fix the rerender SVG bug
Sachin Verma 88Sachin Verma 88
Adding doctype = "html-5.0" this fix my issue..
Thanks Magesh,