1

I am trying to get the page to focus on an empty element, if its within a collapsed div it will then open that element and focus on the required field which was empty. I am using bootstrap for the collapse functionality.

At the moment if the form is attempted to be submitted and there is an empty required field it wont submit but there is nothing to state why.

I am unsure on how to open a collapsed element and focus the required field if it was empty when the form was attempted to be submitted.

The JavaScript in the snippet is for JQuery UI accordion where as am trying to get it to work for bootstrap collapse functionality.

JSFiddle

Below is the html & CSS

// save the accordion in a variable as you'll need it later
$collaspe = $("#accordion");

// when the submit is clicked
$("#formwrite input[type='submit']").on("click", function(event) {

  // traverse all the required elements looking for an empty one
  $("#formwrite input[required='required']").each(function() {

    // if the value is empty, that means that is invalid
    if ($(this).val() == "") {

      // find the index of the closest h3 (divide by 2 because jQuery UI accordion goes in pairs h3-div. A bit hacky, sorry)
      var item = $(this).closest(".ui-accordion-content").prev().index() / 2;

      // open that accordion section that contains the required field
      $collaspe.accordion("option", "active", item);

      // stop scrolling through the required elements
      return false;
    }
  });
});
.container {
  width: 75%;
}
.panel-heading {
  background-color: #D9DBDE;
  padding: 20px;
  margin-bottom: 10px;
  border-radius: 0;
}
.panel-title {
  font-size: 21px;
  display: block;
  width: 100%;
  color: #4F5858;
  line-height: 1.3;
  font-weight: normal;
}
.collapse-icon {
  float: right;
}
.fieldpos {
  margin-left: 0px;
  width: 60%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>


<body>
  <form action="/update" id="formwrite">
    <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
      <div class="panel">
        <div class="panel-heading" role="tab" id="headingOne">
          <h4 class="panel-title va-middle">Account Settings
      <img src='../images/colopen.svg' data-swap='../images/coll.svg' class="panel-icon collapse-icon" role="button" data-toggle="collapse" data-parent="#accordion" href="#collaspeOne" aria-expanded="true" aria-controls="collaspeOne">
      </h4>
        </div>
        <div id="collaspeOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
          <div class="panel panel-default">
            <div class="row fieldpos">
              <fieldset class="form-group textwide">
                <label for="email">Email</label>
                <input type="email" class="form-control" id="email" placeholder="Enter Email" required>
              </fieldset>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="panel">
      <div class="panel-heading" role="tab" id="headingTwo">
        <h4 class="panel-title va-middle">Other Settings
        <img src='../images/colopen.svg' data-swap='../images/coll.svg' class="panel-icon collapse-icon" role="button" data-toggle="collapse" data-parent="#accordion" href="#collaspeTwo" aria-expanded="true" aria-controls="collaspeTwo">
        </h4>
      </div>
      <div id="collaspeTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
        <div class="panel panel-default">
          <div class="row fieldpos">
            <fieldset class="form-group textwide">
              <label for="group">Test</label>
              <input type="text" class="form-control" id="group" placeholder="test" required>
            </fieldset>
          </div>
        </div>
      </div>
    </div>
    <button type="submit" class="btn btn-success form-control savechanges">Save Changes</button>
  </form>
</body>

Any suggestions on how I could do this, I have read a few other questions like my own such as this where I have tried the JS in my own,but have been able to get it working as needed.

Community
  • 1
  • 1
Studento919
  • 625
  • 2
  • 15
  • 44
  • Have you done some coding with respect to `javascript` ? Post it – Vikrant Sep 26 '16 at 11:45
  • 1
    there are `.panel` elements inside other `.panel` elements. Is this a mistake? – Evochrome Sep 26 '16 at 11:49
  • @Vikrant Posted now, I have attempted to use the code of the other question I linked in my own, but keep getting errors to try and at least get something along the lines of what i need. – Studento919 Sep 26 '16 at 11:59
  • @Evochrome Not as far as am aware? – Studento919 Sep 26 '16 at 12:00
  • 1
    First, before asking a question, eliminate all the obvious errors that are - probably - irrelevant to the question. For example there are a number of errors reported in the console which need to be solved before we can even start on the question you're presenting. Also, reduce your code to the absolute minimum amount required to demonstrate your problem (see: "*[MCVE]*" for guidance on this). – David Thomas Sep 26 '16 at 12:01
  • @Studento919 there are, More settings(2x) are inside Other Other Settings. Also, JSFiddle indicates your HTML is not quite correct. Please fix this. I think I might have a solution for you in store :p – Evochrome Sep 26 '16 at 12:20
  • @Evochrome Updated the fiddle, still working on tidying up the JS error. – Studento919 Sep 26 '16 at 12:27

2 Answers2

2

Add a listener to your inputs for them being invalid, then tell the parent container to open.

var inputs = document.querySelectorAll('form div input');

[].forEach.call(inputs, function(input) {
  input.addEventListener('invalid',function(e){
    input.parentNode.style.display = 'block'
  });
});
div {
  display: none;
}
<form>
  <div>
    <input name="one" type="text" required />
  </div>
  <div>
    <input name="two" type="text" required />
  </div>
  <input type="submit" value="submit" />
</form>
Jamie Barker
  • 8,145
  • 3
  • 29
  • 64
  • Tried adding a trigger event and keep getting the following error: An `invalid form control with name='' is not focusable.` E.G `$(this).closest(".collapse-icon").trigger("click");` within the invalid event listener. – Studento919 Sep 26 '16 at 13:46
0

Why not use some good ol' coding yourself ;)

I've updated the css and added some JS. I hope it fits your needs.

CSS:

.panel-collapse {
  margin-top: 20px;
  max-height: 200px;
  -webkit-transition: all 0.6s ease-in-out;
  -moz-transition: all 0.6s ease-in-out;
  -o-transition: all 0.6s ease-in-out;
  transition: all 0.6s ease-in-out;
  overflow-y: hidden;
  display: block;
}

.collapse {
  max-height:0;
  display:block;
  margin: 0 !important;
}

JS:

$(document).ready(function(){
    var validated = false,
        inputC = 0,
        that;
  jQuery.fn.extend({
    valVal: function() {
      return $(this).each(function() {
        var input = $(this);
        inputC++;
        if(!$.trim(input.val())){
            input.closest(".collapse").removeClass("collapse");
        }
      });
    }
  });

    $(".savechanges").on("click", function(){
    that = $(this);
    console.log(that.parent());
    inputC = 0;
    $(".panel-collapse").addClass("collapse");
    that.parent().parent().find("input").valVal();
    var collapse = $(".collapse");
    if(collapse.length==inputC){
        validated = true;
      console.log("yess");
      //Do an AJAX request to server.
    }else{
      console.log("not quite correct yet..");
      //Just for the sample, has no use (yet) in this piece of code
    }

  })
    $(".panel-heading").on("click", function(){
    that = $(this);
    that.parent().find(".panel-collapse").toggleClass("collapse");
    that.parent().find("input").focus();
  })
})

And here is a working JSFiddle

Good luck!

Evochrome
  • 1,205
  • 1
  • 7
  • 20