I'm currently using bootstrap wizard with progress bar of this template to create a form by steps as:
#model MyProject.ViewModels.Test.TestViewModel
<form asp-controller="Test" asp-action="Create" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post" class="needs-validation" role="form" novalidate>
<div class="container-fluid">
<ul class="twitter-bs-wizard-nav nav nav-pills nav-justified">
<li class="nav-item">
<a href="#progress-station-profile" class="nav-link" data-toggle="tab">
<div class="step-icon" data-bs-toggle="tooltip" data-bs-placement="top" title="Station Profile">
<i class="bx bxs-user-detail"></i>
</div>
</a>
</li>
</ul>
<div class="tab-pane" id="progress-station-profile">
<div class="row">
<div class="col-lg-4">
<div class="mb-3">
<label asp-for="CallLetters" class="form-label"></label>
<input asp-for="CallLetters" class="form-control" required autofocus/>
<div class="invalid-feedback">Call Letters is required.</div>
</div>
</div>
<div class="col-lg-4">
<div class="mb-3">
<label asp-for="Market" class="form-label"></label>
<input asp-for="Market" class="form-control" required autofocus/>
<div class="invalid-feedback">Market is required.</div>
</div>
</div>
<div class="col-lg-4">
<div class="mb-3">
<label asp-for="Format" class="form-label"></label>
<select asp-for="Format" class="form-select" required>
<option value="Test 1">Test 1</option>
<option value="Test 2">Test 2</option>
<option value="Test 3">Test 3</option>
</select>
<div class="invalid-feedback">Format is required.</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="mb-3">
<label asp-for="Frequency" class="form-label"></label>
<input asp-for="Frequency" class="form-control" autofocus/>
</div>
</div>
</div>
<ul class="pager wizard twitter-bs-wizard-pager-link">
<li class="next">
<a href="javascript: void(0);" class="btn btn-primary">
Next
<i
class="bx bx-chevron-right ms-1">
</i>
</a>
</li>
</ul>
</div>
..///next step etc..
<input type="submit" class="btn btn-primary me-1" value="Save"/>
</form>
As you can see, some of my fields are required, and I want to achieve to validate those fields via client-side validation when the user clicks the "Next" button because it validates at the end of the form (submit button), and the user has no idea what step was wrong. So it will be awesome if I can validate it when the user clicks the next button
UPDATE
I already find a way to show validations as:
//first step
<div class="tab-pane step" id="progress-station-profile">
//fields here
<button onclick="return validate('progress-station-owner')"
class="btn btn-primary">
Next
</button>
</div>
//Step 2
<div class="tab-pane step" id="progress-station-owner">
//fields here
<button onclick="return validate('progress-station-owner')"
class="btn btn-primary">
Next
</button>
</div>
//Step 3
//fields
<button type="submit" class="btn btn-primary me-1"> Save Station</button>
And I use function as:
function validate(step){
let window = document.getElementById(step);
window.querySelectorAll("input,select,textarea").forEach(e=>{
if(!e.checkValidity()){
e.classList.toggle("is-invalid");
event.preventDefault();
event.stopPropagation();
return false;
}
});
return true;
}
So, if I try to click button Next validations don't allow me to continue, that is correct, but now I have a big problem:
If I click Next on the first step it goes to the second step and shows the second step but it tries to execute the "Next" button of the second step automatically, so validations appear once step 2 showed up. Why is it happening?
Related
For our story we have to make sure our contact us page is accessible. We are supposed to make sure the tab order focus for each input in order for information to be read out on the screenreader. However, we have certain input fields that we don't want the user to be able to edit, however we still want them to be able to have the screen reader capture it. What is the best practice for this issue? What is the approach best to follow to solve this issue?
I found this example online and tried exploring the implementation of this fix Tab on disabled input. It is a css style approach to mitigating the problem but doesn't involve the disabled property.
<form [formGroup]="contactUsForm">
<div class="container pt-4">
<!-- Instructions -->
<div name="instructions-row" class="row">
<div tabindex="0" name="form-instructions" id="form-instructions" class="col justify-content-center">
Please fill out the form and click the send button to submit your message. If your question or comment is
about a specific account, enter the account name and account number in the body of the message.
</div>
</div>
<!-- Basic Info -->
<div name="basic-info-row" class="row">
<div class="col-xl-6 justify-content-center">
<!-- From -->
<div class="input-container">
<label for="from-input" class="liberty-text-secondary">
From
<span *ngIf="contactUsForm.get('from').hasError('required')" class="text-danger">
*
</span>
</label>
<input role="textbox" id="from-input" class="liberty-input col-12" formControlName="from" />
</div>
<!-- Account Number -->
<div class="input-container">
<label for="account-number-input" class="liberty-text-secondary">
Account Number
<span *ngIf="contactUsForm.get('accountNumber').hasError('required')" class="text-danger">
*
</span>
</label>
<input tabindex="0" role="textbox" id="account-number-input" class="liberty-input col-lg-4 col-md-12" formControlName="accountNumber" />
</div>
<!-- User ID -->
<div class="input-container">
<label for="user-id-input" class="liberty-text-secondary">
User ID
<span *ngIf="contactUsForm.get('userId').hasError('required')" class="text-danger">
*
</span>
</label>
<input tabindex="0" role="textbox" id="user-id-input" class="liberty-input col-lg-10 col-md-12" formControlName="userId" />
</div>
<!-- Name -->
<div class="input-container">
<label for="name-input" class="liberty-text-secondary">
Name
<span *ngIf="contactUsForm.get('name').hasError('required')" class="text-danger">
*
</span>
</label>
<input tabindex="0" role="textbox" id="name-input" class="liberty-input col-lg-10 col-md-12" formControlName="name" />
</div>
<!-- Phone Number -->
<div class="input-container">
<label for="phone-number-input" class="liberty-text-secondary">
Phone Number
<span *ngIf="contactUsForm.get('phoneNumber').hasError('required')" class="text-danger">
*
</span>
</label>
<input tabindex="0" role="textbox" id="phone-number-input" class="liberty-input col-lg-4 col-md-12" formControlName="phoneNumber" />
<span *ngIf="contactUsForm.get('phoneNumber').hasError('pattern')" class="text-danger">
Please enter a valid phone number.
</span>
</div>
<!-- Subject -->
<div class="input-container">
<label for="subject-input" class="liberty-text-secondary">
Subject
<span *ngIf="contactUsForm.get('subject').hasError('required')" class="text-danger">
*
</span>
</label>
<select tabindex="0" id="subject-input" class="liberty-select col-lg-11 col-md-12" formControlName="subject">
<option *ngIf="!contactUsForm.value.subject" [value]="null" selected disabled></option>
<option *ngFor="let subject of subjects" [value]="subject">{{subject}}</option>
</select>
</div>
</div>
</div>
<!-- Comments -->
<div class="row">
<div class="col-xl-10 justify-content-center">
<div class="input-container">
<label for="comments-input" class="liberty-text-secondary">
Comments
<span *ngIf="contactUsForm.get('comments').hasError('required')" class="text-danger">
*
</span>
</label>
<textarea tabindex="0" role="textbox" id="comments-input" class="liberty-text-area" formControlName="comments"></textarea>
</div>
</div>
</div>
<!-- Submit Button -->
<div class="row py-4">
<div class="col container">
<div class="row">
<button tabindex="0" role="button" id="submit-button" class="col-xl-2 col-3 btn liberty-button mx-3" [disabled]="contactUsForm.invalid"
(click)="onSubmitClick()">
Send
</button>
<button tabindex="0" role="button" id="cancel-button" class="col-xl-2 col-3 btn liberty-button mx-3" routerLink="/home">
Cancel
</button>
<span class="col-xl-8 col-6"></span>
</div>
</div>
</div>
</div>
</form>
The above code tabs through the enabled inputs only.
Use readonly attribute or css pointer-events none to make the input disabled. Use ngClass to add class dynamically.
component.css
.disabled {
pointer-events: none;
opacity: 0.5;
}
component.html
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input type="text" formControlName="userName">
<input type="text" formControlName="password">
<input [ngClass]="{'disabled':!form.valid}" readonly type="button" value="submit" >
</form>
Example
Note: If you use pointer events none with input type button make sure to add readonly attribute otherwise it will be submit able through enter button
I have a blade form which has a repeater input box and a select box, the repeater works fine but how do i pass the data from those fields to back-end controller in laravel?
add.balde.php
<!--begin::Add-Invoice-Form-->
<form class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" action="{{route('store_invoice')}}" method="POST" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="m-portlet__body">
<div class="form-group m-form__group row">
<div class="col-lg-4">
<label>
Customer Name:
</label>
<select class="form-control m-select2" id="m_select2_1" name="customerId">
#foreach($customer_list as $customer)
<option value=" {{ $customer->id }} ">
{{ $customer->fName }} {{ $customer->mName }} {{ $customer->lName }}
</option>
#endforeach
</select>
</div>
<div class="col-lg-4">
<label>
Invoice Type:
</label>
<div class="m-radio-inline">
<label class="m-radio m-radio--solid">
<input type="radio" name="invoiceType" checked value="billable">
Billable
<span></span>
</label>
<label class="m-radio m-radio--solid">
<input type="radio" name="invoiceType" value="nonbillable">
Non Billable
<span></span>
</label>
</div>
</div>
</div>
<div id="m_repeater_1">
<div class="form-group row" id="m_repeater_1">
<div data-repeater-list="" class="col-lg-12">
<div data-repeater-item class="form-group m-form__group row align-items-center">
<div class="col-lg-4">
<label>
Summary Number:
</label>
<select class="form-control m-select2" id="m_select2_2" name="certificateId[]">
#foreach($certificate_list as $certificate)
<option value=" {{ $certificate->id }} ">
{{ $certificate->summary_no }} ( {{ $certificate->certificateType() }} )
</option>
#endforeach
</select>
</div>
<div class="col-lg-3">
<label>
Rate:
</label>
<input type="number" class="form-control m-input" name="rate" placeholder="Enter rate">
</div>
<div class="col-lg-3">
<br/>
<div data-repeater-delete="" class="btn btn btn-danger m-btn m-btn--icon">
<span>
<i class="la la-trash-o"></i>
<span>
Remove
</span>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="m-form__group form-group row">
<div class="col-lg-4">
<div data-repeater-create="" class="btn btn btn-warning m-btn m-btn--icon">
<span>
<i class="la la-plus"></i>
<span>
Add
</span>
</span>
</div>
</div>
</div></div>
</div>
<div class="m-portlet__foot m-portlet__no-border m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid">
<div class="row">
<div class="col-lg-4"></div>
<div class="col-lg-8">
<button type="submit" class="btn btn-primary">
Submit
</button>
<button type="reset" class="btn btn-secondary">
Cancel
</button>
</div>
</div>
</div>
</div>
</form>
<!--end::Add-Invoice-Form-->
How do I send the values in array format when multiple select box have been filed using repeater?This images shows the UI for the form
Thank you
you can try something like this
<input type="text" value="val" name="somename[]">
<select name="someSelectName[]">
<option value="value">select 1
</option>
</select>
on server side you will receive selected values as array with given name
Change your
<div data-repeater-list="" class="col-lg-12">
To
<div data-repeater-list="arrayName" class="col-lg-12">
and It should work.
This makes the all the input names to have an array format of arrayName[number][input] and the number increments for each input and finally in the request sent you will have all the inputs in the arrayName
I have a form on the page and displayed it as none. And there is a button in the page I want when clicking on the button the form to display.
How can I do that?
<button type="button" class="btn btn-primary add-city">اضافه مدينة جديدة +</button>
and form code is this
<div id="forma">
<div class="form-head">
<p id="add-city">+اضافة المدينة</p>
<i class="fa fa-times-circle close" aria-hidden="true"></i>
</div>
<form class="">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>الدولة<span>*</span></label>
<select class="form-control">
<option>اختر الدوله </option>
</select>
</div>
<div class="form-group">
<label>اسم المدينه(عربي)<span>*</span></label>
<input type="text" class="form-control" id="email">
</div>
</div>
<div class="col-md-6">
<div class="form-group ">
<label>المحافظة<span>*</span></label>
<select class="form-control">
<option>اختر المحافظه </option>
</select>
</div>
<div class="form-group">
<label>اسم المدينه(انجليزي)</label>
<input type="text" class="form-control" id="email">
</div>
</div>
</div>
</div>
</form>
<div class="form-footer">
<button type="button" class="btn btn-primary">ارسال</button>
<button type="button" class="btn btn-secondary">الغاء</button>
</div>
</div>
I made a div with an id called forma so that I can call it in javascript. But I don't know the right way.
You can add an onclick attribute to the button that changes the display to block.
onclick="document.getElementById('forma').style.display = 'block'"
Just use the jQuery click property and show property
$( "#idbutton" ).click(function() {
$("#idform").show();
});
If you are using Bootstrap.js, you can safely use jQuery because it's required. Assuming you should click #add-city button to display the form, simply add to your app.js or inside your <script> tags
$('#add-city').click(function() {
$('#forma').show();
});
In order to toggle the form (show/hide) on every click, you could do something like
$('#add-city').click(function() {
$('#forma').toggleClass('hidden');
});
I am updating hidden field in form with jquery. it works just fine for first three clicks after that it shows only first element value.
Here is working js fiddle jsfiddle link:
when users is clicking on tab the value of fileorurl changes to 1,2 or 3. it works for first 3-5 click but after that the value stocks to only 1. here is html
<div class="container" id="upload">
<div class="row">
<form id="upload-form2"
action="http://way2enjoy.com/modules/compress-png/converturl16.php"
name="arjun"
method="post"
enctype="multipart/form-data">
<div id="tab" class="btn-group" data-toggle="buttons">
<a href="#fileuu" class="btn btn-default active" data-toggle="tab">
<input type="radio" class="changev" value="1">File Upload
</a>
<a href="#urluu" class="btn btn-default" data-toggle="tab">
<input type="radio" class="changev" value="2">URL upload
</a>
<a href="#linkuu" class="btn btn-default" data-toggle="tab">
<input type="radio" class="changev" value="3">Website Link
</a>
</div>
<div class="tab-content">
<div class="tab-pane active" id="fileuu">
<label for="comment">Click below to choose files:</label>
<input type="file" name="file[]" multiple id="input" class="file_input">
</div>
<div class="tab-pane" id="urluu">
<label for="comment">Image Urls to Compress:</label>
<textarea class="form-control" rows="2" name="urls" id="urls"></textarea>
</div>
<div class="tab-pane" id="linkuu">
<label for="comment">Website URL to Analyze:</label>
<textarea class="form-control" rows="2" name="file[]" id="urls"></textarea>
</div>
</div>
<div class="alert alert-warning" role="alert" id="loading_progress"></div>
<br>
<input type="submit"
value="Compress »"
class="btn btn-primary btn-lg pull-right"
id="upload_btn"
name="upload_btn">
<input type="hidden" name="fileorurl" id="myField" value="">
</form>
</div>
</div>
Here is javascript:
<script>
$('.changev').change(function () {
var valueuu = $(this).val();
$("#myField").val(valueuu);
});
</script>
Any help will be useful thanks!
Your checkboxes not updating for some strange reason after a few clicks. You can use the click event on their parents instead:
$('#tab a').on('click', function(){
var valueuu = $(this).find('input').val();
$("#myField").val(valueuu);
});
Fiddle
I would personally use a custom attribute for that and listen to Bootstrap events. The default value of the input is 1, because that will be the first active tab.
$(document).on('shown.bs.tab', '#tab > a', function(e) {
var dataType = $(e.target).attr('data-type');
$("#myField").val(dataType);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container" id="upload">
<div class="row">
<form id="upload-form2" action="http://way2enjoy.com/modules/compress-png/converturl16.php" name="arjun" method="post" enctype="multipart/form-data">
<div id="tab" class="btn-group" data-toggle="buttons">
File Upload
URL upload
Website Link
</div>
<div class="tab-content">
<div class="tab-pane active" id="fileuu">
<label for="comment">Click below to choose files:</label>
<input type="file" name="file[]" multiple id="input" class="file_input">
</div>
<div class="tab-pane" id="urluu">
<label for="comment">Image Urls to Compress:</label>
<textarea class="form-control" rows="2" name="urls" id="urls"></textarea>
</div>
<div class="tab-pane" id="linkuu">
<label for="comment">Website URL to Analyze:</label>
<textarea class="form-control" rows="2" name="file[]" id="urls"></textarea>
</div>
</div>
<div class="alert alert-warning" role="alert" id="loading_progress"></div>
<br>
<input type="submit" value="Compress »" class="btn btn-primary btn-lg pull-right" id="upload_btn" name="upload_btn">
<input type="text" name="fileorurl" id="myField" value="1">
</form>
</div>
</div>
Fiddle here: https://jsfiddle.net/zyynnzm9/3/
Found it ^^ your radio buttons are getting checked but they aren't getting unchecked so they aren't canceling each other .. because they aren't in the same radio group
You have to put them in a radio group by adding the name attribute with equal value to each
The website that I'm making, using Laravel and Bootstrap, has a search bar along with a dropdown list, that will narrow the search down to a specific category. Here's the following code for the search bar:
<div class="container">
<form id="search_form" method="get" action="{{ route('search') }}">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<div class="input-group">
<div class="input-group-btn search-panel">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span name="category" id="search_concept">Title</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Title</li>
<li>Author</li>
<li>School</li>
<li>Course Code</li>
</ul>
</div>
<!--<input type="hidden" name="_token" value="{{ Session::token() }}">-->
<input class="form-control" name="term" placeholder="Search Here" autocomplete="off" autofocus="autofocus" type="text" id="filter">
<span id="search_submit" type="submit" class="btn input-group-addon glyphicon glyphicon-search" style="width:1%;"></span>
</div>
</div>
</div>
</form>
</div>
When I type "hello world" into the search bar and submit the form, I get redirected to this URL: http://localhost:8000/search?term=hello+world
I want to also pick up the selected value of the dropdown list, so when I select 'title' as my category in the dropdown list and submit the form, I would get redirected to:
http://localhost:8000/search?category=title&term=hello+world
How do I approach this?
You can modify it like this and use jQuery/js
<div class="container">
<form id="search_form" method="get" action="{{ route('search') }}">
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<div class="input-group">
<div class="input-group-btn search-panel">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span name="category" id="search_concept">Title</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a data-category="title" class="search_category" href="#title">Title</a></li>
<li><a data-category="author" class="search_category" href="#author">Author</a></li>
<li><a data-category="school" class="search_category" href="#school">School</a></li>
<li><a data-category="course_code" class="search_category" href="#course_code">Course Code</a></li>
</ul>
</div>
<!--<input type="hidden" name="_token" value="{{ Session::token() }}">-->
<input type="hidden" name="category" id="category"/>
<input class="form-control" name="term" placeholder="Search Here" autocomplete="off" autofocus="autofocus" type="text" id="filter">
<span id="search_submit" type="submit" class="btn input-group-addon glyphicon glyphicon-search" style="width:1%;"></span>
</div>
</div>
</div>
</form>
</div>
jQuery:
$(".search_category").click(function(e){
$("#category").val($(this).attr("data-category"));
});