0

It's the first time I'm using jQuery and I need your help because I don't overcome to make what I want.

I have a table of documents with a checkbox for each document in order to select it or not.

I have also a field in which one users set a new year in order to modify filename after.

I have this process :

  1. By default, submit button is disabled
  2. To activate the submit button, user have to check one checkbox AND write the new year
  3. Once the step 2 is done, if I remove year OR uncheck the checkbox, submit button have to be disabled

This is my javascript part (don't forget, it's my first time) :

<script type="application/javascript">

$(document).ready(function(){
    $('#DocumentButton').attr('disabled',true);
    $('#year').keyup(function(){
        // if field year is not empty and checkbox is checked
        if($(this).val().length !=0 && $('.fakeRadio').is(':checked'))
            $('#DocumentButton').attr('disabled', false);
        // if field year is empty or checkbox isn't checked
        else if ($(this).val().length =0 || $('.fakeRadio').is(':checked')==false)
            $('#DocumentButton').attr('disabled',true);
    })
});

   // Simulate Checkbox as Radiobox
   $(document).ready(function(){
      $(".fakeRadio").click(function(){
      var wasChecked = !$(this).prop("checked");
      $(".fakeRadio").prop( "checked", false );
      $(this).prop("checked", (!wasChecked) ? true : false );
      });
    });

  </script>

And the according HTML part :

<div class="col-md-offset-1 col-md-5">
  <h4> {% trans "List of documents:" %} </h4>
  <form action="" method="POST"> {% csrf_token %}
    <table id="DocumentTable" class="table table-bordered table-striped table-condensed table_model"
           style="width: 160%;">
      <thead>
      <tr>
        <th style="width: 10%;">Choice</th>
        <th>Document title</th>
      </tr>
      </thead>
      <tbody>
      {% for document in query_document %}
        <tr>
          <td><input type="checkbox" class="fakeRadio" id="DocumentCheckBox" name="DocumentChoice" value="{{ document.id }}"></td>
          <td>{{ document.title }}</td>
        </tr>
      {% endfor %}
      </tbody>
    </table>

    <input type="text" id="year" name="q1year" placeholder="Set new year" value="{{ request.get.q1year }}">
    <button class="btn btn-default" id="DocumentButton" type="submit" name="UpdateDocument">{% trans "Submit" %}</button>
  </form>
</div>

Up to now, the process works fine with step 1 and 2, but not if I uncheck the checkbox.

Could you help me and explain what is false in my code ?

5 Answers 5

1

HTML5 validation can do this for you. No need for JavaScript. Just add the required attribute to the element.

<form>
  <label>

  <label for="name">name</label><input id="name" required />
  <br/>
  <input type="checkbox" required name="terms"> I accept the Terms and Conditions
  </label>
  <br/>

  <input type="submit">
</form>

But if you want to do it with JavaScript than you can make one method that does both checks. It is easier to just do all the checks in one method than trying to figure out how to do separate checks for each input.

function checkValid () {
  var cbChecked = $("#cb").is(":checked");  // check if checked
  var hasText = $("#name").val().length > 0;  // check if it has text
  
  $("#btnSubmit").prop("disabled", !cbChecked || !hasText);
}

$( function () {
  checkValid(); // run it for the first time
  $("#cb").on("change", checkValid);  // bind checkbox
  $("#name").on("input", checkValid)  // bind textbox
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <label>

  <label for="name">name</label><input id="name" />
  <br/>
  <input id="cb" type="checkbox" name="terms"> I accept the Terms and Conditions
  </label>
  <br/>

  <input type="submit" id="btnSubmit">
</form>

If you have more than on e checkbox and only one is required, than you need to use JavaScript

function checkValid () {
  var cbChecked = $(".cb:checked").length > 0;  // check if at least one checked
  var hasText = $("#name").val().length > 0;  // check if it has text
  
  $("#btnSubmit").prop("disabled", !cbChecked || !hasText);
}

$( function () {
  checkValid(); // run it for the first time
  $(".cb").on("change", checkValid);  // bind checkboxesvia classname
  $("#name").on("input", checkValid)  // bind textbox
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <label>

  <label for="name">name</label><input id="name" />
  <br/>
  <label>
  <input class="cb" type="checkbox" name="terms"> One
  </label>
  <label>
  <input class="cb" type="checkbox" name="terms"> Two
  </label>
  <label>
  <input class="cb" type="checkbox" name="terms"> Three
  </label>
  <br/>

  <input type="submit" id="btnSubmit">
</form>

Sign up to request clarification or add additional context in comments.

2 Comments

I tried your solution but I have to check all checkboxes, else I can't submit if I have just one checkbox and my year field.
The javascript part makes the job fine and I understand pretty well your code with comments ! Thank you :)
1

Try this:

$(function(){

  function Op(){
     if($("table :checked")[0] && $("#year").val())
             $("#DocumentButton").removeAttr("disabled");
     else $("#DocumentButton").attr("disabled", "");
  };

  $("table").on("change", ":checkbox", Op);
  $("#year").on("input", Op);

  Op(); 
});

check it online


You can write op function even shorter:

$(function(){
    function Op(){
       $("#DocumentButton").prop("disabled", !($("table :checked")[0] && $("#year").val()));
    };
    $("table").on("change", ":checkbox", Op);
    $("#year").on("input", Op);

    Op(); 
});

Try this live!

Tip: you can do all things (validation or not) in js. i use this way in my projects always, and all things is very fine and manageable. also works in all browser versions.

1 Comment

H! The last answer that @epascarello has added (his js solution) (after you accept my code!), is exactly similar my script but with another names and using prop function instead of toggle attribute!. Anyway, it is important that your problem is resolved :)
0

You are pretty close, try this:

$(document).ready(function(){
    $('#year').keyup(function(){
        if($(this).val().length > 0)
            if($('.fakeRadio:checked').length() > 0){
                 $('#DocumentButton').attr('disabled', false);
            }
        } else {
            $('#DocumentButton').attr('disabled', true);
        }
    });

    $('.fakeRadio').on('change', function(){
        var checked = $('.fakeRadio:checked').length();
        if(checked > 0 && $('#year').val().length > 0){
            $('#DocumentButton').attr('disabled', false);
        } else {
            $('#DocumentButton').attr('disabled', true);
        }
    });
});

1 Comment

I tried but it doesn't work and I don't know why. It makes exactly the same thing than my code.
0

The problem is you check the validity and disable or disable the button only in the input keyup event, and not in the click event of the checkbox.

You should put the validity check code in a function, and call it in both of the events -

$(document).ready(function(){
    $('#DocumentButton').attr('disabled',true);
    $('#year').keyup(function(){
        checkValidity();
    })
});

// Simulate Checkbox as Radiobox
$(document).ready(function(){
   $(".fakeRadio").click(function(){
      var wasChecked = !$(this).prop("checked");
      $(".fakeRadio").prop( "checked", false );
      $(this).prop("checked", (!wasChecked) ? true : false );

      checkValidity();
   });
});

function checkValidity() {
  // if field year is not empty and checkbox is checked
  if($('#year').val().length !=0 && $('.fakeRadio').is(':checked'))
      $('#DocumentButton').attr('disabled', false);
  // if field year is empty or checkbox isn't checked
  else if ($('#year').val().length =0 || $('.fakeRadio').is(':checked')==false)
      $('#DocumentButton').attr('disabled',true);
}

BTW, there's no need for 2 different document.ready call. You can put all your code in the same one.

2 Comments

It doesn't work because if I have checkbox check and year in my field and I remove just year, submit button is still enabled and it shouldn't be (step 3 in my question) ;)
That shouldn't happen because you still check the validity after every keyup of the input.
0

In initial load of the page submit button will be disabled, If user click checkbox (or) enter some value in input field then button disable will remove

   $(document).ready(function(){
      inputType();
      checkbox();
      $('#DocumentButton').attr('disabled',true); //Initial load of the page submit button will be disabled
    });

function inputType(){
        if($("#year").val() == ''){
           $('#DocumentButton').attr('disabled',true);
        }else{
           $('#DocumentButton').attr('disabled',false);
        }         
 }

function checkbox(){
    $('.fakeRadio').each(function () {
        if ($(this).prop('checked')==true){ 
           $('#DocumentButton').attr('disabled', false);
        }else{
           $('#DocumentButton').attr('disabled', true);
        }
    });
}

Instead of that write a onclick and onkeyup function for both input field and checkbox

  <td><input type="checkbox" onclick="checkbox()" class="fakeRadio" id="DocumentCheckBox" name="DocumentChoice" value="{{ document.id }}"></td>

 <input type="text" onkeyup="inputType()" id="year" name="q1year" placeholder="Set new year" value="{{ request.get.q1year }}">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.