Creating a bar-chart for top viewed data in angular - javascript

I created an angular project that takes some data(as issue) dynamically and stored as card in a component(issues component). If I click on a particular card, it navigates to issue-details component where entire details of an issue should be shown. Now, I have to create a chart that should display top viewed issues. How can I do this? I am a beginner to Angular.
Any help can be appreciated.
Thanks in advance.
issues.component.html:
<h3 *ngIf="default" class="mt-5" style="text-align: center">There is nothing to show. Please raise issue by clicking "Add New" button.</h3>
<app-update (upevent)="upd8=$event" *ngIf="upd8" [ID]="uid"></app-update>
<div *ngIf="!upd8">
<div class="card-group">
<div class="card">
<div class="card-header bg-white">
<button class="btn btn-light" (click)="customtoggle()">Customise</button>
</div>
<div class="card-body" *ngIf="customClicked">
<form #customForm="ngForm">
<h6 class="card-title align-right">Customise View</h6>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="item1" name="customitem" [(ngModel)]="isCD">
<label class="form-check-label" for="item1">Created Date</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="item2" name="customitem" [(ngModel)]="isDes">
<label class="form-check-label" for="item2">Description</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="item3" name="customitem" [(ngModel)]="isSeverity">
<label class="form-check-label" for="item3">Severity</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="item4" name="customitem" [(ngModel)]="isStatus">
<label class="form-check-label" for="item4">Status</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="item5" name="customitem" [(ngModel)]="isRD">
<label class="form-check-label" for="item5">Resolved Date</label>
</div>
</div>
</form>
</div>
</div>
<div class="card text-right">
<div class="card-header bg-white">
<button class="btn btn-light" (click)="filtertoggle()">Filter</button>
</div>
<div class="card-body" *ngIf="filterClicked">
<form #filterForm="ngForm">
<h6 class="card-title align-right">Severity Filter</h6>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="sevfilter1" name="sevfilter" value="Minor" [(ngModel)]="sevfilter">
<label class="form-check-label" for="sevfilter1">Minor</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="sevfilter2" name="sevfilter" value="Major" [(ngModel)]="sevfilter">
<label class="form-check-label" for="sevfilter2">Major</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="sevfilter3" name="sevfilter" value="Critical" [(ngModel)]="sevfilter">
<label class="form-check-label" for="sevfilter3">Critical</label>
</div>
</div>
<h6 class="card-title align-right">Status Filter</h6>
<div class="form-group">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="stafilter1" name="stafilter" value="Open" [(ngModel)]="stafilter">
<label class="form-check-label" for="stafilter1">Open</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="stafilter2" name="stafilter" value="In Progress" [(ngModel)]="stafilter">
<label class="form-check-label" for="stafilter2">In Progress</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="stafilter3" name="stafilter" value="Resolved" [(ngModel)]="stafilter">
<label class="form-check-label" for="stafilter3">Resolved</label>
</div>
</div>
</form>
</div>
</div>
</div>
<div *ngFor="let issue of issues" class="mt-1">
<div *ngIf="issue.Id != 0">
<div class="card" *ngIf="(issue.Severity == sevfilter || sevfilter == 'none') && (issue.Status == stafilter || stafilter == 'none')">
<div class="card-header" style="background-color: #563D7C">
<div class="row">
<div class="col-md-8">
<strong class="nav-link text-white">Issue ID: {{issue.Id}}</strong>
</div>
<div class="col-md-2">
<button type="button" (click)="update(issue)" class="nav-link btn text-white btn-primary float-right">Update</button>
</div>
<div class="col-md-2">
<button type="button" (click)="delete(issue.Id)" class="nav-link btn btn-danger float-right">Delete</button>
</div>
</div>
</div>
<div class="card-body" style="background-color: #E1D3F7">
<ul class="list-group">
**<a [routerLink]="['/issuesdetail',issue.CreatedDate,issue.Description,issue.Severity,issue.Status,issue.ResolvedDate]" routerLinkActive="active">**
`This is the line where it routes to issue-detail component and displays particular issue`
<li class="list-group-item" *ngIf="isCD"><strong>Created Date: </strong>{{issue.CreatedDate}}</li>
<li class="list-group-item" *ngIf="isDes"><strong>Description: </strong>{{issue.Description}}</li>
<li class="list-group-item" *ngIf="isSeverity"><strong>Severity: </strong>{{issue.Severity}}</li>
<li class="list-group-item" *ngIf="isStatus"><strong>Status: </strong>{{issue.Status}}</li>
<li class="list-group-item" *ngIf='issue.Status == "Resolved" && isRD'><strong>Resolved Date: </strong>{{issue.ResolvedDate}}</li>
</a> </ul>
</div>
</div>
</div>
</div>
</div>
issues.component.ts:
import { Component, OnInit } from '#angular/core';
import { LocaljsonService } from '../localjson.service';
import { NavigationExtras, Router } from 'node_modules/#angular/router';
#Component({
selector: 'app-issues',
templateUrl: './issues.component.html',
styleUrls: ['./issues.component.css']
})
export class IssuesComponent implements OnInit {
constructor(private _localjsonService: LocaljsonService, private _router: Router){
}
issues: any;
default: boolean;
upd8 = false;
uid: any;
customClicked = false;
filterClicked = false;
isCD = true;
isDes = true;
isSeverity = true;
isStatus = true;
isRD = true;
stafilter = 'none';
sevfilter = 'none';
ngOnInit() {
this.issues = this._localjsonService.getJSON();
if (this.issues.length < 2) {
this.default = true;
} else {
this.default = false;
}
console.log(this.calls);
}
customtoggle() {
this.customClicked = !this.customClicked;
}
filtertoggle() {
this.filterClicked = !this.filterClicked;
}
update(id: any) {
this.upd8 = true;
this.uid = id;
}
delete(id: any) {
for (let i = 1; i < this.issues.length; i++) {
if ( this.issues[i].Id === id ) {
this.issues.splice(i, 1);
}
}
this._localjsonService.setJSON(this.issues);
if (this.issues.length < 2) {
// this._router.navigate(['/issues']);
this.default = true;
}
}
}
issue-detail.component.ts:
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Router, Params } from '#angular/router';
import { Location } from "#angular/common";
import { LocaljsonService } from '../localjson.service';
import { AddnewComponent } from '../addnew/addnew.component';
import { count } from 'rxjs/operators';
#Component({
selector: 'app-issue-detail',
templateUrl: './issue-detail.component.html',
styleUrls: ['./issue-detail.component.css']
})
export class IssueDetailComponent implements OnInit {
description!:any;
createdDate!:string;
resolvedDate!:string;
severity!:string;
status!:string;
constructor(private route: ActivatedRoute, private router: Router,
private _localjsonService:LocaljsonService) {
}
ngOnInit(): void {
this.route.paramMap.forEach((params: Params) => {
console.log(params);
this.createdDate=params.get("CreatedDate");
this.description=params.get("Description");
console.log(this.description);
this.severity=params.get("Severity");
this.status=params.get("Status");
this.resolvedDate=params.get("ResolvedDate");
});
}
goBack(description:string): void {
// Query Parameter Approach
this.router.navigate(['/issues'], {queryParams: {viewedid: this.description}});
}
}
issue-detail.component.html:
<div>
<h2>Issue Details</h2>
<div class="card mx-auto" >
<div class="des">
<ul class="list-group">
<li class="list-group-item"><strong>Created Date: </strong>{{createdDate}}</li>
<li class="list-group-item"><strong>Description: </strong>{{description}}</li>
<li class="list-group-item"><strong>Severity: </strong>{{severity}}</li>
<li class="list-group-item"><strong>Status: </strong>{{status}}</li>
<li class="list-group-item"><strong>Resolved Date: </strong>{{resolvedDate}}</li>
</ul>
<a class="btn btn-primary" href="#" role="button" (click)="goBack(description.value)">Back</a>
</div>
</div>
</div>
issue-tracker.component.ts:(this is the root module)
<nav class="navbar navbar-expand-lg sticky-top navbar-dark navbar-fixed-top">
<a class="navbar-brand" routerLink='/about'><strong>Issue Tracker</strong></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" routerLink='/about' routerLinkActive='active'>About</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink='/issues' routerLinkActive='active'>View-Issue-List</a>
</li>
</ul>
<a class="nav-link btn btn-primary float-right" role="button" routerLink='/addnew' routerLinkActive='active'>Add New</a>
</div>
</nav>
<div class="container">
<router-outlet></router-outlet>
</div>

Related

Dynamically creating tabs in bootstrap, with each new tab having the same default content?

I want to make a page such that I start off with Landing Page and Add Tab[+]. Then if I click add tab, I get a New Tab, with a blank version of the Landing Page Template. I'm using Bootstrap for front end and Python for back end.
https://jsfiddle.net/ub9m4ayq/1/
<form method="post">
<input type="hidden" name="campaign_key" value="{{campaign.campaign}}">
<input type="hidden" name="new" value="{{new}}">
<fieldset>
<div class="nav flex-column nav-pills" id="page-tabs" role="tablist" aria-orientation="vertical">
<a class="nav-link active" id="landing-tab" data-toggle="pill" href="#v-pills-landing" role="tab"
aria-controls="v-pills-home" aria-selected="true">Landing Page</a>
<a class="nav-link" id="add-new-tab" data-toggle="pill" href="#v-pills-add-new" role="tab"
aria-controls="v-pills-profile" aria-selected="false">[+] Add Page</a>
</div>
<div class="tab-content" id="v-pills-tabContent">
<div class="tab-pane fade show active" id="v-pills-landing" role="tabpanel" aria-labelledby="v-pills-landing">
<div class="row">
<div class="col">
<div class="mb-3">
<label class="form-label">Page Title</label>
<input class="form-control" placeholder="Landing Page">
</div>
</div>
<div class="col">
<div class="mb-3">
<label class="form-label">URL</label>
<input class="form-control" type="text" name="page_url" placeholder="/index.html">
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Page template (preview)</label>
<textarea id="email_template" name="email_template">{}</textarea>
<div id="email_template_editor" style="height: 300px; width: 100%">
</div>
<script src="/static/ace-builds/src-min-noconflict/ace.js" type="text/javascript"
charset="utf-8"></script>
<script>
var editor_textarea = document.getElementById('email_template');
var editor_elem = document.getElementById('email_template_editor');
editor_textarea.style.display = 'none';
editor_elem.style.border = '1px solid #ccc';
var editor = ace.edit(editor_elem, { wrap: true });
editor.session.setMode("ace/mode/html");
//editor.setTheme("ace/theme/twilight");
editor.session.on('change', function () {
editor_textarea.value = editor.session.getValue();
});
</script>
</div>
</div>
<div class="tab-pane fade" id="v-pills-add-new" role="tabpanel" aria-labelledby="v-pills-add-new">
<p>Hi</p>
</div>
</div>
</fieldset>
<div class="mb-3">
<button class="btn btn-primary">Save</button>
</div>
</form>
Thanks!

Is there a way to make the delete icon appear for every card when I checked the checkbox?

I am unable to make the trash icon visible more than one when I checked the checkbox element.
The first card only shows the trash icon, and the rest of the cards are not showing.
I have tried getElementById, querySelectorAll and getElementsByClassName. Nothing works properly as expected.
Can you find the logic error in the code?
function check() {
if (document.querySelector(".check").checked == true) {
document.querySelector(".deleteButton").style.visibility = "visible";
} else {
document.querySelector(".deleteButton").style.visibility = "hidden";
}
}
.deleteButton {
visibility: hidden;
}
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="form-check">
<a onclick="check()">
<input type="checkbox" class="check">
</a>
</div>
<h4 class="card-title">
Description 1
<a class="btn btn-outline-info deleteButton" href="/delete-todo/?id1">
<i class="fas fa-trash-alt" disabled="disabled"></i>
</a>
</h4>
</div>
</div>
<br>
</div>
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="form-check">
<a onclick="check()">
<input type="checkbox" class="check">
</a>
</div>
<h4 class="card-title">
Description 2
<a class="btn btn-outline-info deleteButton" href="/delete-todo/?id2">
<i class="fas fa-trash-alt" disabled="disabled"></i>
</a>
</h4>
</div>
</div>
<br>
</div>
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="form-check">
<a onclick="check()">
<input type="checkbox" class="check">
</a>
</div>
<h4 class="card-title">
Description 3
<a class="btn btn-outline-info deleteButton" href="/delete-todo/?id3">
<i class="fas fa-trash-alt" disabled="disabled"></i>
</a>
</h4>
</div>
</div>
<br>
</div>
Don't wrap a checkbox in a link
Also delegate
I delegate from a div I called container. It needs to be the nearest common container for your cards
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("check")) {
tgt.closest(".card-body").querySelector(".deleteButton").classList.toggle("hide", !tgt.checked)
}
else if (tgt.closest("a").classList.contains("deleteButton")) {
e.preventDefault();
tgt.closest(".card").remove()
}
})
.hide {
display: none
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" crossorigin="anonymous" />
<div id="container">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="form-check">
<input type="checkbox" class="check">
</div>
<h4 class="card-title">
Description 1
<a class="btn btn-outline-info deleteButton hide" href="/delete-todo/?id1">
<i class="fas fa-trash-alt" disabled="disabled">Delete</i>
</a>
</h4>
</div>
</div>
<br>
</div>
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="form-check">
<input type="checkbox" class="check">
</div>
<h4 class="card-title">
Description 2
<a class="btn btn-outline-info deleteButton hide" href="/delete-todo/?id2">
<i class="fas fa-trash-alt" disabled="disabled">Delete</i>
</a>
</h4>
</div>
</div>
<br>
</div>
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="form-check">
<input type="checkbox" class="check">
</div>
<h4 class="card-title">
Description 3
<a class="btn btn-outline-info deleteButton hide" href="/delete-todo/?id3">
<i class="fas fa-trash-alt" disabled="disabled">Delete</i>
</a>
</h4>
</div>
</div>
<br>
</div>
</div>

Render component vue js into nav tab

I have a problem with render component (courses), when i want click in case "undergraduate" but the componenent renders in the last tab panel... help me please!, any idea how solve this problem? thanks.
in the image have the issue render only in the last nav tab enter image description here
here my code
Html
<div id="ofert" class="row py-4">
<div class="col-md-4 mb-2">
<div class="row">
<div class="col-xs-12 col-md-12 p-0">
<ul class="nav nav-tabs flex-column nav-ga-pills" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" ##click.prevent="navClick" data-graduation="Undergraduate" id="home-tab" data-toggle="tab" href="#undergraduate" role="tab" aria-controls="home" aria-selected="true">undergraduate</a>
</li>
<li class="nav-item">
<a class="nav-link" ##click.prevent="navClick" data-graduation="Postgraduate" id="profile-tab" data-toggle="tab" href="#postgraduate" role="tab" aria-controls="profile" aria-selected="false">oosgraduate</a>
</li>
</ul>
</div>
</div>
</div>
<div class="col-md-8">
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="undergraduate" role="tabpanel" aria-labelledby="home-tab">
<courses ref="courses" :static=`image`></courses>
</div >
<div class="tab-pane fade" id="postgraduate" role="tabpanel" aria-labelledby="profile-tab">
<courses ref="courses" :static=`image`></courses>
</div>
</div>
</div>
</div>
parent
import courses from '../components/microspecial/ofert.vue'
new Vue({
el: '#ofert',
components: { courses },
data() {
return {
graduationlevel: ''
}
},
methods: {
navClick(e) {
this.graduationlevel = e.currentTarget.dataset.graduation;
this.$refs.courses.showData(this.graduationlevel);
}
}
});
child
<template>
<div class="row bg-light">
<div v-for="item in courses" class="col-sm-12 col-md-6 p-4 border-bottom">
<div class="row ga-i-box-oferta">
<div class="col-md-12 mb-2 ga-tittle-oferta">
<h2>{{item.Name}}</h2>
</div>
<div class="d-none d-lg-block col-md-5">
<div><img class="border" :src="url +`/repository/microspecial/courses/` + item.Id + `.png`" alt="" width="130" /></div>
</div>
<div class="col-xs-12 col-lg-7 ga-i-box-oferta-info">
<i class="fas fa-barcode"></i><span>Snies: {{item.Snies}}</span><br>
<i class="fas fa-chalkboard-teacher"></i><span>{{item.MethodologyName}}</span><br />
<i class="fas fa-user-graduate"></i><span>{{item.Title}} </span>
<div class="ga-i-box-btn">
Más información <i class="fas fa-arrow-circle-right"></i>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['static'],
data() {
return {
courses: [],
url: this.static
}
},
methods: {
showData(graduationLevel) {
this.courses = [];
fetch(`/MicroSpecial/GetCourses?graduationLevel=${graduationLevel}`)
.then(respon => respon.json())
.then(response => {
this.courses = response;
})
.catch(response => {
})
}
}
}
</script>

JS Filter Not Working

I am currently developing a landing page website for a client to display a range of products.
I have created a filter in JS to filter some products but its not working.
The two radios are tagged with Motorola and when you select the Motorola it doesn't show them?
I would appreciate any help someone can give me.
I am not the most confident with javascript
<div class="container mg-b-40">
<div class="row">
<div class="col-lg-2">
<aside class="sidebar">
<h5 class="heading-primary">Filter</h5>
<ul class="shop-filters">
<li class="filter">
<input type="checkbox" value="motorola" id="motorola">
<label for="motorola">Motorola</label>
</li>
<li class="filter">
<input type="checkbox" value="hytera" id="hytera">
<label for="hytera">Hytera</label>
</li>
<li class="filter">
<input type="checkbox" value="icom" id="icom">
<label for="icom">Icom</label>
</li>
<li class="filter">
<input type="checkbox" value="vertex" id="vertex">
<label for="vertex">Vertex</label>
</li>
<li class="filter">
<input type="checkbox" value="kenwood" id="kenwood">
<label for="kenwood">Kenwood</label>
</li>
<li class="filter">
<input type="checkbox" value="savox" id="savox">
<label for="savox">Savox</label>
</li>
</ul>
</aside>
</div>
<div class="col-lg-10">
<div class="masonry-loader masonry-loader-showing">
<div class="row products product-thumb-info-list mt-3" data-plugin-masonry data-plugin-options="{'layoutMode': 'fitRows'}">
<div class="category motorola">
<div class="col-sm-6 col-lg-12 product">
<span class="product-thumb-info">
<span class="product-thumb-info-image">
<img alt="" class="img-fluid" src="https://cdn.shopify.com/s/files/1/1148/2692/products/dp1400-01_Radio_Shop_UK_b113f82f-a13b-4ffa-93fd-612f313084ef.jpg?v=1529421291">
</span>
<span class="product-thumb-info-content">
<h4 class="heading-brand">Motorola DP1400</h4>
<div class="btn-group action-group" role="group" aria-label="Action Buttons">
Call Now
<a href="" class="btn btn-secondary btn-buy" rel=”nofollow”>Buy Now</a>
</div>
</span>
</span>
</div>
</div>
<div class="category hytera">
<div class="col-sm-6 col-lg-12 product">
<span class="product-thumb-info">
<span class="product-thumb-info-image">
<img alt="" class="img-fluid" src="https://cdn.shopify.com/s/files/1/1148/2692/products/dp1400-01_Radio_Shop_UK_b113f82f-a13b-4ffa-93fd-612f313084ef.jpg?v=1529421291">
</span>
<span class="product-thumb-info-content">
<h4 class="heading-brand">Motorola DP1400</h4>
<div class="btn-group action-group" role="group" aria-label="Action Buttons">
Call Now
<a href="" class="btn btn-secondary btn-buy" rel=”nofollow”>Buy Now</a>
</div>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(':input').change(function(evt){
var filter = $(':input:checked,select').map(function(index, el) {
return "." + el.value;
}).toArray().join("");
$(".product").hide().filter(filter).show();
});
</script>
The problem with your code is that you're hiding .product, but actual item to be hidden is .category. See below the working demo.
$(':input').change(function(evt) {
var filter = $(':input:checked, select').map(function(_, el) {
return "." + el.value;
}).toArray().join("");
$(".category").hide().filter(filter).show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container mg-b-40">
<div class="row">
<div class="col-lg-2">
<aside class="sidebar">
<h5 class="heading-primary">Filter</h5>
<ul class="shop-filters">
<li class="filter">
<input type="checkbox" value="motorola" id="motorola">
<label for="motorola">Motorola</label>
</li>
<li class="filter">
<input type="checkbox" value="hytera" id="hytera">
<label for="hytera">Hytera</label>
</li>
<li class="filter">
<input type="checkbox" value="icom" id="icom">
<label for="icom">Icom</label>
</li>
<li class="filter">
<input type="checkbox" value="vertex" id="vertex">
<label for="vertex">Vertex</label>
</li>
<li class="filter">
<input type="checkbox" value="kenwood" id="kenwood">
<label for="kenwood">Kenwood</label>
</li>
<li class="filter">
<input type="checkbox" value="savox" id="savox">
<label for="savox">Savox</label>
</li>
</ul>
</aside>
</div>
<div class="col-lg-10">
<div class="masonry-loader masonry-loader-showing">
<div class="row products product-thumb-info-list mt-3" data-plugin-masonry data-plugin-options="{'layoutMode': 'fitRows'}">
<div class="category motorola">
<div class="col-sm-6 col-lg-12 product">
<span class="product-thumb-info">
<span class="product-thumb-info-image">
<img alt="" class="img-fluid" src="https://cdn.shopify.com/s/files/1/1148/2692/products/dp1400-01_Radio_Shop_UK_b113f82f-a13b-4ffa-93fd-612f313084ef.jpg?v=1529421291">
</span>
<span class="product-thumb-info-content">
<h4 class="heading-brand">Motorola DP1400</h4>
<div class="btn-group action-group" role="group" aria-label="Action Buttons">
Call Now
<a href="" class="btn btn-secondary btn-buy" rel=”nofollow”>Buy Now</a>
</div>
</span>
</span>
</div>
</div>
<div class="category hytera">
<div class="col-sm-6 col-lg-12 product">
<span class="product-thumb-info">
<span class="product-thumb-info-image">
<img alt="" class="img-fluid" src="https://cdn.shopify.com/s/files/1/1148/2692/products/dp1400-01_Radio_Shop_UK_b113f82f-a13b-4ffa-93fd-612f313084ef.jpg?v=1529421291">
</span>
<span class="product-thumb-info-content">
<h4 class="heading-brand">Hytera</h4>
<div class="btn-group action-group" role="group" aria-label="Action Buttons">
Call Now
<a href="" class="btn btn-secondary btn-buy" rel=”nofollow”>Buy Now</a>
</div>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>

How to validate in each step the required fields? (that is, the next button should only work if required fields are valid and not empty)

I´m creating a multi-step form using bootstrap and jquery with 4 steps.
But I want that in each step validate the required fields, that is, the button to go to the next step should only work if the required fields are not empty.
But I´m not having success implementing this part of validating each step the required fields. Do you know how to do that?
Working example: https://jsfiddle.net/4vzf9qgr/2/
Jquery:
$(function(){
// navigation buttons
$('a.nav-link').on('show.bs.tab', function (e) {
var $target = $(e.target);
if ($target.parent().hasClass('disabled')) {
e.preventDefault();
}
});
$(".next-step").click(function (e) {
var $active = $('.nav-pills li a.active');
$active.parent().next().removeClass('disabled');
nextTab($active);
});
$(".prev-step").click(function (e) {
var $active = $('.nav-pills li a.active');
prevTab($active);
});
function nextTab(elem) {
$(elem).parent().next().find('a.nav-link').click();
}
function prevTab(elem) {
$(elem).parent().prev().find('a.nav-link').click();
}
});
HTML
<div class="bg-light-gray2">
<div class="container nopadding py-4">
<div class="row justify-content-center align-items-center">
<div class="col-12">
<h1 class="h5 text-center text-heading-blue font-weight-bold">Page Title</h1>
</div>
</div>
<div class="row mt-3 d-flex justify-content-center">
<div class="col-12">
<div class="registration_form">
<ul class="nav nav-pills bg-light-gray registration_form_list" role="tablist">
<li class="">
<a class="nav-link active" href="#step1" data-toggle="tab" role="tab">
Step 1<br><small class="d-none d-md-inline-block">General Info</small></a>
</li>
<li class="disabled">
<a class="nav-link" href="#step2" data-toggle="tab" role="tab">
Step 2<br><small class="d-none d-md-inline-block">Conference Creator Info</small></a>
</li>
<li class="disabled">
<a class="nav-link" href="#step3" data-toggle="tab" role="tab">
Step 3<br><small class="d-none d-md-inline-block">Registration Types</small></a>
</li>
</ul>
<form method="post" name="test" class="clearfix" action="/conference/store">
<div class="tab-content registration_body bg-white" id="myTabContent">
<div class="tab-pane fade show active clearfix" id="step1" role="tabpanel" aria-labelledby="home-tab">
<div class="form-group">
<label for="conference_name" class="text-heading h6 font-weight-semi-bold">Conference Name</label>
<input type="text" required class="form-control" name="conference_name" id="conference_name">
</div>
<div class="form-row">
<div class="form-group col-lg-6">
<label for="conference_categories" class="text-heading h6 font-weight-semi-bold">Categories</label>
<select id="tag_list" multiple class="form-control" name="conference_categories" id="conference_categories">
<option>category1</option>
<option>category2</option>
</select>
</div>
</div>
<div class="form-group">
<label for="textarea" class="text-heading h6 font-weight-semi-bold">Description</label>
<textarea class="form-control" name="conference_description" id="textarea" rows="3"></textarea>
</div>
<div class="float-right">
<button type="button" href="#step2" data-toggle="tab" role="tab"
class="btn mr-2 btn-primary btn next-step">
Go To Step 2
</button>
</div>
</div>
<div class="tab-pane fade clearfix" id="step2" role="tabpanel" aria-labelledby="profile-tab">
<div class="form-group">
<label for="conference_organizer_description" class="text-heading h6 font-weight-semi-bold">Description</label>
<textarea name="organizer_description" id="conference_organizer_description" class="form-control" rows="3"></textarea>
</div>
<button type="button" href="#step1" data-toggle="tab" role="tab"
class="btn mr-2 btn-outline-primary btn prev-step">
Back to Step 1
</button>
<button type="button" href="#step3" data-toggle="tab" role="tab"
class="btn mr-2 btn-primary btn next-step">
Go To Step 3
</button>
</div>
<div class="tab-pane clearfix fade" id="step3" role="tabpanel" aria-labelledby="contact-tab">
<div class="form-group">
<label for="registration_type_name" class="text-heading h6 font-weight-semi-bold">Registration Type Name</label>
<input type="text" required class="form-control" name="registration_type_name" id="registration_type_name">
</div>
<div class="form-group">
<label for="registration_type_description" class="text-heading h6 font-weight-semi-bold">Registration Type Description</label>
<input type="text" class="form-control" name="registration_type_description" id="registration_type_description">
</div>
<button type="button" href="#step2" data-toggle="tab" role="tab"
class="btn mr-2 btn-outline-primary btn prev-step">
Go Back To Step 2
</button>
<button type="submit"
class="btn mr-2 btn-primary btn">
Store
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
One way to do it is to use the div IDs that you have ("#step1", "#step2", etc) and have the button be disabled unless the following function returns true:
function validateForm(divId)
{
var inputs, index;
var form=document.getElementById(formId);
inputs = form.getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
// deal with inputs[index] element.
if (inputs[index].value==null || inputs[index].value=="")
{
alert("Field is empty");
$(buttonID).prop('disabled', true);
return
}
}
$(buttonID).prop('disabled', false);
}
Update/Additional comments:
I changed the function above to set the button instead of returning anything. At form load, have the button be disabled. Then add an onfocus attr to run an event listener like this:
function validateFormListener(divID, formObject) {
formObject.addEventListener("input", function(evt) {
validateForm(divID, buttonID)
})
}
Give the button an ID, then replace buttonID in the examples with this name. Change the input tags to look like this:
<input type="text" required class="form-control" onfocus="validateFormListener('#step1', buttonID, this)" name="conference_name" id="conference_name">

Categories

Resources