Form not validating required fields with BootStrap - javascript

I have a form that submits with empty required fields.
I'm using Twitter BootStrap with it.
I posted this example in jsFiddle.
Maybe is just an tag issue from BootStrap, but i'm really not seeing what is wrong.

3 things:
That is not how you use required.
You need to wrap your jQuery code in .ready().
Move the <button> element inside the <form> and make it type="submit".
Updated Code:
$(document).ready(function(){
$(".action").click(()=>{
$(".ajaxForm").submit();
});
$(".ajaxForm").submit(()=>false);
});
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<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>
<form class="ajaxForm">
<div class="container col-sm-6 col-xs-12">
<div class="form-group input-group">
<span class="input-group-addon">
Nome
</span>
<input type="text" class="form-control nome" required />
</div>
</div>
<div class="container col-sm-6 col-xs-12">
<div class="form-group input-group">
<span class="input-group-addon">
CPF
</span>
<input type="text" class="form-control cpf" required />
</div>
</div>
<button type="submit" class="action btn btn-success">Teste</button>
</form>
Updated jsFiddle

Thanks for the answers.
Since I have a button (div, actually) outside the form that will trigger the submit, I found my way by (quick fix) triggering a click on a hidden submit button.
The HTML:
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<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>
<form class="ajaxForm">
<div class="container col-sm-6 col-xs-12">
<div class="form-group input-group"> <span class="input-group-addon">
Nome
</span>
<input type="text" class="form-control nome" required />
</div>
</div>
<div class="container col-sm-6 col-xs-12">
<div class="form-group input-group"> <span class="input-group-addon">
CPF
</span>
<input type="text" class="form-control cpf" required />
</div>
</div>
<input type="submit" style="display:none" /> <!-- The hidden button -->
</form>
<button class="action btn btn-success">Teste</button>
The JavaScript:
$(".action").click(() = > {
$(".ajaxForm input[type='submit']").click();
});
$(".ajaxForm").submit(() = > false);
So, this quick fix will work, for now. Here is the jsFiddle updated.

Related

Changing Form Attributes Before Submission

I'm working on something that involves ensuring the method of form submission is POST not GET when the method might have been omitted somehow and somewhere. A JS/jQuery function checks each form before submission for a particular class. If the class exists, it goes on to check the method. If the method is a GET, it should ignore it and submit the form. But if it is undefined or empty, it should proceed to set the method to POST then submit.
This is the JQuery used. The HTML follows.
$(document).ready(function() {
$('form').submit(function() {
if (this.find(':submit').is('.ckh-method')) {
if ((this.attr('method') !== "GET" && this.attr('method') == "") || this.attr('method') == undefined) {
this.setAttribute('method', 'POST');
return true;
}
}
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://fontawesome-free/web-fonts-with-css/css/fontawesome-all.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<form class="form-horizontal" role="form" action="phpFile.php" method="">
<div class="row">
<div class="col-sm-12">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-user-alt"></i>
</span>
<input type="text" class="form-control" placeholder="Username" name="username" id="username" required="required" value=''>
</div>
</div>
<div class="col-sm-12">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-lock"></i>
</span>
<input type="password" class="form-control" placeholder="Password" name="password" id="password" required="required" value=''>
</div>
</div>
<p class="conditions col-sm-12">Forgot Username or Password?
<div class="text-center col-sm-12 error"></div>
</p>
<div class="col-sm-12" id="btn-hold">
<button type="submit" class="btn btn-success btn-block ckh-method">Log In</button>
</div>
<div class="col-sm-12">
<a type="button" class="btn btn-link btn-block" href="proceed.php">Sign Up</a>
</div>
</div>
</form>
</div>
</body>
</html>
Problem: The form method doesn't change on submission because there is a JS error somewhere in my code. I'm suspecting it has to do with the 'this' keyword. Maybe I used it wrongly. I've tried setting breakpoints so I can identify the issue but the form submits before I can step into the function (in my Developer's tool) and discover the problem. Can someone help me out?
var frm = document.getElementById("form1")
frm.addEventListener("submit" ,checkmethod )
function checkmethod(event){
event.preventDefault();
if(frm.method !="GET") frm.method = "POST";
frm.submit();
}
<form id="form1" action="" >
<button type="submit">submit</button>
</form>
Found your console error. bootstrap js requires jquery so i have corrected the sequence as below
first : Jquery JS
second : Bootstrap JS
also use $(this) instead of just this
use attr for setting attributes instead of setAttribute
$('form').submit(function() {
if ($(this).find(':submit').is('.ckh-method'))
{debugger;
if (($(this).attr('method') !== "GET" && $(this).attr('method') == "") || $(this).attr('method') == undefined) {
$(this).attr('method', 'POST');
return true;
}
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://fontawesome-free/web-fonts-with-css/css/fontawesome-all.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<form class="form-horizontal" role="form" action="phpFile.php" method="">
<div class="row">
<div class="col-sm-12">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-user-alt"></i>
</span>
<input type="text" class="form-control" placeholder="Username" name="username" id="username" required="required" value=''>
</div>
</div>
<div class="col-sm-12">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-lock"></i>
</span>
<input type="password" class="form-control" placeholder="Password" name="password" id="password" required="required" value=''>
</div>
</div>
<p class="conditions col-sm-12">Forgot Username or Password?
<div class="text-center col-sm-12 error"></div>
</p>
<div class="col-sm-12" id="btn-hold">
<button type="submit" class="btn btn-success btn-block ckh-method">Log In</button>
</div>
<div class="col-sm-12">
<a type="button" class="btn btn-link btn-block" href="proceed.php">Sign Up</a>
</div>
</form>
</div>
</body>
</html>
I edited the snippet:
$(document).ready({
$('form').submit(function() {
if ($(this).find(':submit').is('.chk-method')) {
if (($(this).attr('method') !== "GET" && $(this).attr('method') == "") || $(this).attr('method') == undefined) {
$(this).attr('method', 'POST');
return true;
}
}
})
})
Use $(this) instead of 'this' and attr() instead of setAttribute().

Clean way to generate HTML

First of All I can't put all my elements in ONE ROW ONLY (all inline) I'm trying to generate one row of elements inside envVariablesDiv. I did all the html using javascript in my attempt and it's a huge mess and confusing.
Is there a simpler way to add rows of my elements everytime I click the button? I also need to be able to delete the row when I click delete.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="top20 content-form">
<label class="col-sm-2 control-label" for="addEnv"><button class="btn btn-primary">add</button></label>
<div class="col-sm-10">
<label id="addEnv" class="label label-secondary pointer-label"><span class="fa fa-plus-circle"></span> Add environment variable</label>
<div id="envVariablesDiv">
<div class="input-group">
<span class="input-group-addon">Text</span>
<input id="msg" type="text" class="form-control" name="msg" placeholder="Additional Info">
</div>
<div class="input-group">
<span class="input-group-addon">Text</span>
<input id="msg" type="text" class="form-control" name="msg" placeholder="Additional Info">
</div>
<button class="btn btn-danger">Delete</button>
</div>
</div>
</div>
JS I done: The styling is different now. I want to use input group.
$('#addEnv').click(function () {
$('#envVariablesDiv').append('<div class="col-sm-5 top10"><label for="envName" class="control-label">Name</label><input id="envName" class="form-control" name="envName" type="text" placeholder="e.g. name1" /></div>' +
'<div class="col-sm-5 top10"><label for=envVar class="control-label">Variable</label><input class="form-control" id="envVar" type="text" name="envVar" placeholder="e.g. var1" /></div><div class="col-sm-2 top10"><button class="btn btn-danger"><span class="fa fa-trash"></span></button></div>');
});

bootstrap input-prepend makes two div inline (in a same line),no new line

<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" media="screen">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.jss"></script>
<div class="input-prepend">
<span class="add-on">#</span>
<input class="span2" id="prependedInput" type="text" placeholder="Username">
</div>
<div class="input-append">
<input class="span2" id="appendedInput" type="text">
<span class="add-on">.00</span>
</div>
the result is :
So,two divs are in the same line.How can i have a new line?
The default sytle of div is block,is that mean when I use prependedInput and appendedInput ,it will change it to inline?
bootstrap version is 2.3.2
As you see the documentation provided in Bootstrap 2.3.2, it doesn't state that your classes input-append and input-prepend will be in the same line.
It's just shown for clarity purpose. But will also see that you will get it in a new line when you change it to smaller screen i.e. col-xs-12.
Do it be either <br> or col-xs-12:
<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" media="screen">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.jss"></script>
<form class="bs-docs-example">
<h4>Using <code>col-xl-12</code></h4>
<div class="col-xl-12">
<div class="input-prepend">
<span class="add-on">#</span>
<input class="span2" id="prependedInput" type="text" placeholder="Username">
</div>
</div>
<div class="col-xl-12">
<div class="input-append">
<input class="span2" id="appendedInput" type="text">
<span class="add-on">.00</span>
</div>
</div>
</form>
<h4>Using <code><br/></code></h4>
<form class="bs-docs-example">
<div class="input-prepend">
<span class="add-on">#</span>
<input class="span2" id="prependedInput" type="text" placeholder="Username">
</div>
<br>
<div class="input-append">
<input class="span2" id="appendedInput" type="text">
<span class="add-on">.00</span>
</div>
</form>

How to add dynamic data attribute value to a button and a div generated by repeater.js

I am using repeater.js to repeat a div with some input fields and button, but the problem is that i want to give each and every div a unique id so that i can extract data from all the fields of that particular div input elements.
this is the HTML Code:
<div class="form-group mt-repeater">
<a href="javascript:;" data-repeater-create class="btn btn-circle purple mt-repeater-add">
<i class="fa fa-edit"></i> Repeat Field
</a>
<div data-repeater-list="group-b">
<div data-repeater-item class="mt-repeater-item">
<div class="mt-repeater-cell">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="dosage_form" class="form-control typeahead-findings circle-input" placeholder="Dosage Form">
<label for="dosage_form">e.g. Tablet / Syrup / Capsule etc.</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="brand_name" class="form-control typeahead-findings circle-input" placeholder="Brand / Generic Name">
<label for="brand_name">e.g. Dytor</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" id="contents" type="text" placeholder="Contents" />
<span class="help-block"> e.g Paracetamol </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="dose" class="form-control typeahead-findings circle-input" placeholder="Dose">
<label for="dose">e.g. 20 mg / 20 ml</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" id="dose_regimen" type="text" placeholder="Dose Regimen" />
<span class="help-block"> e.g 1-1-1-1 </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="therapy_duration" class="form-control typeahead-findings circle-input" placeholder="Therapy Duration">
<label for="therapy_duration">e.g. 1 Day / 1 Month etc.</label>
</div>
</div>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-plus"></i>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-minus"></i>
</div>
</div>
</div>
</div>
every time i click on the add repater button this div gets replicated but what i also want is that the new div generated should have a unique div id also the curresponding elemnts inside it should have a class or id starting with that id so that data extraction can be easy for that particular div
I was using this Jquery code:
$(".addData").on('click' ,function()
{
alert("hi");
});
This is the repeater i am using: https://pastebin.com/n7g7tdTH
but this code only runs for the very first div on the later generated dynamic divs it doesn't run. I also tried editing the repeater.js but no success because its all dynamic and i am not able to understand where i should edit that code to add a dynamic data-counter value for the div and the corresponding elements.
Can anyone help with this logic?
Another option, to retrieve field values would be to rename all input field id with name (example below) and use repeater.js repeaterVal() to get all the field values .
$(".mt-repeater").repeater();
$("#getVal").click(function () {
$('.mt-repeater').repeaterVal()["group-b"].map(function(fields){
//fields contain the collection of input fields per row
console.log(fields["dosage_form"]);
console.log(fields["brand_name"]);
//....
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="form-group mt-repeater">
<a href="javascript:;" data-repeater-create class="btn btn-circle purple mt-repeater-add">
<i class="fa fa-edit"></i> Repeat Field
</a>
<div data-repeater-list="group-b">
<div data-repeater-item class="mt-repeater-item">
<div class="mt-repeater-cell">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="dosage_form" class="form-control typeahead-findings circle-input" placeholder="Dosage Form">
<label for="dosage_form">e.g. Tablet / Syrup / Capsule etc.</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="brand_name" class="form-control typeahead-findings circle-input" placeholder="Brand / Generic Name">
<label for="brand_name">e.g. Dytor</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" nam="contents" type="text" placeholder="Contents" />
<span class="help-block"> e.g Paracetamol </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="dose" class="form-control typeahead-findings circle-input" placeholder="Dose">
<label for="dose">e.g. 20 mg / 20 ml</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" name="dose_regimen" type="text" placeholder="Dose Regimen" />
<span class="help-block"> e.g 1-1-1-1 </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="therapy_duration" class="form-control typeahead-findings circle-input" placeholder="Therapy Duration">
<label for="therapy_duration">e.g. 1 Day / 1 Month etc.</label>
</div>
</div>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-plus"></i>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-minus"></i>
</div>
</div>
</div>
</div>
<button id="getVal">Get Value</button>
For the first problem..
but this code only runs for the very first div on the later generated
dynamic divs it doesn't run
You can convert your jquery events into delegated events.. These allow you to catch events on DOM elements based on a selector, so when newer DOM elements are added these are caught too.
So -> $(".addData").on('click' ,function()
As a delegated event becomes -> $(document.body).on("click",".addData" ,function()
The second problem.
but how to get the values from the input field that are present near that button
This can be achieved by traversing up the DOM tree to a parent that surrounds the elements you want,. eg. .row or maybe mt-repeater-cell, as long as it's a DOM element that contains the elements you want to find. Here you can use jquery's closest selector, that will traverse up the tree until it finds the element your after.
So -> $(this).closest('.row').find('#dose_regimen').val()
The above will traverse up the DOM tree until it finds a .row class, we then find element with id dose_regimen etc,.. #dose_regimen and then finally get it's value with .val()

Access the value of an input that is loaded after the dom

how can I access the value of an input text field, which loads propably after the dom?
I am working with leaflet at the moment and a plugin creats an input field and I don't know, how to access it.
If I try this:
$('#myTextbox1').on('input', function() {
alert($('#myTextbox1').val());
});
I don't get any result. I guess, jQuery can't handle the created input field.
My HTML looks like this:
#extends('layouts.app')
#section('head')
<link rel="stylesheet" type="text/css" href="{{ asset('css/leaflet/leaflet.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('css/leaflet/leaflet-search.css') }}">
#ensection
#section('content')
<div class="col-md-8 col-md-offset-2 form-container">
<div id="map-adress"></div>
<div class="panel panel-default marker-panel">
<div class="panel-heading">Create a post</div>
<div class="panel-body">
<div class="col-md-8 col-md-offset-4">
<p>Insert the adress of the marker position<br>
(You can move the marker on the map to the right position).</p>
</div>
<div class="form-group">
<label for="findbox-adress" class="col-md-4 control-label find-label">Marker Location</label>
<div class="col-md-6">
<div id="findbox-adress"></div>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary user_marker_btn">
Validate
</button>
</div>
</div>
</div>
</div>
<div id="user_marker_adress" class="panel panel-default">
<div class="panel-heading">Validate the marker adress</div>
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('userposts.create') }}">
{{ csrf_field() }}
<div class="form-group">
<label for="a_street" class="col-md-4 control-label">Street</label>
<div class="col-md-6">
<input id="a_street" type="text" class="form-control" name="a_street" required>
</div>
</div>
<div class="form-group">
<label for="a_street_no" class="col-md-4 control-label">Street No.</label>
<div class="col-md-6">
<input id="a_street_no" type="text" class="form-control" name="a_street_no" required>
</div>
</div>
<div class="form-group">
<label for="a_zip_code" class="col-md-4 control-label">Zip Code</label>
<div class="col-md-6">
<input id="a_zip_code" type="text" class="form-control" name="a_zip_code" required>
</div>
</div>
<div class="form-group">
<label for="a_state" class="col-md-4 control-label">State</label>
<div class="col-md-6">
<input id="a_state" type="text" class="form-control" name="a_state" required>
</div>
</div>
<div class="form-group">
<label for="a_country" class="col-md-4 control-label">Country</label>
<div class="col-md-6">
<input id="a_country" type="text" class="form-control" name="a_country" required>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="reset" class="btn btn-danger">
Clear
</button>
<button type="submit" class="btn btn-primary">
Next
</button>
</div>
</div>
</form>
</div>
</div>
#endsection
#section('scripts')
<script type="text/javascript" src="{{ asset('js/leafleat/leaflet.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/leafleat/leaflet-search.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/leafleat/marker-adress.js') }}"></script>
#endsection
The div with the ID "findbox-adress" triggers the plugin, which will create the form with the input, that I can't access.
Hope, someone got an idear of my problem...
Edit:
OK, I have found an ID in this element and with the ID it is working, but only the text, that I have typed in. The plugin gives me a dropdown selection(autocomplete like ajax) where I can choose a unordered list with some li's. But there I can't get a value? How can I get the value, if someone is clicking on the autocomplete(li's)?
My try:
$(".user_marker_btn").click(function(){
console.log($("#searchtext9").val());
});
On dynamically created elements, use event delegation to attach event listeners.
Attach the event listener to a parent element that existed on DOM-load, and then pass the element that you wish to delegate the event to:
$('body').on('input', '#myTextbox1', function() {
alert($('#myTextbox1').val());
});
First of all, your given code doesn't look right. Please refer to jQuery manual: http://api.jquery.com/on/
This might be:
$( "body" ).on( "click", "input#myTextbox1" function() {
console.log( $( this ).val() );
});
As you said, "The div with the ID "findbox-adress" triggers the plugin, which will create the form with the input"
If you can track the event when the div 'findbox-adress' get clicked or triggered, you can easily check for the form whether it has been added in the DOM or not and then check for input field by using $("input#myTextbox1").val();
Or if you cannot track the event of loading the form, you will need to have a function to check always when the form is getting loaded into the DOM. That might be using setTimeout() or any other method by framework/library. And finally stop the tracking when the form loaded.

Categories