YvesC
YvesC

Reputation: 23

Fail to initialize when changing inner html (google app script)

(original question)

I'm now trying to develop a web app through App Script using Materialize layout and components.

As I wanted to create a nav-bar that contains different page buttons (which should change the body part of the site), I found the elements within each site are not working well. I tried to create routes of sites using doGet(e) and some if-else arguments, which works just fine, but that renders a whole new page instead of keeping the nav-bar above still. I'm wondering if there's a way to do so... (I'm guessing it's the way I change innerHTML being wrong.)

As for now, the main page shows normal. However, when I click the "A" button on the nav-bar (and it shows a date picker below), it's now popping a picker as it supposed to.

(0327 Update)

I'm sorry for any misleading of my question. I tried to simplify my question below with the updated code that contains only my situations here.

The page below is a mainPage that contains a "datePicker1" element, and when I click the "Page A" button above, a new "datePicker2" is written into the DOM content. However, "dP1" works well, which pops its calendar as it supposed to, but "dP2" is not. :(

(P.S. I think I was not clear enough: for the "nav-bar" mentioned before, I was hoping it works as a header in an HTML.)

Here's my code (updated):

(mainPage.html)

<!DOCTYPE html>
<html language="en">
  <head>
    <base target="_top">
    <title>Title</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" >
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </head>
    
  <body>
    <!-- navbar -->
    <header>
      <div class="navbar-fixed">
        <nav>
          <div class="nav-wrapper teal darken-4">
            <div class="row">
              <div class="col s10 offset-s1">
                <div class="brand-logo">Logo</div>
                <ul id="nav-mobile" class="right hide-on-med-and-down">
                  <li><a onClick="pageSelect(0);">Page A</a></li>
                  <li><a onClick="pageSelect(1);">Page B</a></li>
                  <li><a onClick="pageSelect(2);">Page C</a></li>
                </ul>
              </div>
            </div>
          </div>
        </nav>
      </div>
    </header>
    
    <section>
      <div class="container">
        Dateinput 1:
        <div class="input-field">
          <label for="dateinput1">Dateinput 1</label>
          <input id="dateinput1" type="text" class="datepicker">
        </div><br>
        Dateinput2:
        <div id="pageContent">
        </div>
      </div>
    </section>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script> 
    <script>
      $(document).ready(function(){
        $('.datepicker').datepicker();
      });
    </script>
    <script>
      function changeContent(content){
        document.getElementById("pageContent").innerHTML = content;
      }
      function pageSelect(index){
        google.script.run.withSuccessHandler(changeContent).getPage(index);
      }
    </script>
  </body>
</html>

(pageA.html)

<div class="input-field">
  <label for="dateinput2">Dateinput 2</label>
  <input id="dateinput2" type="text" class="datepicker">
</div>

(backend.gs)

var mainPage = HtmlService.createTemplateFromFile("mainPage");

function doGet() {
  return mainPage.evaluate()
  .setTitle("mainPage")
  .setSandboxMode(HtmlService.SandboxMode.IFRAME)
  .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

function getPage(index){
  let pageName;
  switch(index){
    case 0: pageName = "pageA"; break;
    case 1: pageName = "pageB"; break;
    case 2: pageName = "pageC"; break;
  }
  return HtmlService.createHtmlOutputFromFile(pageName).getContent();
}

I've tried to solve this on my own and been searching, still not getting any further... Hope I'm making myself clear, thanks a lot!

Upvotes: 2

Views: 421

Answers (1)

Nikko J.
Nikko J.

Reputation: 5543

If you check the elements of your web app to your browser, you can see in dateinput1 that there is appended modal and the injected date picker(dateinput2) does not have. During the build process, if the materialize.js found a datepicker class in your html, it will append the datepicker-modal class that shows the date picker when the text box is clicked.

But since your script injected the dateinput2 after the build process, it wont get the datepicker-modal. This causes your script not to show the datepicker.

Alternative solution is include the dateinput2 in your main html file and use the style property display to hide and show the date picker box. By this, we can ensure that the dateinput2 has modal for showing the datepicker.

enter image description here

Reference:

Upvotes: 1

Related Questions