Print/export widget bug - button clicking causes postback in ASP.NET

6962
14
Jump to solution
10-24-2019 02:12 PM
ChrisSmith7
Frequent Contributor

Hello,

I believe I've encountered a bug with the v4 print widget, which is causing a postback when clicking button elements. For instance, "Advanced Options", "Refresh", "Map Only", "Export" causes a postback on an aspx in Chrome.

One solution is to add the widget outside of the form tag, e.g. as indicated by ArcGIS JavaScript API 4.11 - Print causes Postback Issue in asp.net - Stack Overflow.

However, the built-in widgets are designed to make it easier to develop and to stay within the widget "ecosystem", so this isn't a preferable solution for me.

Another solution is to add the "type" attribute, as "button", which is actually something recommended by W3 - https://www.w3docs.com/learn-html/html-button-tag.html:

The <button> tag doesn’t have required attributes; however, we recommend always use the type=”button” attribute, if the tag used as an ordinary button.

The recommendation is made as browsers determine default behavior. In my case, when using Chrome on an aspx, it is using "submit" behavior.

I have a solution to iterate over the widget elements in jQuery to add the type attribute, but it's a kludge (we have to detect when the widget is loaded and when hidden elements are made visible). Also, styling of the "Layout" and "Map Only" buttons at the top changes, so that's something else that will need manual correction.

Is there a better solution/recommendation? Is Esri working on a fix?

Thanks!

1 Solution

Accepted Solutions
Noah-Sager
Esri Regular Contributor

Update: the fix for this issue will make it in for the next release, version 4.17.

View solution in original post

14 Replies
Noah-Sager
Esri Regular Contributor

Thanks for reporting this, Chris. Does this issue occur with other widgets, or is it just with the Print widget? Could you share a simplified app that reproduces the issue you are seeing? Feel free to message or email me if you don't want to post it here.

Here is another method that may or may not work for you, similar to the stackOverflow thread, and similar to how we add the TimeSlider widget to an app:

https://codepen.io/noash/pen/mddwPEz 

-Noah

0 Kudos
ChrisSmith7
Frequent Contributor

Noah, thanks for reaching-out... presumably, it will occur with any widgets containing button elements missing type="button". 

I can work on developing a simplified ASP.NET app and attach when I can, but I do have a kludgy jQuery workaround. The easiest solution would be for Esri to add type attributes to the widget in the API. Here's the HTML as modified by my workaround (all of the button elements were missing type="button" from the API):

<div class="esri-print esri-widget esri-widget--panel" data-node-ref="_rootNode">
    <div>
        <div class="esri-print__container">
            <header class="esri-print__header-title">Export</header>
            <div>
                <ul class="esri-print__layout-tab-list" role="tablist">
                    <li id="16e19dffab1-widget-4__layoutTab" data-tab-id="layoutTab" class="esri-print__layout-tab" role="tab" tabindex="0" aria-selected="true">Layout</li>
                    <li id="16e19dffab1-widget-4__mapOnlyTab" data-tab-id="mapOnlyTab" class="esri-print__layout-tab" role="tab" tabindex="0" aria-selected="false">Map Only</li>
                </ul>
                <section id="16e19dffab1-widget-4__layoutContent" aria-labelledby="16e19dffab1-widget-4__layoutTab" class="esri-print__layout-section" role="tabpanel">
                    <div class="esri-print__panel-container">
                        <div class="esri-print__form-section-container">
                            <label>Title
                                <input type="text" tabindex="0" placeholder="Title of file" class="esri-print__input-text esri-input" data-input-name="title">
                            </label>
                        </div>
                        <div class="esri-print__form-section-container">
                            <label>Page setup
                                <select class="esri-select" data-target-property="layout">
                                    <option value="letter-ansi-a-landscape">Letter ANSI A Landscape</option>
                                    <option value="a3-landscape">A3 Landscape</option>
                                    <option value="a3-portrait">A3 Portrait</option>
                                    <option value="a4-landscape">A4 Landscape</option>
                                    <option value="a4-portrait">A4 Portrait</option>
                                    <option value="letter-ansi-a-portrait">Letter ANSI A Portrait</option>
                                    <option value="tabloid-ansi-b-landscape">Tabloid ANSI B Landscape</option>
                                    <option value="tabloid-ansi-b-portrait">Tabloid ANSI B Portrait</option>
                                </select>
                            </label>
                        </div>
                        <div class="esri-print__form-section-container">
                            <label>File format
                                <select class="esri-select" data-target-property="format">
                                    <option value="pdf">PDF</option>
                                    <option value="png32">PNG32</option>
                                    <option value="png8">PNG8</option>
                                    <option value="jpg">JPG</option>
                                    <option value="gif">GIF</option>
                                    <option value="eps">EPS</option>
                                    <option value="svg">SVG</option>
                                    <option value="svgz">SVGZ</option>
                                </select>
                            </label>
                        </div>
                    </div>
                    <div class="esri-print__panel-container esri-print__advanced-options-section">
                        <button aria-label="Advanced Options" aria-expanded="true" role="button" class="esri-print__advanced-options-button" type="button">
                            <div class="esri-print__advanced-options-button-container"><span aria-hidden="true" class="esri-icon-right-triangle-arrow esri-print__advanced-options-button-icon--closed"></span><span aria-hidden="true" class="esri-icon-left-triangle-arrow esri-print__advanced-options-button-icon--closed-rtl"></span><span aria-hidden="true" class="esri-icon-down-arrow esri-print__advanced-options-button-icon--opened"></span><span class="esri-print__advanced-options-button-title">Advanced Options</span></div>
                        </button>
                        <div aria-labelledby="16e19dffab1-widget-4__advancedOptionsForLayout" class="esri-print__advanced-options-container">
                            <div class="esri-print__scale-info-container esri-print__form-section-container">
                                <label>
                                    <input type="checkbox" data-option-name="scaleEnabled" tabindex="0">Set scale</label>
                                <div class="esri-print__scale-input-container">
                                    <input type="number" aria-label="scale" aria-valuenow="9244648.868618" role="spinbutton" class="esri-print__input-text esri-input esri-print__scale-input" tabindex="0" data-input-name="scale" disabled="">
                                    <button role="button" aria-label="reset" class="esri-widget--button esri-print__refresh-button esri-icon-refresh" tabindex="0" type="button"></button>
                                </div>
                            </div>
                            <div class="esri-print__author-info-container esri-print__form-section-container">
                                <label>Author
                                    <input type="text" class="esri-print__input-text esri-input" tabindex="0" data-input-name="author">
                                </label>
                            </div>
                            <div class="esri-print__copyright-info-container esri-print__form-section-container">
                                <label>Copyright
                                    <input type="text" class="esri-print__input-text esri-input" tabindex="0" data-input-name="copyright">
                                </label>
                            </div>
                            <div class="esri-print__form-section-container">
                                <label>DPI
                                    <input type="number" class="esri-print__input-text esri-input" data-input-name="dpi" min="1" tabindex="0">
                                </label>
                            </div>
                            <div class="esri-print__legend-info-container esri-print__form-section-container">
                                <label>
                                    <input type="checkbox" data-option-name="legendEnabled" tabindex="0">Include legend</label>
                            </div>
                        </div>
                    </div>
                </section>
                <button aria-label="Export. Exported files will appear below." role="button" class="esri-print__export-button esri-button" tabindex="0" type="button">Export</button>
                <div class="esri-print__export-panel-container">
                    <h3 class="esri-print__export-title esri-widget__heading">Exported Files</h3>
                    <div>
                        <div>Your exported files will appear here.</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
0 Kudos
ChrisSmith7
Frequent Contributor

Oh, and to answer your other question, this is also an issue with the sketch widget.

0 Kudos
Noah-Sager
Esri Regular Contributor

Ok, thanks for the info. Please share the simplified ASP.NET app when you have time and I'll take a look.

0 Kudos
TravisBock2
New Contributor II

Was there a resolution or better work around on this?  Its not ASP related.  Here is the sketch widget codepen wrapped in a form with a onsubmit event. https://codepen.io/tbock/pen/NWNGWrx 

0 Kudos
Noah-Sager
Esri Regular Contributor
Thanks for the additional information, Travis. I think it's because button elements have a default behavior of "submit" when wrapped in a form, based on:
 
We are investigating this now from the API perspective. In the meantime, you could use evt.preventDefault() in the onsubmit callback if the element that invoked the submission was not the expected one.
 
Psuedo-code:
document.getElementById("myform").onsubmit = function (evt) {   if (myRealSubmitButton !== evt.submitter) {     // submit likely called via sketch UI button click     evt.preventDefault();   } };
TravisBock2
New Contributor II

Hi Noah,

Yes I think your assessment is correct and your temporary solution is reasonable. However,  I agree with Chris Smith that the buttons generated in the API should be type=button as the documentation indicates. 

I have also added the type=button attribute using jquery and it does solve the problem and appears to cause no harm to the widgets functionality.   

Thanks!

Noah-Sager
Esri Regular Contributor

Update: we are getting closer to a solution for this, where the type=button as discussed. This should make it in for the next release (early October), but I will update this thread when a final decision is made.

Noah-Sager
Esri Regular Contributor

Update: the fix for this issue will make it in for the next release, version 4.17.