Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Thursday, April 25, 2024

Html JS - Handle Browser Back Button on SPA

In Single page applications, we will not have dedicated URLs. So on click of Browser Back button it will navigate us to previous page and we lost our current page changes. We can handle this with native JavaScript functions,

Create Html Page as below to mimic SPA, 


On click of each Page button, it can switch the content,




On Each Page navigation we can set the hash URL something like below using history.pushstate or location.hash



Now on click of back button use the hashchange event to detect and open the page accordingly


Here is full code:

<html>

<head>

    <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>

</head>

<body>

    <input type="button" value="Page1" onclick="openPage('1');" />

    <input type="button" value="Page2" onclick="openPage('2');" />

    <input type="button" value="Page3" onclick="openPage('3');" />

 

    <div id="page1" class="page">Page 1 Content</div>

    <div id="page2" class="page">Page 2 Content</div>

    <div id="page3" class="page">Page 3 Content</div>

 

 

    <div id="history"></div>

</body>

 

<script>

    $(document).ready(function () {

        hideAllPages();

     });

 

    $(window).on('popstate', (e) => {

        e.preventDefault();

        var currentLocation = window.location.pathname;

        history.push(currentLocation)

    });

     window.onbeforeunload = function () {

        return "Are you sure you want to leave this page?";

     };

    addEventListener("hashchange", (event) => {

        alert("New" + event.newURL);

        alert("Old" + event.oldURL);

        var currentHash = event.currentTarget.location.hash;

        openPage(currentHash.replace("#", ""), true);

     });

    function hideAllPages() {

        $(".page").hide();

    }

    function openPage(pageId, ignoreHistoryPush = false) {

        hideAllPages();

        $("#page" + pageId).show();

        if (!ignoreHistoryPush)  //This is to not add history on everytime

            history.pushState({ page: pageId }, pageId, '#' + pageId);
            //
location.hash = pageId  //This way also can set it

    }

 

 

</script>

</html>


Wednesday, December 6, 2023

Html - Render Html Dynamically into Frame without Hosting and Communicate from Parent

 In case we want to render Html dynamically into website as frame without hosting the Html into another website, we can use of this code Blob with createObjectURL to render dynamically,


Create Parent Website as below:

<html>

<head>

<script>

// This function will update the iframe src with the HTML code from the textarea

function renderHTML() {

   // Get the textarea element by its id

  var textarea = document.getElementById("html-code");

  // Get the iframe element by its id

  var iframe = document.getElementById("html-frame");

  // Create a blob object from the textarea value

  var blob = new Blob([textarea.value], {type: "text/html"});

  // Create a URL object from the blob object

  var url = URL.createObjectURL(blob);

  // Set the iframe src to the URL object

  iframe.src = url;

}

 

function postIframe(){

 var iframe = document.getElementById("html-frame");

 iframe.contentWindow.postMessage("Hi, Message From Parent Website", '*');

}

  </script>

</head>

<body>

  <h1>HTML Editor</h1>

  <p>Enter some HTML code in the textarea below and click the button to render it in the iframe.</p>

<textarea id="html-code" rows="10" cols="50">

        <h2>Hello World</h2>

        <p>This is a simple HTML document.</p>

</textarea>


<br>

<button onclick="renderHTML()">Render HTML</button>

<br>

<iframe id="html-frame" width="500" height="300"></iframe>

<br />

<button onclick="postIframe()">Post Iframe</button>

</body>

</html>


In case we want to communicate with iFrame, we can use of postMessage, for that we can add the following code into Html of iFrame

iFrame Html Content as below:


<!DOCTYPE html>

<html>

<head>

  <title>Page Title</title>

</head>

<body>

  <h1>This is a Heading</h1>

  <p>This is a paragraph.</p>

  <script type="text/javaScript">

     function addListener() {

       window.addEventListener('message', event => {

        // IMPORTANT: check the origin of the data!

        //if (event.origin === 'https://your-parent-site-url') {

        // The data was sent from your site.

        // Data sent with postMessage is stored in event.data:

        alert(event.data);

        //} else {

        // The data was NOT sent from your site!

        // Be careful! Do not use it. This else branch is

        // here just for clarity, you usually shouldn't need it.

        return;

        //}

      });

     }

    addListener();

   </script>

<div> Footer Content</div>

</body>

</html>

Friday, July 21, 2023

How to get previous page details in page change event on embedded PowerBI report

In Power Bi, there is challenge to get page details when changing the pages. In Angular/JavaScript, powerBI client provides event handling to manage this. For this page changes, we have "pageChanged" event. Below sample code will help us to get events on page changes, so that you can capture bookmark if needed on previous page names etc.,


Sample Code: 

import { service, factories } from "powerbi-client";
const powerBI= new service.Service(factories.hpmFactory, factories.wpmpFactory, factories.routerFactory);

....

let currentSelectedPage = any = null;
let pbiElement = document.getElementById(“yourdivid”);
let pbiconfig = : any = {
    type: 'report',
    hostName: "https://app.powerbi.com/",
    accessToken: "",
    embedUrl: "",
    id: "",
    settings: {
      filterPaneEnabled: false,
      navContentPaneEnabled: false
    }
  }

this.report =  powerBI.embed(pbiElement, pbiconfig);

this.report.on('pageChanged', (event) => {
      
     console.log('Page changed Old:', event.detail.oldPage);
    
    //If event.detail.oldPage is not working then go with custom logic 
    //if (this.currentSelectedPage)
    //console.log('Page changed Old:', this.currentSelectedPage.displayName);  
    //set changed page into existing variables
    //this.currentSelectedPage = event.detail.newPage;

      console.log('Page changed New:', this.currentSelectedPage.displayName);
});

Monday, September 13, 2021

Browser - Change Current Geo Location

In order to test different Geo Location in browser, we have option to change location in browser. Follow below steps,

Browsers used: Chrome, IE Edge

  1. Go to Developer Tools (Click F12)
  2. Click ... Settings Icon -> More Tools -> Sensors
  3. Now in Sensors Window, Change the location as needed. You can also manage for new locations.




Tuesday, March 7, 2017

JavaScript - Simple Export to excel

To export excel in JavaScript without any server side techiques, we can use following steps

Used blob file saver for download https://github.com/eligrey/FileSaver.js

Step 1: Create Html Content with required styles as below

var tableHtml = '<html xmlns:x="urn:schemas-microsoft-com:office:excel">';
        tableHtml += '<head><xml><x:ExcelWorkbook><x:ExcelWorksheets>';
        tableHtml += '<x:ExcelWorksheet><x:Name>PlanFundLineup</x:Name>';
        tableHtml += '<x:WorksheetOptions><x:Panes></x:Panes></x:WorksheetOptions></x:ExcelWorksheet>';
        tableHtml += '</x:ExcelWorksheets></x:ExcelWorkbook></xml></head><body>';
  tableHtml += "<div><table  border='1'>" +
        tableHtml += "<thead>" +
        tableHtml += "<tr><th>" +
        tableHtml += "Header Text" +
        tableHtml += "</th></tr>" +
 tableHtml += "</thead>" +
               "<tbody>" +
        tableHtml += "<tr><td>" +
        tableHtml += "Content Text" +
        tableHtml += "</td></tr>" +
               "</tbody>" +
              "</table></div>";
        tableHtml += '</body></html>';

Step 2: Download this html content using blob

var blob = new Blob([tableHtml], { type: "application/vnd.ms-excel;charset=utf-8" })
window.saveAs(blob, "excelname.xls");


Wednesday, November 9, 2016

AngularJS - JavaScript - Client Side error logging

Usually for ServerSide logging we can use many error logging tools (For ex: elmah, log4net etc.,) to log errors into database and email. But for client side JavaScript framework we should include some extra code or some tools available (for ex: JSNLog etc.,). Here am going to explain how custom we do that,

First create JavaScript file "errorlog.js" and copy paste below code,

var errorLoggingServerURL = "Error/Log";

function logErrorToServer(ex, stack) {
    if (ex == null) return;

    if (stack == null && ex.stack != null) stack = ex.stack;

    // format output
    var out = ex.message != null ? ex.name + ": " + ex.message : "JavaScript Exception";
    if (stack != null) out += "\n  at " + stack.toString();

   
    // send error message
    $.ajax({
        type: 'POST',
        url: errorLoggingServerURL,
        data: { message: escape(out) }
    });

}

Function.prototype.trace = function () {
    var trace = [];
    var current = this;
    while (current) {
        trace.push(current.signature());
        current = current.caller;
    }
    return trace;
}

Function.prototype.signature = function () {
    var signature = {
        name: this.getName(),
        params: [],
        toString: function () {
            var params = this.params.length > 0 ?
                "'" + this.params.join("', '") + "'" : "";
            return this.name + "(" + params + ")"
        }
    };
    if (this.arguments) {
        for (var x = 0; x < this.arguments.length; x++)
            signature.params.push(this.arguments[x]);
    }
    return signature;
}

Function.prototype.getName = function () {
    if (this.name)
        return this.name;
    var definition = this.toString().split("\n")[0];
    var exp = /^function ([^\s(]+).+/;
    if (exp.test(definition))
        return definition.split("\n")[0].replace(exp, "$1") || "anonymous";
    return "anonymous";
}

window.onerror = function (msg, url, line) {
    if (arguments != null && arguments.callee != null && arguments.callee.trace)
        logErrorToServer(msg, arguments.callee.trace());

}


In AngularJS, we can have custom logging as follows,

To override AngularJS default logging and to write custom logging use as below,

 app.factory('$exceptionHandler', function () {
        return function (exception, cause) {
            //Javascript Error log will catch this
            logErrorToServer(exception);
        };
    })

Or to use both angularJS default logging and custom logging use as below

//Exception log decorator
 $provide.decorator('$exceptionHandler', ['$delegate', function ($delegate) {
    return function (exception, cause) {
     $delegate(exception, cause);
     logErrorToServer(exception);
    };
 }]);



In Server Side, we can receive the Ajax call and use any logging tool to log error, For ex, here am using Elmah to log error, it uses MVC action controller and using logging as custom class named JavaScriptException

public class ErrorController : Controller
    {
public void Log(string message)
        {
            ErrorSignal
                .FromCurrentContext()
                .Raise(new JavaScriptException(HttpUtility.UrlDecode(message)));
     }

   }