Form Onclick with Required field? - javascript

I have currently a form which has the below code, the issue is that when a user presses the form submit button even if not checking the required field the onclick call is still triggered, how can I make it so that you HAVE to fulfill the required field before getting a trigger?
<form method="post">
<div class="form-group">
<select id="inputState" class="form-control" style="width: 100%">
<option>10,000 credits</option>
<option>25,000 credits</option>
<option>50,000 credits</option>
<option>75,000 credits</option>
<option>100,000 credits</option>
</select>
</div>
<div class="text-center">
<div class="row justify-content-center mb-2">
<div class="col-12 col-md-8 text-center">
<p class="mb-0 small text-muted"><strong>Promotion Disclaimer</strong>
<br>You will be required to install a free mobile app from our sponsors to receive your Coins for free. This process only takes a minute or two and you can remove the app once you're finished.</p>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1" required>
<label class="form-check-label" for="defaultCheck1">
I agree to Promotion Disclaimer
</label>
</div>
<br>
<button class="btn btn-primary btn-sm btn-continue" data-step="3" onclick="call_locker();">Continue</button>
</div>
</form>

Using the form onsubmit event, move your call_locker call into the form element. This is called when there is a submit event. You can trigger said event by default on your button click. To prevent the refreshing of the page, you can either add event.preventDefault() or returning false from the function. Here I have a mock function of call_locker which returns false.
<script>
call_locker = () => { console.log('called locker'); return false; }
</script>
<form method="post" onsubmit="return call_locker();">
<div class="form-group">
<select id="inputState" class="form-control" style="width: 100%">
<option>10,000 credits</option>
<option>25,000 credits</option>
<option>50,000 credits</option>
<option>75,000 credits</option>
<option>100,000 credits</option>
</select>
</div>
<div class="text-center">
<div class="row justify-content-center mb-2">
<div class="col-12 col-md-8 text-center">
<p class="mb-0 small text-muted"><strong>Promotion Disclaimer</strong>
<br>You will be required to install a free mobile app from our sponsors to receive your Coins for free. This process only takes a minute or two and you can remove the app once you're finished.</p>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1" required>
<label class="form-check-label" for="defaultCheck1">
I agree to Promotion Disclaimer
</label>
</div>
<br>
<button class="btn btn-primary btn-sm btn-continue" data-step="3">Continue</button>
</div>
</form>

There is a simple solution to your issue.
Instead of using the onclick event, you can use the onsubmit event, which will not call the function unless the form is submitted.
The browser will not submit the form if elements with the required attribute are not filled out, so the function will not be called if you are using the onsubmit event until the required fields are filled out.
onclick="call_locker();" should become onsubmit="call_locker();"

There is another way to solve your problem.
if you want to make it so that the browser won't refresh itself (and therefore submit the form) whenever you click on the submit button and your fields are not fulfilled, you can make your javascript code do it by preventing the default of the submit key which is refreshing the browser whenever it is pressed.
Javascript Example
call_locker(event)
{
if (document.getElementById().value === undefined &&
document.getElementById(defaultCheck1).value === undefined)
{
event.preventDefault();
}
}

Related

Bootstrap validation with JavaScript - disable submission with invalid fields

I have the following HTML code:
<form class="row g-3 needs-validation" novalidate>
<div class="col-md-4">
<label for="validationCustom01" class="form-label">First name</label>
<input type="text" class="form-control" id="validationCustom01" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationCustom02" class="form-label">Last name</label>
<input type="text" class="form-control" id="validationCustom02" value="Otto" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationCustomUsername" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">#</span>
<input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
<div class="col-md-6">
<label for="validationCustom03" class="form-label">City</label>
<input type="text" class="form-control" id="validationCustom03" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
</div>
<div class="col-md-3">
<label for="validationCustom04" class="form-label">State</label>
<select class="form-select" id="validationCustom04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-feedback">
Please select a valid state.
</div>
</div>
<div class="col-md-3">
<label for="validationCustom05" class="form-label">Zip</label>
<input type="text" class="form-control" id="validationCustom05" required>
<div class="invalid-feedback">
Please provide a valid zip.
</div>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
<label class="form-check-label" for="invalidCheck">
Agree to terms and conditions
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
With the following JavaScript code, to validate the user input. If there are any invalid fields, it should the user stop submitting his request:
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
// putting alert here does not work..?
// something like alert('successfully validated your request!')
}, false)
})
})()
The problem is: I want to alert the user, if the submission was successfully, with the alert() function. But I can't figure out where to put the alert function. I marked the code where I tried putting the alert function into, but it's always triggering even when it's not even validated. Does somebody know what am I doing wrong here? Thank you very much.

JQuery .append() content won't stay on screen

I'm creating a form where the user can add their modules that they study at university. When they click the button, it adds a new set of fields for another module. I've added a click listener to the button #add and I'm trying to append the form #input_form with the same fields:
<form id="input_form">
<h6>Add modules below...</h6>
<div class="form-row">
<div class="col-md-6">
<input type="text" class="form-control" name="module_name" placeholder="Module Name">
</div>
<div class="col-md-6">
<input type="text" class="form-control" name="module_code" placeholder="Module Code">
</div>
</div>
<div class="form-group col-md-6">
<label for="credit_entry"># of Credits: </label>
<input type="number" name="credits" id="credit_entry">
</div>
<div class="form-group col-md-6">
<label for="colour_selector">(Optional) Choose a Colour: </label>
<select id="colour_selector" name="colour_select">
<option value="blue">Blue</option> <!-- Default -->
<option value="red">Red</option>
<option value="yellow">Yellow</option>
<option value="pink">Pink</option>
<option value="black">Black</option>
</select>
</div>
</div>
<div class="row">
<button name="add" id="add" class="btn btn-secondary">Add Another</button>
</div>
// Add fields dynamically
$("#add").click(function() {
$("#input_form").append("<h1>The fields will go here</h1>");
});
When I click the button, I see the content (the h1) added for a split second but then it disappears. I am not sure why the appended HTML won't stay on screen. I have another part of this project which works similarly and appends to a ul list and the HTML is persisting on screen for that just fine, but for some reason this won't.
I'm pretty new to web design and jQuery so sorry if there's an easy answer that I'm missing.
"If the element has a form owner, the element must submit the form owner from the button element." (w3.org)
That means, any button inside a form executes submit() on its parent form.
To prevent that, explicitly define the button type as button:
<button name="add" type="button" id="add" class="btn btn-secondary">Add Another</button>
In action:
https://codepen.io/akamichael/pen/NWqgaWz?editors=1010

How to set drop down value as blank using Angular.js

I need one help.I need to set drop down value as blank after finishing one action using Angular.js.I am explaining my code below.
<div style="height:270px; overflow-x:hidden; overflow-y:scroll;" ng-show="viewOrderTable">
<div class="table-responsive dashboard-demo-table">
<select class="form-control" id="status" ng-model="order_status" ng-change="changeOrderStatus(order_id,shipping_email,p.pro_data_id,order_status,p.days)">
<option value="">Select Status</option>
<option value="In-progress">IN-PROGRESS</option>
<option value="Dispatch">DISPATCH</option>
<option value="Delivered">DELIVERED</option>
<option value="canceled" ng-if="p.pro_status =='Ordered' && p.pro_status=='In-progress'">CANCELED</option>
<option value="Returned" ng-if="p.days <= 48 && p.pro_status=='Delivered'">RETURN</option>
</select>
</div>
</div>
from the above list when user is selecting DISPATCH the below form is opening.
<div class="" ng-show="viewDispatch">
<div style="padding-bottom:20px;">
<div class="col-md-6">
<div class="input-group bmargindiv1 col-md-12">
<span class="input-group-addon ndrftextwidth" style="width:120px; text-align:left;">Dispatched Date& Time :</span>
<div class="datepicker" date-format="dd-MM-y h:mm:ss" button-prev='<i class="fa fa-arrow-circle-left"></i>' button-next='<i class="fa fa-arrow-circle-right"></i>'>
<input type="text" name="dispatch_date" class="form-control" id="dispatch_date" ng-model="dispatch_date" placeholder="Add Dispatched Date& Time" ng-change="clearField('dispatch_date');" />
</div>
</div>
</div>
<div class="clear"></div>
</div>
<div class="col-md-12 text-right">
<button type="button" class="btn btn-success" ng-click="addDispatchData();">Submit</button> <button type="button" class="btn btn-danger" ng-click="clearDispatchData();">Back</button>
</div>
</div>
</div>
The controller side code for this action is given below.
$scope.changeOrderStatus=function(orderid,email,prodataid,order_status,hour){
if(order_status=='Dispatch'){
$scope.viewOrderTable=false;
$scope.viewDispatch=true;
pro_dataId=prodataid;
order_Id=orderid;
dStatus=order_status;
email=email;
}
}
When user is clicking on back button its again coming to its original state but drop down DISPATCH option is displaying where i need to reset the drop down list again.
$scope.clearDispatchData=function(){
$scope.viewOrderTable=true;
$scope.viewDispatch=false;
$scope.order_status='';
}
I did like above but its not resetting .Please help me to resolve this issue.
You can use ng-init for this in your html file
<select class="form-control" id="status" ng-model="order_status" ng-change="changeOrderStatus(order_id,shipping_email,p.pro_data_id,order_status,p.days)" ng-init='order_status == 0'>
May be digest issue you can try using $timeout so you should inject $timeout in your controller before use.
$scope.clearDispatchData=function(){
$timeout(function() {
$scope.viewOrderTable=true;
$scope.viewDispatch=false;
$scope.order_status='';
});
}

Show Added Values on same page before submitting in form with multiple entry

I would like to add functionality to my existing form.So far my form allows only entries on per submit bases, meaning is if the user wants to add another entry, he/she has to go back to the form and add and click to submit again.I would like to show all added values on same page, cause I am planning to add a Javascript print function that will print the add entries before saving to database.I need all values in fields to be printed
<form method="POST" name="myForm" action="saveto.php">
<label> Speed Rating:</label>
<select name="speed_rating" required class="form-control" id="speed_rating" ></select>
<div class="form-group col-sm-8">
<label> Description:</label>
<select name="description" required class="form-control" id="description" >
</select>
</div>
<div class="form-group col-sm-4">
<label> Load Index:</label>
<select name="load_index" required class="form-control" id="load_index" >
</select>
</div>
<div class="form-group col-sm-6">
<label> Vendor:</label>
<select name="vendor" required class="form-control" id="vendor" >
</select>
<div class="note"> Recommended Vendor : <span id="recomvend"> </span> </div>
</div>
<div class="form-group col-sm-6">
<label> Quantity:</label>
<input type="text" required name="qty" class="form-control" id="qty"></div>
<div style="clear:both"> </div>
<input type="submit" name="submit" class="btn btn-primary smp" value="Submit">
<button id="clear" type="button" class="btn btn-primary smp smp2" > Reset </button>
</div>
<input type="submit" value="submit" name="submit">
</form>
entry 1
speed rating -- 46
description ---'the discription'
------
entry 2
speed rating --56
description ---'another description'
submit
The saveto.php is just a normal script that will process the submitted data to database, one entry in a per submit bases.

Dynamic form addition/subtraction with angularjs

I am trying to get my dynamic form additions/subtractions to work correctly. The situation is that I am able to get the form block to add or remove, however, when I click the remove button it removes the most recently added block rather than the one I click on.
For example, if I add two new form blocks for a total of 3 blocks (block1, block2, block3) and I click remove on block2, instead of removing block 2 it removes block3.
I have created a plunker that demonstrates this, but it ONLY works when you launch the preview side in a separate window (otherwise the add button is inactive for some reason).
Working Example (must open in popup preview in plunker to function): plunker
<form class="form-horizontal" name="cpdForm" novalidate="" ng-submit="processForm()" ng-show="!message">
<h2>Subcontractor Performance</h2>
<hr />
<div ng-repeat="subcontractor in subcontractors">
<div class="well well-sm">Subcontractor #{{subcontractor.id}} <span id="subCounter"></span>
<button type="button" ng-click="removeSub()" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="form-group">
<div class="col-md-6">
<label for="subName">Subcontractor Name</label>
<input type="text" class="form-control" id="subName" name="subName" placeholder="Subcontractor" ng-model="formData.subName['subName'+($index+1)]" />
</div>
<div class="col-md-3">
<label for="mwbeCert">Disadvantaged Certification</label>
<select class="form-control" name="mwbeCert" ng-model="formData.mwbeCert" required="">
<option value="">Select MWBE Certification...</option>
<option ng-repeat="item in dropdownpoll['mwbecert']" value="{{item.mwbeid}}">{{item.mwbe}}</option>
</select>
</div>
<div class="col-md-3">
<label for="subAmount">Contracted Amount</label>
<div class="inner-addon left-addon">
<i class="glyphicon glyphicon-usd"></i>
<input type="text" class="form-control" id="subAmount" name="subAmount" placeholder="Contracted Amount" ng-model="formData.subAmount" />
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-4">
<label for="subContactName">Contact Name</label>
<input type="text" class="form-control" id="subContactName" name="subContactName" placeholder="Contact Name" ng-model="formData.subContactName" />
</div>
<div class="col-md-4">
<label for="subContactPhone">Contact Phone</label>
<input type="text" class="form-control" id="subContactPhone" name="subContactPhone" placeholder="Contact Phone" ng-model="formData.subContactPhone" />
</div>
<div class="col-md-4">
<label for="subContactEmail">Contact Email</label>
<input type="text" class="form-control" id="subContactEmail" name="subContactEmail" placeholder="Contact Email" ng-model="formData.subContactEmail" />
</div>
</div>
<div class="form-group">
<div class="col-md-3">
<label for="subRating">Subcontractor Rating</label>
<select class="form-control" name="subRating" ng-model="formData.subRating" required="">
<option value="">Select Subcontractor Rating...</option>
<option ng-repeat="item in dropdownpoll['subrating']" value="{{item.subratingid}}">{{item.rating}}</option>
</select>
</div>
<div class="col-md-9">
<label for="subComment">Comments</label>
<input type="text" class="form-control" id="subComment" name="subComment" placeholder="Comments" ng-model="formData.subComment" />
</div>
</div>
<hr />
<button type="button" class="btn btn-info btn-sm pull-right" ng-show="showAddSub(subcontractor)" ng-click="addNewSub()">[+] Add New Sub</button>
</div>
<input type="hidden" style="display:none;" ng-model="formData.subCount" value="{{subcontractor.id}}" />
<div class="form-group">
<div class="col-sm-12">
<button class="btn btn-primary" id="submit" ng-click="submitting()" ng-disabled="buttonDisabled">{{submit}}</button>
</div>
</div>
</form>
<pre>{{formData}}</pre>
you are splicing $scope.subcontractors-1 which only behaves like it does, ie, removes the last one.
try using $event.currentTarget as a general rule, it will indicate the clicked item exactly, and don't forget to pass $event as a parameter for the remove function.
I hope this helps you
You need to pass an index to the function removeSub
I modified your fn to accept an index
$scope.removeSub = function(ind) {
var newItemNo = $scope.subcontractors.length-1;
$scope.subcontractors.splice(ind-1, 1);
};
and in your HTML you just pass the currently iterated $index
<button type="button" ng-click="removeSub($index)" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
Hope this works. But be careful your formdata and subcontrators array are not in sync after this, thats a programming logic I guess you have to fix.
Happy coding
Cheers.
Joy
Not a full answer but your not telling the function in your script.js which one to remove your just telling it to chop one off the end. Try setting it up so that you pass the current subContractor id like ng-click="removeSub({{subcontractor.subContractorId}})" (not sure what your data model is) you could also reference the index but I believe that would be harder.

Categories

Resources