Search code examples
javascriptjquerymaterializegrid-layout

How to 'recompute' the width of elements in a Materialize row after dynamically inserting an element?


I'm trying to write a jQuery script which moves an input and its corresponding label outside of its parent div and places if after, in a separate div:

    $("input[id*='-clear_id']").add("label[for*='-clear_id']").wrapAll("<div class='clear-button-wrapper'/>")
    $('.clear-button-wrapper').parent().after($('.clear-button-wrapper'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">

    <!-- Compiled and minified JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
    
  <form>
  <div class="row">
    <div class="file-field input-field col s12">
      <label class="active" for="id_headshot">Headshot</label>
      <div class="btn">
        <span>File</span>
        Currently: <a href="https://lucy-dev2.s3.amazonaws.com/uploads/IMG_3515.png">IMG_3515.png</a>
<input type="checkbox" name="headshot-clear" id="headshot-clear_id" />
<label for="headshot-clear_id">Clear</label><br />
Change:
<input type="file" name="headshot" id="id_headshot" />
        
      </div>
      <div class="file-path-wrapper">
        <input class="file-path validate" type="text">
      </div>
    </div>
  </div>
  </form>

What I notice, however, is that the element after that, the div with the class file-path-wrapper, gets moved down because it no longer fits in the <div class="row"> (note how the underline no longer aligns with the bottom of the button):

enter image description here

I've also seen similar behavior with other content that is dynamically added to Materialize tables. It seems like Materialize computes the width of each element 'upfront', and does not adjust the width to accommodate block elements added dynamically later.

Ideally, I'd like to call something like Materialize.refresh() to recompute the width of the elements with the newly inserted content. Is this possible?


Solution

  • To solve this particular problem, I finally just added the class 'right' to the wrapAll argument. This makes the 'Clear' input float to the right and everything fits on one row again:

        $("input[id*='-clear_id']").add("label[for*='-clear_id']").wrapAll("<div class='clear-button-wrapper right'/>")
        $('.clear-button-wrapper').parent().after($('.clear-button-wrapper'));
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <!-- Compiled and minified CSS -->
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">
    
        <!-- Compiled and minified JavaScript -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
        
      <form>
      <div class="row">
        <div class="file-field input-field col s12">
          <label class="active" for="id_headshot">Headshot</label>
          <div class="btn">
            <span>File</span>
            Currently: <a href="https://lucy-dev2.s3.amazonaws.com/uploads/IMG_3515.png">IMG_3515.png</a>
    <input type="checkbox" name="headshot-clear" id="headshot-clear_id" />
    <label for="headshot-clear_id">Clear</label><br />
    Change:
    <input type="file" name="headshot" id="id_headshot" />
            
          </div>
          <div class="file-path-wrapper">
            <input class="file-path validate" type="text">
          </div>
        </div>
      </div>
      </form>

    Here is how the result looks:

    enter image description here