Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override "Error Loading Page" for network failure in js file

I have JQuery Mobile-1.0.js file.

 // Load a page into the DOM.
    $.mobile.loadPage = function (url, options) {
        // This function uses deferred notifications to let callers
        // know when the page is done loading, or if an error has occurred.
        var deferred = $.Deferred(),

        // The default loadPage options with overrides specified by
        // the caller.
            settings = $.extend({}, $.mobile.loadPage.defaults, options),

        // The DOM element for the page after it has been loaded.
            page = null,

        // If the reloadPage option is true, and the page is already
        // in the DOM, dupCachedPage will be set to the page element
        // so that it can be removed after the new version of the
        // page is loaded off the network.
            dupCachedPage = null,

        // determine the current base url
            findBaseWithDefault = function () {
                var closestBase = ($.mobile.activePage && getClosestBaseUrl($.mobile.activePage));
                return closestBase || documentBase.hrefNoHash;
            },

        // The absolute version of the URL passed into the function. This
        // version of the URL may contain dialog/subpage params in it.
            absUrl = path.makeUrlAbsolute(url, findBaseWithDefault());


        // If the caller provided data, and we're using "get" request,
        // append the data to the URL.
        if (settings.data && settings.type === "get") {
            absUrl = path.addSearchParams(absUrl, settings.data);
            settings.data = undefined;
        }

        // If the caller is using a "post" request, reloadPage must be true
        if (settings.data && settings.type === "post") {
            settings.reloadPage = true;
        }

        // The absolute version of the URL minus any dialog/subpage params.
        // In otherwords the real URL of the page to be loaded.
        var fileUrl = path.getFilePath(absUrl),

        // The version of the Url actually stored in the data-url attribute of
        // the page. For embedded pages, it is just the id of the page. For pages
        // within the same domain as the document base, it is the site relative
        // path. For cross-domain pages (Phone Gap only) the entire absolute Url
        // used to load the page.
            dataUrl = path.convertUrlToDataUrl(absUrl);

        // Make sure we have a pageContainer to work with.
        settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;

        // Check to see if the page already exists in the DOM.
        page = settings.pageContainer.children(":jqmData(url='" + dataUrl + "')");

        // If we failed to find the page, check to see if the url is a
        // reference to an embedded page. If so, it may have been dynamically
        // injected by a developer, in which case it would be lacking a data-url
        // attribute and in need of enhancement.
        if (page.length === 0 && dataUrl && !path.isPath(dataUrl)) {
            page = settings.pageContainer.children("#" + dataUrl)
                .attr("data-" + $.mobile.ns + "url", dataUrl);
        }

        // If we failed to find a page in the DOM, check the URL to see if it
        // refers to the first page in the application. If it isn't a reference
        // to the first page and refers to non-existent embedded page, error out.
        if (page.length === 0) {
            if ($.mobile.firstPage && path.isFirstPageUrl(fileUrl)) {
                // Check to make sure our cached-first-page is actually
                // in the DOM. Some user deployed apps are pruning the first
                // page from the DOM for various reasons, we check for this
                // case here because we don't want a first-page with an id
                // falling through to the non-existent embedded page error
                // case. If the first-page is not in the DOM, then we let
                // things fall through to the ajax loading code below so
                // that it gets reloaded.
                if ($.mobile.firstPage.parent().length) {
                    page = $($.mobile.firstPage);
                }
            } else if (path.isEmbeddedPage(fileUrl)) {
                deferred.reject(absUrl, options);
                return deferred.promise();
            }
        }

        // Reset base to the default document base.
        if (base) {
            base.reset();
        }

        // If the page we are interested in is already in the DOM,
        // and the caller did not indicate that we should force a
        // reload of the file, we are done. Otherwise, track the
        // existing page as a duplicated.
        if (page.length) {
            if (!settings.reloadPage) {
                enhancePage(page, settings.role);
                deferred.resolve(absUrl, options, page);
                return deferred.promise();
            }
            dupCachedPage = page;
        }

        var mpc = settings.pageContainer,
            pblEvent = new $.Event("pagebeforeload"),
            triggerData = { url: url, absUrl: absUrl, dataUrl: dataUrl, deferred: deferred, options: settings };

        // Let listeners know we're about to load a page.
        mpc.trigger(pblEvent, triggerData);

        // If the default behavior is prevented, stop here!
        if (pblEvent.isDefaultPrevented()) {
            return deferred.promise();
        }

        if (settings.showLoadMsg) {

            // This configurable timeout allows cached pages a brief delay to load without showing a message
            var loadMsgDelay = setTimeout(function () {
                $.mobile.showPageLoadingMsg();
            }, settings.loadMsgDelay),

            // Shared logic for clearing timeout and removing message.
                hideMsg = function () {

                    // Stop message show timer
                    clearTimeout(loadMsgDelay);

                    // Hide loading message
                    $.mobile.hidePageLoadingMsg();
                };
        }

        if (!($.mobile.allowCrossDomainPages || path.isSameDomain(documentUrl, absUrl))) {
            deferred.reject(absUrl, options);
        } else {
            // Load the new page.
            $.ajax({
                url: fileUrl,
                type: settings.type,
                data: settings.data,
                dataType: "html",
                success: function (html, textStatus, xhr) {
                    //pre-parse html to check for a data-url,
                    //use it as the new fileUrl, base path, etc
                    var all = $("<div></div>"),

                    //page title regexp
                        newPageTitle = html.match(/<title[^>]*>([^<]*)/) && RegExp.$1,

                    // TODO handle dialogs again
                        pageElemRegex = new RegExp("(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>)"),
                        dataUrlRegex = new RegExp("\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?");


                    // data-url must be provided for the base tag so resource requests can be directed to the
                    // correct url. loading into a temprorary element makes these requests immediately
                    if (pageElemRegex.test(html)
                            && RegExp.$1
                            && dataUrlRegex.test(RegExp.$1)
                            && RegExp.$1) {
                        url = fileUrl = path.getFilePath(RegExp.$1);
                    }

                    if (base) {
                        base.set(fileUrl);
                    }

                    //workaround to allow scripts to execute when included in page divs
                    all.get(0).innerHTML = html;
                    page = all.find(":jqmData(role='page'), :jqmData(role='dialog')").first();

                    //if page elem couldn't be found, create one and insert the body element's contents
                    if (!page.length) {
                        page = $("<div data-" + $.mobile.ns + "role='page'>" + html.split(/<\/?body[^>]*>/gmi)[1] + "</div>");
                    }

                    if (newPageTitle && !page.jqmData("title")) {
                        if (~newPageTitle.indexOf("&")) {
                            newPageTitle = $("<div>" + newPageTitle + "</div>").text();
                        }
                        page.jqmData("title", newPageTitle);
                    }

                    //rewrite src and href attrs to use a base url
                    if (!$.support.dynamicBaseTag) {
                        var newPath = path.get(fileUrl);
                        page.find("[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]").each(function () {
                            var thisAttr = $(this).is('[href]') ? 'href' :
                                    $(this).is('[src]') ? 'src' : 'action',
                                thisUrl = $(this).attr(thisAttr);

                            // XXX_jblas: We need to fix this so that it removes the document
                            //            base URL, and then prepends with the new page URL.
                            //if full path exists and is same, chop it - helps IE out
                            thisUrl = thisUrl.replace(location.protocol + '//' + location.host + location.pathname, '');

                            if (!/^(\w+:|#|\/)/.test(thisUrl)) {
                                $(this).attr(thisAttr, newPath + thisUrl);
                            }
                        });
                    }

                    //append to page and enhance
                    // TODO taging a page with external to make sure that embedded pages aren't removed
                    //      by the various page handling code is bad. Having page handling code in many
                    //      places is bad. Solutions post 1.0
                    page
                        .attr("data-" + $.mobile.ns + "url", path.convertUrlToDataUrl(fileUrl))
                        .attr("data-" + $.mobile.ns + "external-page", true)
                        .appendTo(settings.pageContainer);

                    // wait for page creation to leverage options defined on widget
                    page.one('pagecreate', $.mobile._bindPageRemove);

                    enhancePage(page, settings.role);

                    // Enhancing the page may result in new dialogs/sub pages being inserted
                    // into the DOM. If the original absUrl refers to a sub-page, that is the
                    // real page we are interested in.
                    if (absUrl.indexOf("&" + $.mobile.subPageUrlKey) > -1) {
                        page = settings.pageContainer.children(":jqmData(url='" + dataUrl + "')");
                    }

                    //bind pageHide to removePage after it's hidden, if the page options specify to do so

                    // Remove loading message.
                    if (settings.showLoadMsg) {
                        hideMsg();
                    }

                    // Add the page reference and xhr to our triggerData.
                    triggerData.xhr = xhr;
                    triggerData.textStatus = textStatus;
                    triggerData.page = page;

                    // Let listeners know the page loaded successfully.
                    settings.pageContainer.trigger("pageload", triggerData);

                    deferred.resolve(absUrl, options, page, dupCachedPage);
                },
                error: function (xhr, textStatus, errorThrown) {
                    //set base back to current path
                    if (base) {
                        base.set(path.get());
                    }

                    // Add error info to our triggerData.
                    triggerData.xhr = xhr;
                    triggerData.textStatus = textStatus;
                    triggerData.errorThrown = errorThrown;

                    var plfEvent = new $.Event("pageloadfailed");

                    // Let listeners know the page load failed.
                    settings.pageContainer.trigger(plfEvent, triggerData);

                    // If the default behavior is prevented, stop here!
                    // Note that it is the responsibility of the listener/handler
                    // that called preventDefault(), to resolve/reject the
                    // deferred object within the triggerData.
                    if (plfEvent.isDefaultPrevented()) {
                        return;
                    }

                    // Remove loading message.
                    if (settings.showLoadMsg) {

                        // Remove loading message.
                        hideMsg();

                        //show error message
                        $("<div class='ui-loader ui-overlay-shadow ui-body-e ui-corner-all'><h1>" + $.mobile.pageLoadErrorMessage + "</h1></div>")
                            .css({ "display": "block", "opacity": 0.96, "top": $window.scrollTop() + 100 })
                            .appendTo(settings.pageContainer)
                            .delay(800)
                            .fadeOut(400, function () {
                                $(this).remove();
                            });
                    }

                    deferred.reject(absUrl, options);
                }
            });
        }

        return deferred.promise();
    };

This is the code for showing an error message "Error Loading Page" for error in page. Here i want to show alert message for net connection failure as "Please check your net connection" instead of the below image.

Error Loading Page

Note: I dont want to change the pageloaderrormessage. want to stop to get the page error messages, instead of that i will enable my network error condition as in Show Network Error in android. If the user pressed "Ok" in alert dialog i'll navigate them into Reload.html.

Please tell me where i can check that condition and where i have to change the error message?

like image 989
Ponmalar Avatar asked Dec 26 '22 22:12

Ponmalar


1 Answers

As both @shkschneider and @codemonkey have suggested you need to set this option on mobileinit

Example:

$(document).bind("mobileinit", function(){
    $.mobile.pageLoadErrorMessage = "Please check your net connection";
});

Linking the jQM 1.0.1 docs:

  • http://jquerymobile.com/demos/1.0.1/docs/api/globalconfig.html

Here is a example:

  • http://jquerymobile.com/demos/1.0.1/docs/config/pageLoadErrorMessage.html ( click the "or Try this broken link" button )

Now if you have the ability to upgrade jQM to 1.1.1 you might try something like this:

//use theme swatch "b", a custom message, and no spinner
$.mobile.showPageLoadingMsg("b", "Please check your net connection", true);

// hide after delay
setTimeout( $.mobile.hidePageLoadingMsg, 1500 );

Docs:

  • http://jquerymobile.com/demos/1.1.1/docs/api/methods.html

UPDATE:

Another thought is to use a plugin to achieve something like you want, Does something like this work?

  • http://dev.jtsage.com/jQM-SimpleDialog/demos/bool.html
like image 55
Phill Pafford Avatar answered Mar 02 '23 21:03

Phill Pafford