1675257841
Please watch the video https://youtu.be/N0TAP4NGN0g
#html #css #javascript #jquery #login #registration #webdevelopement
Please visit https://www.codertutorial.com for more such articles.
Please like, share and subscribe if you found this short helpful.
1675082807
Building a 3D Image Slider Using JavaScript, HTML & CSS With Slider Setting
Please visit codertutorial.com for such details articles.
Please Like, Share, and Subscribe.
#javascript #html #web-development #css #jquery #code
1674824880
Adding pagination on the page becomes easier with the DataTables plugin. It comes with all the basic features that require in pagination like – searching, sorting, rows per page, etc.
You can add action buttons to the list. For these need to update the AJAX script.
In this tutorial, I show how you can add a toggle button to change user status in DataTable AJAX pagination with PHP.
Create employees
table and I added some records.
CREATE TABLE `employees` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`emp_name` varchar(80) NOT NULL,
`gender` varchar(10) NOT NULL,
`city` varchar(80) NOT NULL,
`email` varchar(80) NOT NULL,
`status` smallint(2) NOT NULL
);
Change the value of the status
field from the toggle button in DataTable.
Create a config.php
for the database connection.
Completed Code
<?php
$host = "localhost"; /* Host name */
$user = "root"; /* User */
$password = ""; /* Password */
$dbname = "tutorial"; /* Database name */
$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
die("Connection failed: " . mysqli_connect_error());
}
<!-- Datatable CSS -->
<link href='//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'>
<!-- jQuery Library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Datatable JS -->
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
For toggle button add some CSS.
Create a <table id="empTable" >
. Initialize DataTables on this <table >
using jQuery.
Completed Code
<style type="text/css">
/* Toggle button */
#empTable .switch {
position: relative;
display: inline-block;
width: 45px;
height: 22px;
}
#empTable .switch input {
opacity: 0;
width: 0;
height: 0;
}
#empTable .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
#empTable .slider:before {
position: absolute;
content: "";
height: 17px;
width: 17px;
left: 1px;
bottom: 3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
#empTable input:checked + .slider {
background-color: #007bff;
}
#empTable input:focus + .slider {
box-shadow: 0 0 1px #007bff;
}
#empTable input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
#empTable .slider.round {
border-radius: 34px;
}
#empTable .slider.round:before {
border-radius: 50%;
}
/*********/
</style>
<div >
<!-- Table -->
<table id='empTable' class='display dataTable'>
<thead>
<tr>
<th>Employee name</th>
<th>Email</th>
<th>Gender</th>
<th>City</th>
<th>Status</th>
</tr>
</thead>
</table>
</div>
Initialize DataTable
Initialize DataTable on #empTable
. Set AJAX URL to ajaxfile.php
. Pass paginationData
with data.request
. Specify key names that need to be read in columns
option.
Change status
Define change
event on changeuserstatus
class. Read update id from data-id
attribute. Check if the checkbox is checked or not. If checked then store 1
in status
variable. Send AJAX request to ajaxfile.php
where pass {request: 'changeStatus',status: status,id: empid}
as data.
Completed Code
$(document).ready(function(){
// DataTable
var dataTable = $('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'searching': true, // Set false to Remove default Search Control
'ajax': {
'url':'ajaxfile.php',
'data': function(data){
// Append to data
data.request = "paginationData";
}
},
'columns': [
{ data: 'emp_name' },
{ data: 'email' },
{ data: 'gender' },
{ data: 'city' },
{ data: 'status' },
]
});
// Change user status
$('#empTable').on('click','.changeuserstatus',function(e){
if (confirm("Are you sure?") == true) {
var empid = $(this).attr('data-id');
var status = 0;
if($(this).is(":checked")){
status = 1;
}
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: {request: 'changeStatus',status: status,id: empid},
success: function(response){
console.log(response);
}
});
}else{
e.preventDefault();
}
});
});
Create ajaxfile.php
file for AJAX request handling.
From this file handle 2 requests –
Return DataTables data ($request == ‘paginationData’) –
Read DataTables POST data and assign them to the variables. In the $searchQuery
variable store search query on fields if $searchValue
is not empty.
Count the total number of records with and without search filter from the employees
table and assign count value to the variables.
Fetch records from the employees
table with search filter. Loop on the fetched records.
In the $status_html
store HTML layout for the toggle.
Initialize $data
Array with fetched data. Here, in the status
pass $status_html
.
In the $response
Array store all the required data and returns it in JSON format.
Update user status ($request == ‘changeStatus’) –
Read POST update id and status. Execute update query on employees
table to update status
field value with $status
where id = $empid
.
Completed Code
<?php
include 'config.php';
$request = "";
if(isset($_POST['request'])){
$request = $_POST['request'];
}
// Datatable Data
if($request == 'paginationData'){
## Read value
$draw = $_POST['draw'];
$row = $_POST['start'];
$rowperpage = $_POST['length']; // Rows display per page
$columnIndex = $_POST['order'][0]['column']; // Column index
$columnName = $_POST['columns'][$columnIndex]['data']; // Column name
$columnSortOrder = $_POST['order'][0]['dir']; // asc or desc
$searchValue = mysqli_real_escape_string($con,$_POST['search']['value']); // Search value
## Search
$searchQuery = " ";
if($searchValue != ''){
$searchQuery = " AND (emp_name LIKE '%".$searchValue."%' OR email LIKE '%".$searchValue."%' OR city LIKE'%".$searchValue."%' ) ";
}
## Total number of records without filtering
$records = mysqli_query($con,"SELECT COUNT(*) as allcount FROM employees");
$row = mysqli_fetch_assoc($records);
$totalRecords = $row['allcount'];
## Total number of records with filtering
$records = mysqli_query($con,"SELECT COUNT(*) as allcount FROM employees WHERE 1 ".$searchQuery);
$row = mysqli_fetch_assoc($records);
$totalRecordwithFilter = $row['allcount'];
## Fetch records
$sql = "SELECT * FROM employees WHERE 1 ".$searchQuery." ORDER BY ".$columnName." ".$columnSortOrder." LIMIT ".$row.",".$rowperpage;
$empRecords = mysqli_query($con, $sql);
$data = array();
while ($row = mysqli_fetch_assoc($empRecords)) {
$empid = $row['id'];
// Status
$checked = "";
if($row['status'] == 1){
$checked = "checked";
}
$status_html = '<label class="switch">
<input type="checkbox" '.$checked.' class="changeuserstatus" data-id="'.$empid.'" >
<span class="slider round"></span>
</label>';
$data[] = array(
"emp_name" => $row['emp_name'],
"email" => $row['email'],
"gender" => $row['gender'],
"city" => $row['city'],
"status "=> $status_html,
);
}
## Response
$response = array(
"draw" => intval($draw),
"iTotalRecords" => $totalRecords,
"iTotalDisplayRecords" => $totalRecordwithFilter,
"aaData" => $data
);
echo json_encode($response);
die;
}
// Change user status
if($request == 'changeStatus'){
$empid = $_POST['id'];
$status = $_POST['status'];
mysqli_query($con,"UPDATE employees SET status=".$status." WHERE id=".$empid);
echo 1;
die;
}
With this, you can change the status directly from the list instead of going to the edit form.
Following the same steps you can add more buttons for different operations.
You can also view this tutorial if you want to know how to add edit delete action button in the DataTables AJAX pagination.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1674817097
In this article, we will see a jquery datatable hide/show column based on condition. Here, we will learn how to hide and show a datatable column dynamically. You can make use of the column().visible() API method to dynamically show and hide columns in a datatable.
column().visible() is used to show and hide columns in datatable based on condition. Also, you can get/set the visibility of single and multiple selected columns.
So, let's see hide datatable column using jquery, show/hide column dynamically in datatable, jquery datatable add column dynamically, show/hide columns dynamically datatable, laravel 9 datatable hide and show columns dynamically.
Example:
We will check the column based on the condition and get the visibility status of column index 1.
var table = $('#example').DataTable();
alert( 'Column index 1 is '+
(table.column( 1 ).visible() === true ? 'visible' : 'not visible')
);
Example:
Hide the second column in the table. You can hide and show any column using the true and false.
var table = $('#example').DataTable();
table.column( 1 ).visible( false );
Example:
In this example, we will see on click you can hide and show columns in datatable.
<div>
Toggle column: <a class="toggle-vis" data-column="0">Name</a> - <a class="toggle-vis" data-column="1">Position</a> - <a class="toggle-vis" data-column="2">Office</a> - <a class="toggle-vis" data-column="3">Age</a> - <a class="toggle-vis" data-column="4">Start date</a> - <a class="toggle-vis" data-column="5">Salary</a>
</div>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bruno Nash</td>
<td>Software Engineer</td>
<td>London</td>
<td>38</td>
<td>2011-05-03</td>
<td>$163,500</td>
</tr>
<tr>
<td>Sakura Yamamoto</td>
<td>Support Engineer</td>
<td>Tokyo</td>
<td>37</td>
<td>2009-08-19</td>
<td>$139,575</td>
</tr>
<tr>
<td>Thor Walton</td>
<td>Developer</td>
<td>New York</td>
<td>61</td>
<td>2013-08-11</td>
<td>$98,540</td>
</tr>
<tr>
<td>Finn Camacho</td>
<td>Support Engineer</td>
<td>San Francisco</td>
<td>47</td>
<td>2009-07-07</td>
<td>$87,500</td>
</tr>
<tr>
<td>Serge Baldwin</td>
<td>Data Coordinator</td>
<td>Singapore</td>
<td>64</td>
<td>2012-04-09</td>
<td>$138,575</td>
</tr>
<tr>
<td>Zenaida Frank</td>
<td>Software Engineer</td>
<td>New York</td>
<td>63</td>
<td>2010-01-04</td>
<td>$125,250</td>
</tr>
<tr>
<td>Zorita Serrano</td>
<td>Software Engineer</td>
<td>San Francisco</td>
<td>56</td>
<td>2012-06-01</td>
<td>$115,000</td>
</tr>
<tr>
<td>Jennifer Acosta</td>
<td>Junior Javascript Developer</td>
<td>Edinburgh</td>
<td>43</td>
<td>2013-02-01</td>
<td>$75,650</td>
</tr>
<tr>
<td>Cara Stevens</td>
<td>Sales Assistant</td>
<td>New York</td>
<td>46</td>
<td>2011-12-06</td>
<td>$145,600</td>
</tr>
<tr>
<td>Hermione Butler</td>
<td>Regional Director</td>
<td>London</td>
<td>47</td>
<td>2011-03-21</td>
<td>$356,250</td>
</tr>
<tr>
<td>Lael Greer</td>
<td>Systems Administrator</td>
<td>London</td>
<td>21</td>
<td>2009-02-27</td>
<td>$103,500</td>
</tr>
<tr>
<td>Jonas Alexander</td>
<td>Developer</td>
<td>San Francisco</td>
<td>30</td>
<td>2010-07-14</td>
<td>$86,500</td>
</tr>
<tr>
<td>Shad Decker</td>
<td>Regional Director</td>
<td>Edinburgh</td>
<td>51</td>
<td>2008-11-13</td>
<td>$183,000</td>
</tr>
<tr>
<td>Michael Bruce</td>
<td>Javascript Developer</td>
<td>Singapore</td>
<td>29</td>
<td>2011-06-27</td>
<td>$183,000</td>
</tr>
<tr>
<td>Donna Snider</td>
<td>Customer Support</td>
<td>New York</td>
<td>27</td>
<td>2011-01-25</td>
<td>$112,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
Read Also: Laravel 9 AJAX CRUD Example
jQuery:
$(document).ready(function () {
var table = $('#example').DataTable({
scrollY: '200px',
paging: false,
});
$('a.toggle-vis').on('click', function (e) {
e.preventDefault();
// Get the column API object
var column = table.column($(this).attr('data-column'));
// Toggle the visibility
column.visible(!column.visible());
});
});
Original article source at: https://websolutionstuff.com/
1674813120
In this article, we will see how to validate multi step form wizard using jquery. Here, we will learn to validate the multi step form using jquery. First, we create the multi step form using bootstrap. Also, in this example, we are not using any jquery plugin for multi step form wizard.
So, let's see jquery multi step form with validation, how to create multi step form, multi step form wizard with jquery validation, bootstrap 4 multi step form wizard with validation, multi step form bootstrap 5, and jQuery multi step form with validation and next previous navigation.
Add HTML:
<html lang="en">
</head>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet">
</head>
<body>
<div class="main">
<h3>How To Validate Multi Step Form Using jQuery - Websolutionstuff</h3>
<form id="multistep_form">
<!-- progressbar -->
<ul id="progress_header">
<li class="active"></li>
<li></li>
<li></li>
</ul>
<!-- Step 01 -->
<div class="multistep-box">
<div class="title-box">
<h2>Create your account</h2>
</div>
<p>
<input type="text" name="email" placeholder="Email" id="email">
<span id="error-email"></span>
</p>
<p>
<input type="password" name="pass" placeholder="Password" id="pass">
<span id="error-pass"></span>
</p>
<p>
<input type="password" name="cpass" placeholder="Confirm Password" id="cpass">
<span id="error-cpass"></span>
</p>
<p class="nxt-prev-button"><input type="button" name="next" class="fs_next_btn action-button" value="Next" /></p>
</div>
<!-- Step 02 -->
<div class="multistep-box">
<div class="title-box">
<h2>Social Profiles</h2>
</div>
<p>
<input type="text" name="twitter" placeholder="Twitter" id="twitter">
<span id="error-twitter"></span>
</p>
<p>
<input type="text" name="facebook" placeholder="Facebook" id="facebook">
<span id="error-facebook"></span>
</p>
<p>
<input type="text" name="linkedin" placeholder="Linkedin" id="linkedin">
<span id="error-linkedin"></span>
</p>
<p class="nxt-prev-button">
<input type="button" name="previous" class="previous action-button" value="Previous" />
<input type="button" name="next" class="ss_next_btn action-button" value="Next" />
</p>
</div>
<!-- Step 03 -->
<div class="multistep-box">
<div class="title-box">
<h2>Personal Details</h2>
</div>
<p>
<input type="text" name="fname" placeholder="First Name" id="fname">
<span id="error-fname"></span>
</p>
<p>
<input type="text" name="lname" placeholder="Last Name" id="lname">
<span id="error-lname"></span>
</p>
<p>
<input type="text" name="phone" placeholder="Phone" id="phone">
<span id="error-phone"></span>
</p>
<p>
<textarea name="address" placeholder="Address" id="address"></textarea>
<span id="error-address"></span>
</p>
<p class="nxt-prev-button"><input type="button" name="previous" class="previous action-button" value="Previous" />
<input type="submit" name="submit" class="submit_btn ts_next_btn action-button" value="Submit" />
</p>
</div>
</form>
<h1>You are successfully logged in</h1>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.0/jquery.easing.js" type="text/javascript"></script>
</body>
</html>
Add CSS:
body {
display: inline-block;
width: 100%;
height: 100vh;
overflow: hidden;
background-image: url("https://img1.akspic.com/image/80377-gadget-numeric_keypad-input_device-electronic_device-space_bar-3840x2160.jpg");
background-repeat: no-repeat;
background-size: cover;
position: relative;
margin: 0;
font-weight: 400;
font-family: 'Roboto', sans-serif;
}
body:before {
content: "";
display: block;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.main {
position: absolute;
left: 0;
right: 0;
top: 30px;
margin: 0 auto;
height: 515px;
}
input:-internal-autofill-selected {
background-color: #fff !important;
}
#multistep_form {
width: 550px;
margin: 0 auto;
text-align: center;
position: relative;
height: 100%;
z-index: 999;
opacity: 1;
visibility: visible;
}
/*progress header*/
#progress_header {
overflow: hidden;
margin: 0 auto 30px;
padding: 0;
}
#progress_header li {
list-style-type: none;
width: 33.33%;
float: left;
position: relative;
font-size: 16px;
font-weight: bold;
font-family: monospace;
color: #fff;
text-transform: uppercase;
}
#progress_header li:after {
width: 35px;
line-height: 35px;
display: block;
font-size: 22px;
color: #888;
font-family: monospace;
background-color: #fff;
border-radius: 100px;
margin: 0 auto;
background-repeat: no-repeat;
font-family: 'Roboto', sans-serif;
}
#progress_header li:nth-child(1):after {
content: "1";
}
#progress_header li:nth-child(2):after {
content: "2";
}
#progress_header li:nth-child(3):after {
content: "3";
}
#progress_header li:before {
content: '';
width: 100%;
height: 5px;
background: #fff;
position: absolute;
left: -50%;
top: 50%;
z-index: -1;
}
#progress_header li:first-child:before {
content: none;
}
#progress_header li.active:before,
#progress_header li.active:after {
background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b) !important;
color: #fff !important;
transition: all 0.5s;
}
/*title*/
.title-box {
width: 100%;
margin: 0 0 30px 0;
}
.title-box h2 {
font-size: 22px;
text-transform: uppercase;
color: #2C3E50;
margin: 0;
font-family: cursive;
display: inline-block;
position: relative;
padding: 0 0 10px 0;
font-family: 'Roboto', sans-serif;
}
.title-box h2:before {
content: "";
background: #6ddc8b;
width: 70px;
height: 2px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: 0 auto;
display: block;
}
.title-box h2:after {
content: "";
background: #6ddc8b;
width: 50px;
height: 2px;
position: absolute;
bottom: -5px;
left: 0;
right: 0;
margin: 0 auto;
display: block;
}
/*Input and Button*/
.multistep-box {
background: white;
border: 0 none;
border-radius: 3px;
box-shadow: 1px 1px 55px 3px rgba(255, 255, 255, 0.4);
padding: 30px 30px;
box-sizing: border-box;
width: 80%;
margin: 0 10%;
position: absolute;
}
.multistep-box:not(:first-of-type) {
display: none;
}
.multistep-box p {
margin: 0 0 12px 0;
text-align: left;
}
.multistep-box span {
font-size: 12px;
color: #FF0000;
}
input, textarea {
padding: 15px;
border: 1px solid #ccc;
border-radius: 3px;
margin: 0;
width: 100%;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
color: #2C3E50;
font-size: 13px;
transition: all 0.5s;
outline: none;
}
input:focus, textarea:focus {
box-shadow: inset 0px 0px 50px 2px rgb(0,0,0,0.1);
}
input.box_error, textarea.box_error {
border-color: #FF0000;
box-shadow: inset 0px 0px 50px 2px rgb(255,0,0,0.1);
}
input.box_error:focus, textarea.box_error:focus {
box-shadow: inset 0px 0px 50px 2px rgb(255,0,0,0.1);
}
p.nxt-prev-button {
margin: 25px 0 0 0;
text-align: center;
}
.action-button {
width: 100px;
font-weight: bold;
color: white;
border: 0 none;
border-radius: 1px;
cursor: pointer;
padding: 10px 5px;
margin: 0 5px;
background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b);
transition: all 0.5s;
}
.action-button:hover,
.action-button:focus {
box-shadow: 0 0 0 2px white, 0 0 0 3px #6ce199;
}
.form_submited #multistep_form {
opacity: 0;
visibility: hidden;
}
.form_submited h1 {
-webkit-background-clip: text;
transform: translate(0%, 0%);
-webkit-transform: translate(0%, 0%);
transition: all 0.3s ease;
opacity: 1;
visibility: visible;
}
h1 {
margin: 0;
text-align: center;
font-size: 90px;
background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b) !important;
background-image: linear-gradient(to right top, #35e8c3, #36edbb, #3df2b2, #4af7a7, #59fb9b) !important;
color: transparent;
-webkit-background-clip: text;
-webkit-background-clip: text;
transform: translate(0%, -80%);
-webkit-transform: translate(0%, -80%);
transition: all 0.3s ease;
opacity: 0;
visibility: hidden;
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
text-align: center;
top: 50%;
}
h3{
color:#fff;
text-align:center;
margin-bottom:20px;
}
Add jQuery:
var current_slide, next_slide, previous_slide;
var left, opacity, scale;
var animation;
var error = false;
// email validation
$("#email").keyup(function() {
var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
if (!emailReg.test($("#email").val())) {
$("#error-email").text('Please enter an Email addres.');
$("#email").addClass("box_error");
error = true;
} else {
$("#error-email").text('');
error = false;
$("#email").removeClass("box_error");
}
});
// password validation
$("#pass").keyup(function() {
var pass = $("#pass").val();
var cpass = $("#cpass").val();
if (pass != '') {
$("#error-pass").text('');
error = false;
$("#pass").removeClass("box_error");
}
if (pass != cpass && cpass != '') {
$("#error-cpass").text('Password and Confirm Password is not matched.');
error = true;
} else {
$("#error-cpass").text('');
error = false;
}
});
// confirm password validation
$("#cpass").keyup(function() {
var pass = $("#pass").val();
var cpass = $("#cpass").val();
if (pass != cpass) {
$("#error-cpass").text('Please enter the same Password as above.');
$("#cpass").addClass("box_error");
error = true;
} else {
$("#error-cpass").text('');
error = false;
$("#cpass").removeClass("box_error");
}
});
// twitter
$("#twitter").keyup(function() {
var twitterReg = /https?:\/\/twitter\.com\/(#!\/)?[a-z0-9_]+$/;
if (!twitterReg.test($("#twitter").val())) {
$("#error-twitter").text('Twitter link is not valid.');
$("#twitter").addClass("box_error");
error = true;
} else {
$("#error-twitter").text('');
error = false;
$("#twitter").removeClass("box_error");
}
});
// facebook
$("#facebook").keyup(function() {
var facebookReg = /^(https?:\/\/)?(www\.)?facebook.com\/[a-zA-Z0-9(\.\?)?]/;
if (!facebookReg.test($("#facebook").val())) {
$("#error-facebook").text('Facebook link is not valid.');
$("#facebook").addClass("box_error");
error = true;
} else {
$("#error-facebook").text('');
error = false;
$("#facebook").removeClass("box_error");
}
});
// linkedin
$("#linkedin").keyup(function() {
var linkedinReg = /(ftp|http|https):\/\/?(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if (!linkedinReg.test($("#linkedin").val())) {
$("#error-linkedin").text('Linkedin link is not valid.');
$("#linkedin").addClass("box_error");
error = true;
} else {
$("#error-linkedin").text('');
error = false;
$("#linkedin").removeClass("box_error");
}
});
// first name
$("#fname").keyup(function() {
var fname = $("#fname").val();
if (fname == '') {
$("#error-fname").text('Enter your First name.');
$("#fname").addClass("box_error");
error = true;
} else {
$("#error-fname").text('');
error = false;
}
if ((fname.length <= 2) || (fname.length > 20)) {
$("#error-fname").text("User length must be between 2 and 20 Characters.");
$("#fname").addClass("box_error");
error = true;
}
if (!isNaN(fname)) {
$("#error-fname").text("Only Characters are allowed.");
$("#fname").addClass("box_error");
error = true;
} else {
$("#fname").removeClass("box_error");
}
});
// last name
$("#lname").keyup(function() {
var lname = $("#lname").val();
if (lname != lname) {
$("#error-lname").text('Enter your Last name.');
$("#lname").addClass("box_error");
error = true;
} else {
$("#error-lname").text('');
error = false;
}
if ((lname.length <= 2) || (lname.length > 20)) {
$("#error-lname").text("User length must be between 2 and 20 Characters.");
$("#lname").addClass("box_error");
error = true;
}
if (!isNaN(lname)) {
$("#error-lname").text("Only Characters are allowed.");
$("#lname").addClass("box_error");
error = true;
} else {
$("#lname").removeClass("box_error");
}
});
// phone
$("#phone").keyup(function() {
var phone = $("#phone").val();
if (phone != phone) {
$("#error-phone").text('Enter your Phone number.');
$("#phone").addClass("box_error");
error = true;
} else {
$("#error-phone").text('');
error = false;
}
if (phone.length != 10) {
$("#error-phone").text("Mobile number must be of 10 Digits only.");
$("#phone").addClass("box_error");
error = true;
} else {
$("#phone").removeClass("box_error");
}
});
// address
$("#address").keyup(function() {
var address = $("#address").val();
if (address != address) {
$("#error-address").text('Enter your Address.');
$("#address").addClass("box_error");
error = true;
} else {
$("#error-address").text('');
error = false;
$("#address").removeClass("box_error");
}
});
// first step validation
$(".fs_next_btn").click(function() {
// email
if ($("#email").val() == '') {
$("#error-email").text('Please enter an email address.');
$("#email").addClass("box_error");
error = true;
} else {
var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
if (!emailReg.test($("#email").val())) {
$("#error-email").text('Please insert a valid email address.');
error = true;
} else {
$("#error-email").text('');
$("#email").removeClass("box_error");
}
}
// password
if ($("#pass").val() == '') {
$("#error-pass").text('Please enter a password.');
$("#pass").addClass("box_error");
error = true;
}
if ($("#cpass").val() == '') {
$("#error-cpass").text('Please enter a Confirm password.');
$("#cpass").addClass("box_error");
error = true;
} else {
var pass = $("#pass").val();
var cpass = $("#cpass").val();
if (pass != cpass) {
$("#error-cpass").text('Please enter the same password as above.');
error = true;
} else {
$("#error-cpass").text('');
$("#pass").removeClass("box_error");
$("#cpass").removeClass("box_error");
}
}
// animation
if (!error) {
if (animation) return false;
animation = true;
current_slide = $(this).parent().parent();
next_slide = $(this).parent().parent().next();
$("#progress_header li").eq($(".multistep-box").index(next_slide)).addClass("active");
next_slide.show();
current_slide.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_slide.css({
'transform': 'scale(' + scale + ')'
});
next_slide.css({
'left': left,
'opacity': opacity
});
},
duration: 800,
complete: function() {
current_slide.hide();
animation = false;
},
easing: 'easeInOutBack'
});
}
});
// second step validation
$(".ss_next_btn").click(function() {
// twitter
if ($("#twitter").val() == '') {
$("#error-twitter").text('twitter link is required.');
$("#twitter").addClass("box_error");
error = true;
} else {
var twitterReg = /https?:\/\/twitter\.com\/(#!\/)?[a-z0-9_]+$/;
if (!twitterReg.test($("#twitter").val())) {
$("#error-twitter").text('Twitter link is not valid.');
error = true;
} else {
$("#error-twitter").text('');
$("#twitter").removeClass("box_error");
}
}
// facebook
if ($("#facebook").val() == '') {
$("#error-facebook").text('Facebook link is required.');
$("#facebook").addClass("box_error");
error = true;
} else {
var facebookReg = /^(https?:\/\/)?(www\.)?facebook.com\/[a-zA-Z0-9(\.\?)?]/;
if (!facebookReg.test($("#facebook").val())) {
$("#error-facebook").text('Facebook link is not valid.');
error = true;
$("#facebook").addClass("box_error");
} else {
$("#error-facebook").text('');
}
}
// linkedin
if ($("#linkedin").val() == '') {
$("#error-linkedin").text('Linkedin link is required.');
$("#linkedin").addClass("box_error");
error = true;
} else {
var linkedinReg = /(ftp|http|https):\/\/?(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if (!linkedinReg.test($("#linkedin").val())) {
$("#error-linkedin").text('Linkedin link is not valid.');
error = true;
} else {
$("#error-linkedin").text('');
$("#linkedin").removeClass("box_error");
}
}
if (!error) {
if (animation) return false;
animation = true;
current_slide = $(this).parent().parent();
next_slide = $(this).parent().parent().next();
$("#progress_header li").eq($(".multistep-box").index(next_slide)).addClass("active");
next_slide.show();
current_slide.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_slide.css({
'transform': 'scale(' + scale + ')'
});
next_slide.css({
'left': left,
'opacity': opacity
});
},
duration: 800,
complete: function() {
current_slide.hide();
animation = false;
},
easing: 'easeInOutBack'
});
}
});
// third step validation
$(".ts_next_btn").click(function() {
// first name
if ($("#fname").val() == '') {
$("#error-fname").text('Enter your First name.');
$("#fname").addClass("box_error");
error = true;
} else {
var fname = $("#fname").val();
if (fname != fname) {
$("#error-fname").text('First name is required.');
error = true;
} else {
$("#error-fname").text('');
error = false;
$("#fname").removeClass("box_error");
}
if ((fname.length <= 2) || (fname.length > 20)) {
$("#error-fname").text("User length must be between 2 and 20 Characters.");
error = true;
}
if (!isNaN(fname)) {
$("#error-fname").text("Only Characters are allowed.");
error = true;
} else {
$("#fname").removeClass("box_error");
}
}
// last name
if ($("#lname").val() == '') {
$("#error-lname").text('Enter your Last name.');
$("#lname").addClass("box_error");
error = true;
} else {
var lname = $("#lname").val();
if (lname != lname) {
$("#error-lname").text('Last name is required.');
error = true;
} else {
$("#error-lname").text('');
error = false;
}
if ((lname.length <= 2) || (lname.length > 20)) {
$("#error-lname").text("User length must be between 2 and 20 Characters.");
error = true;
}
if (!isNaN(lname)) {
$("#error-lname").text("Only Characters are allowed.");
error = true;
} else {
$("#lname").removeClass("box_error");
}
}
// phone
if ($("#phone").val() == '') {
$("#error-phone").text('Enter your Phone number.');
$("#phone").addClass("box_error");
error = true;
} else {
var phone = $("#phone").val();
if (phone != phone) {
$("#error-phone").text('Phone number is required.');
error = true;
} else {
$("#error-phone").text('');
error = false;
}
if (phone.length != 10) {
$("#error-phone").text("Mobile number must be of 10 Digits only.");
error = true;
} else {
$("#phone").removeClass("box_error");
}
}
// address
if ($("#address").val() == '') {
$("#error-address").text('Enter your Address.');
$("#address").addClass("box_error");
error = true;
} else {
var address = $("#address").val();
if (address != address) {
$("#error-address").text('Address is required.');
error = true;
} else {
$("#error-address").text('');
$("#address").removeClass("box_error");
error = false;
}
}
if (!error) {
if (animation) return false;
animation = true;
current_slide = $(this).parent().parent();
next_slide = $(this).parent().parent().next();
$("#progress_header li").eq($(".multistep-box").index(next_slide)).addClass("active");
next_slide.show();
current_slide.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_slide.css({
'transform': 'scale(' + scale + ')'
});
next_slide.css({
'left': left,
'opacity': opacity
});
},
duration: 800,
complete: function() {
current_slide.hide();
animation = false;
},
easing: 'easeInOutBack'
});
}
});
// previous
$(".previous").click(function() {
if (animation) return false;
animation = true;
current_slide = $(this).parent().parent();
previous_slide = $(this).parent().parent().prev();
$("#progress_header li").eq($(".multistep-box").index(current_slide)).removeClass("active");
previous_slide.show();
current_slide.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 0.8 + (1 - now) * 0.2;
left = ((1 - now) * 50) + "%";
opacity = 1 - now;
current_slide.css({
'left': left
});
previous_slide.css({
'transform': 'scale(' + scale + ')',
'opacity': opacity
});
},
duration: 800,
complete: function() {
current_slide.hide();
animation = false;
},
easing: 'easeInOutBack'
});
});
$(".submit_btn").click(function() {
if (!error){
$(".main").addClass("form_submited");
}
return false;
})
Output:
Original article source at: https://websolutionstuff.com/
1673877540
The 5 star rating system allows users to rate articles on a scale of 1 to 5.
It is a popular way for visitors to merchant websites to rate the quality of products and services. It is also commonly used to rate the quality of user-generated content, such as reviews and comments.
In this tutorial, I am creating a 5 star rating system in CodeIgniter 4 where the ratings will be stored in a database and the average rating will be displayed with the article. Users can rate an article and based on the rating the average rating gets updated.
.env
file which is available at the project root.NOTE – If dot (.) not added at the start then rename the file to .env.
database.default.hostname
, database.default.database
, database.default.username
, database.default.password
, database.default.DBDriver
, database.default.DBPrefix
, and database.default.port
.database.default.hostname = 127.0.0.1
database.default.database = codeigniterdb
database.default.username = root
database.default.password = root
database.default.DBDriver = MySQLi
database.default.DBPrefix =
database.default.port = 3306
.env
file.security.tokenName
,security.headerName
, security.cookieName
, security.expires
,and security.regenerate
.security.tokenName
value with 'csrf_hash_name'
. With this name read CSRF hash. You can update it with any other value.security.regenerate = false
.security.tokenName = 'csrf_hash_name' security.headerName = 'X-CSRF-TOKEN' security.cookieName = 'csrf_cookie_name' security.expires = 7200 security.regenerate = true
app/Config/Filters.php
file.'csrf'
in 'before'
if commented.// Always applied before every request
public $globals = [
'before' => [
// 'honeypot',
'csrf',
// 'invalidchars',
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
];
I am creating 2 tables using migration –
posts Table –
php spark migrate:create create_posts_table
app/Database/Migrations/
folder from the project root.CreatePostsTable
open it.up()
method.down()
method delete posts
table that calls when undoing migration.<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreatePostsTable extends Migration
{
public function up(){
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'auto_increment' => true,
],
'title' => [
'type' => 'VARCHAR',
'constraint' => '100',
],
'description' => [
'type' => 'TEXT',
'null' => true,
],
'link' => [
'type' => 'VARCHAR',
'constraint' => '255',
],
]);
$this->forge->addKey('id', true);
$this->forge->createTable('posts');
}
public function down(){
$this->forge->dropTable('posts');
}
}
post_ratings Table –
php spark migrate:create create_post_ratings_table
app/Database/Migrations/
folder from the project root.CreatePostRatingsTable
open it.up()
method. Added foreign key on post_id
field. I didn’t add a foreign key on user_id
but you can add it will implementing.down()
method delete post_ratings
table that calls when undoing migration.<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreatePostRatingsTable extends Migration
{
public function up(){
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'auto_increment' => true,
],
'user_id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
],
'post_id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
],
'rating' => [
'type' => 'VARCHAR',
'constraint' => 10
]
]);
$this->forge->addKey('id', true);
$this->forge->addForeignKey('post_id', 'posts', 'id', 'CASCADE', 'CASCADE');
$this->forge->createTable('post_ratings');
}
public function down(){
$this->forge->dropTable('post_ratings');
}
}
php spark migrate
Create 2 Models –
Posts Model –
Posts
Model –php spark make:model Posts
app/Models/Posts.php
file.$allowedFields
Array specify field names – ['title','description','link']
that can be set during insert and update.Completed Code
<?php
namespace App\Models;
use CodeIgniter\Model;
class Posts extends Model
{
protected $DBGroup = 'default';
protected $table = 'posts';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $insertID = 0;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = ['title','description','link'];
// Dates
protected $useTimestamps = false;
protected $dateFormat = 'datetime';
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
// Validation
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
protected $cleanValidationRules = true;
// Callbacks
protected $allowCallbacks = true;
protected $beforeInsert = [];
protected $afterInsert = [];
protected $beforeUpdate = [];
protected $afterUpdate = [];
protected $beforeFind = [];
protected $afterFind = [];
protected $beforeDelete = [];
protected $afterDelete = [];
}
PostRatings Model –
PostRatings
Model –php spark make:model PostRatings
app/Models/PostRatings.php
file.$allowedFields
Array specify field names – ['user_id','post_id','rating']
that can be set during insert and update.Completed Code
<?php
namespace App\Models;
use CodeIgniter\Model;
class PostRatings extends Model
{
protected $DBGroup = 'default';
protected $table = 'post_ratings';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $insertID = 0;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $protectFields = true;
protected $allowedFields = ['user_id','post_id','rating'];
// Dates
protected $useTimestamps = false;
protected $dateFormat = 'datetime';
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
// Validation
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
protected $cleanValidationRules = true;
// Callbacks
protected $allowCallbacks = true;
protected $beforeInsert = [];
protected $afterInsert = [];
protected $beforeUpdate = [];
protected $afterUpdate = [];
protected $beforeFind = [];
protected $afterFind = [];
protected $beforeDelete = [];
protected $afterDelete = [];
}
app/Config/Routes.php
file.$routes->get('/', 'PostsController::index');
$routes->get('post/updaterating', 'PostsController::updateRating');
PostsController
Controller –php spark make:controller PostsController
app/Controllers/PostsController.php
file.Posts
and PostRatings
Model.$userid
class variable to store user id for rating. You can update its value with logged-in SESSION user id.’Create 2 methods –
posts
table. Loop on the fetched records to get user rating on the post_ratings
table and calculate average rating of the post.Pass $userrating
and $avgrating
with post data.
Load index
view and pass $data
Array.
Read passed post_id
and rating
and assign them to the variables. Check if user has any rating on the $post_id
or not in the post_ratings
table.
If exists then update the rating
field value with $rating
otherwise insert a new record in the post_ratings
table.
Calculate the average rating of the $post_id
and assign to $data['avgrating']
.
Return $data
Array in JSON format.
Completed Code
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use App\Models\Posts;
use App\Models\PostRatings;
class PostsController extends BaseController
{
public $userid = 2;// Replace this value with your user SESSION variable
public function index(){
$postsObj = new Posts();
$postRatingsObj = new PostRatings();
// Fetch all posts
$postData = $postsObj->select('*')->findAll();
foreach($postData as $key=>$post){
## User Rating
$postratingData = $postRatingsObj->select('rating')
->where('post_id',$post['id'])
->where('user_id',$this->userid)
->find();
$userrating = 0;
if(!empty($postratingData)){
$userrating = $postratingData[0]['rating'];
}
## Post average rating
$postratingData = $postRatingsObj->select('ROUND(AVG(rating),1) as averageRating')
->where('post_id',$post['id'])
->find();
$avgrating = $postratingData[0]['averageRating'];
if($avgrating == ''){
$avgrating = 0;
}
$postData[$key]['userrating'] = $userrating;
$postData[$key]['avgrating'] = $avgrating;
}
$data['posts'] = $postData;
return view('index',$data);
}
public function updateRating(){
$request = service('request');
$getData = $request->getGet();
$post_id = $getData['post_id'];
$rating = $getData['rating'];
$postRatingsObj = new PostRatings();
// Check user rating
$postratingData = $postRatingsObj->select('id')
->where('post_id',$post_id)
->where('user_id',$this->userid)
->find();
if(!empty($postratingData)){
## Update user rating
$postrating_id = $postratingData[0]['id'];
$postRatingsObj->set('rating', $rating);
$postRatingsObj->where('id', $postrating_id);
$postRatingsObj->update();
}else{
## Insert user rating
$insdata = [
'user_id' => $this->userid,
'post_id' => $post_id,
'rating' => $rating
];
$postRatingsObj->insert($insdata);
}
// Calculate average rating
$postratingData = $postRatingsObj->select('ROUND(AVG(rating),1) as averageRating')
->where('post_id',$post_id)
->find();
$avgrating = $postratingData[0]['averageRating'];
if($rating == ''){
$avgrating = 0;
}
$data['avgrating'] = $avgrating;
return $this->response->setJSON($data);
}
}
index.php
file in app/Views/
folder.public/
folder.<!-- CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/fontawesome.min.css">
<link rel="stylesheet" href="<?= base_url('bootstrap-star-rating/css/star-rating.css') ?>" media="all" type="text/css"/>
<link rel="stylesheet" href="<?= base_url('bootstrap-star-rating/themes/krajee-svg/theme.css') ?>" media="all" type="text/css"/>
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="<?= base_url('bootstrap-star-rating/js/star-rating.min.js') ?>"></script>
$posts
. Display post data with 5 star rating bar.Adding Rating bar –
<input >
element with class rating rating-loading
and set data
attributes.<input class="rating rating-loading"
data-post_id="<?= $post['id'] ?>"
data-min="0"
data-max="5"
data-step="0.5"
data-show-clear="false"
data-show-caption="false"
data-size="md"
value="<?= $post['userrating'] ?>"
>
I have set the following data attributes –
false
to hide clear rating button.false
to hide the rating label.md
but you can change it to xl
, lg
, sm
, and xs
.In value
attribute stored the user rating $post['userrating']
.
To display the average rating created <span >
. It value gets updated using jQuery when rating is been changed.
jQuery –
Define change
event on rating
class to detect rating change. Assign selected rating in rating
variable and also read post_id
from the data
attribute.
Send AJAX request to post/updaterating
. Pass {post_id: post_id,rating:rating}
as data. On successful callback update average rating in <span >
.
Completed Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>5 Star Rating system with jQuery AJAX in CodeIgniter 4</title>
<style type="text/css">
.content{
border: 0px solid black;
border-radius: 3px;
padding: 5px;
margin: 0 auto;
width: 50%;
}
.post{
border-bottom: 1px solid black;
padding: 10px;
margin-top: 10px;
margin-bottom: 10px;
}
.post:last-child{
border: 0;
}
.post h2{
font-weight: normal;
font-size: 30px;
}
.post a.link{
text-decoration: none;
color: black;
}
.post-text{
letter-spacing: 1px;
font-size: 15px;
font-family: serif;
color: gray;
text-align: justify;
}
.post-action{
margin-top: 15px;
margin-bottom: 15px;
}
</style>
<!-- CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/fontawesome.min.css">
<link rel="stylesheet" href="<?= base_url('bootstrap-star-rating/css/star-rating.css') ?>" media="all" type="text/css"/>
<link rel="stylesheet" href="<?= base_url('bootstrap-star-rating/themes/krajee-svg/theme.css') ?>" media="all" type="text/css"/>
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="<?= base_url('bootstrap-star-rating/js/star-rating.min.js') ?>"></script>
</head>
<body>
<div class="content">
<?php
foreach($posts as $post){
?>
<div class="post">
<h2>
<a href='<?= $post['link'] ?>' class='link' target='_blank'><?= $post['title'] ?></a>
</h2>
<div class="post-text">
<?= $post['description'] ?>
</div>
<div class="post-action">
<!-- Rating Bar -->
<input class="rating rating-loading"
data-post_id="<?= $post['id'] ?>"
data-min="0"
data-max="5"
data-step="0.5"
data-show-clear="false"
data-show-caption="false"
data-size="md"
value="<?= $post['userrating'] ?>"
>
<div style='clear: both;'></div>
<!-- Display average rating -->
Average Rating : <span id='avgrating_<?= $post['id'] ?>'><?= $post['avgrating'] ?></span>
</div>
</div>
<?php
}
?>
</div>
<!-- Script -->
<script type="text/javascript">
$(document).ready(function(){
// Detect Rating change
$('.rating').on(
'change', function () {
var rating = $(this).val(); // Selected Rating
var post_id = $(this).data('post_id');
// AJAX request
$.ajax({
url:"<?=site_url('post/updaterating')?>",
data: {post_id: post_id,rating:rating},
dataType: 'json',
success: function(response){
// Update average rating
$('#avgrating_'+post_id).text(response.avgrating)
}
});
}
);
});
</script>
</body>
</html>
In the example, I have fixed the userid for rating. While implementing this on your project replace its value with the logged-in user id.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1673254694
This plugin can be used to read a RSS feed and transform it into a custom piece of HTML.
A vanilla JavaScript version of this library can be found here: Vanilla RSS. This plugin uses Feedr, a backend server that parses and converts RSS feeds into its JSON representation. The server was built as a drop-in replacement for Google's former Feed API.
Through npm:
$ npm install jquery
$ npm install jquery-rss
const $ = require('jquery');
require('jquery-rss'); // This will add the plugin to the jQuery namespace
Through cdnjs:
<script src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-rss/3.3.0/jquery.rss.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>jquery.rss example</title>
<script src="lib/jquery-1.6.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script>
<script src="dist/jquery.rss.min.js"></script>
<script>
jQuery(function($) {
$("#rss-feeds").rss("http://feeds.feedburner.com/premiumpixels");
});
</script>
</head>
<body>
<div id="rss-feeds"></div>
</body>
</html>
Demo link for above code: http://embed.plnkr.co/WQRoCYLld162uplnz1rc/preview
Note: Moment.js is optional. If you include it, jquery.rss will use it to format dates. If you do not want to include Moment.js, you may opt for providing your own date formatting function, or for not formatting dates at all.
$("#rss-feeds").rss(
// You can either provide a single feed URL or a list of URLs (via an array)
"http://feeds.feedburner.com/premiumpixels",
{
// how many entries do you want?
// default: 4
// valid values: any integer
limit: 10,
// want to offset results being displayed?
// default: false
// valid values: any integer
offsetStart: false, // offset start point
offsetEnd: false, // offset end point
// will request the API via https
// default: false
// valid values: false, true
ssl: true,
// which server should be requested for feed parsing
// the server implementation is here: https://github.com/sdepold/feedr
// default: feedrapp.info
// valid values: any string
host: "my-own-feedr-instance.com",
// option to seldomly render ads
// ads help covering the costs for the feedrapp server hosting and future improvements
// default: true
// valid values: false, true
support: false,
// outer template for the html transformation
// default: "<ul>{entries}</ul>"
// valid values: any string
layoutTemplate: "<div class='feed-container'>{entries}</div>",
// inner template for each entry
// default: '<li><a href="{url}">[{author}@{date}] {title}</a><br/>{shortBodyPlain}</li>'
// valid values: any string
entryTemplate: "<p>{title}</p>",
// additional token definition for in-template-usage
// default: {}
// valid values: any object/hash
tokens: {
foo: "bar",
bar: function(entry, tokens) {
return entry.title;
}
},
// formats the date with moment.js (optional)
// default: 'dddd MMM Do'
// valid values: see http://momentjs.com/docs/#/displaying/
dateFormat: "MMMM Do, YYYY",
// localizes the date with moment.js (optional)
// default: 'en'
dateLocale: "de",
// Defines the format which is used for the feed.
// Default: null (utf8)
// valid values: https://github.com/ashtuchkin/iconv-lite/wiki/Supported-Encodings
encoding: "ISO-8859-1",
// Defined the order of the feed's entries.
// Default: undefined (keeps the order of the original feed)
// valid values: All entry properties; title, link, content, contentSnippet, publishedDate, categories, author, thumbnail
// Order can be reversed by prefixing a dash (-)
order: "-publishedDate",
// formats the date in whatever manner you choose. (optional)
// this function should return your formatted date.
// this is useful if you want to format dates without moment.js.
// if you don't use moment.js and don't define a dateFormatFunction, the dates will
// not be formatted; they will appear exactly as the RSS feed gives them to you.
dateFormatFunction: function(date) {},
// a callback, which gets triggered when an error occurs
// default: function() { throw new Error("jQuery RSS: url don't link to RSS-Feed") }
error: function() {},
// a callback, which gets triggered when everything was loaded successfully
// this is an alternative to the next parameter (callback function)
// default: function(){}
success: function() {},
// a callback, which gets triggered once data was received but before the rendering.
// this can be useful when you need to remove a spinner or something similar
onData: function() {}
},
// callback function
// called after feeds are successfully loaded and after animations are done
function callback() {}
);
Since version 3.0.0 the plugin is no longer using the Google Feed API but a drop-in replacement called feedr. That server is currently running on Heroku and might have some downtimes, interruptions or unexpected issues. While I will try to keep those problems as rare as possible, it can totally happen from time to time. I might move the service to some other provide or even improve the infrastructure.
If you don't want to rely on the provided server and instead run your own version, you can just download feedr, install the dependencies and run it. As written above, you can specify the host which is used to parse the feeds with the host
option.
As seen in the options, you can specify a template in order to transform the json objects into HTML. In order to that, you can either define the outer template (which describes the html around the entries) or the entry template (which describes the html of an entry).
The basic format of those templates are:
<!-- layoutTemplate: -->
"<outer-html>{entries}</outer-html>"
<!-- entryTemplate: -->
"<any-html>{token1}{token2}</any-html>"
So, let's say you have specified a limit of 2, using the upper pseudo html. This will result in the following:
<outer-html>
<any-html>{token1}{token2}</any-html>
<any-html>{token1}{token2}</any-html>
</outer-html>
There are some predefined tokens:
You can also define custom tokens using the tokens
option:
$("#foo").rss(url, {
entryTemplate: "{dynamic}, {static}, {re-use}",
tokens: {
dynamic: function(entry, tokens) {
return "dynamic-stuff: " + entry.title;
},
"re-use": function(entry, tokens) {
return encodeURIComponent(tokens.teaserImageUrl);
},
static: "static"
}
});
Please make sure to NOT define infinite loops. The following example is really BAD:
$('#foo').rss(url, {
entryTemplate: "{loop}",
tokens: {
whoops: function(entry, tokens) { return tokens.loop() }
loop: function(entry, tokens) { return tokens.whoops() }
}
})
Here is a real-world example:
$("#foo").rss(url, {
layoutTemplate: "<table><tr><th>Title</th></tr>{entries}</table>",
entryTemplate: "<tr><td>{title}</td></tr>"
});
The plugin also allows you to filter specific entries in order to only print them:
$("#foo").rss(url, {
limit: 100,
filterLimit: 10,
filter: function(entry, tokens) {
return tokens.title.indexOf("my filter") > -1;
}
});
This will request 100 entries via the Feed API and renders the first 10 matching entries.
The test suite is using BusterJS. In order to successfully run the tests you will need phantomjs. If that is installed you only have to run npm test
.
Since version 3.4.0 of jquery.rss, users have the chance to support funding future developments and covering the costs for the hosting of jquery.rss' respective server side companion app feedr.
Every once in a while supporters will get affiliate links instead of one of the feed's entries.
If you are not interested in supporting the authors of the plugin, then you can easily opt-out of it by setting the respective support
option. See below for further details.
Thanks in advance!
Author: sdepold
Source Code: https://github.com/sdepold/jquery-rss
License: MIT license
1672823120
Autocomplete widget in the jQuery UI library displays an items list that matches with the search value in the textbox.
You can either predefine its data or load it dynamically.
In this tutorial, I show how you can add jQuery UI autocomplete in the Livewire component in your Laravel 9 project.
Open .env
file to update the database connection.
Specify the host, database name, username, and password.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tutorial
DB_USERNAME=root
DB_PASSWORD=
employees
using migration.php artisan make:migration create_employees_table
database/migrations/
folder from the project root.create_employees_table
and open it.up()
method.public function up()
{
Schema::create('employees', function (Blueprint $table) {
$table->id();
$table->string('emp_name',60);
$table->string('email',80);
$table->string('city',100);
$table->smallInteger('status');
$table->timestamps();
});
}
php artisan migrate
Employees
Model –php artisan make:model Employees
app/Models/Employees.php
file.$fillable
property.Completed Code
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Employees extends Model
{
use HasFactory;
protected $fillable = [
'emp_name','email','city','status'
];
}
PagesController
controller.php artisan make:controller PagesController
app\Http\Controllers\PagesController.php
file.index
view.Completed Code
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PagesController extends Controller
{
public function index(){
return view('index');
}
}
routes/web.php
file.<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;
Route::get('/', [PagesController::class, 'index']);
jqueryui-autocomplete
component –php artisan make:livewire jqueryui-autocomplete
This will create 2 files –
app/Http/Livewire/JqueryuiAutocomplete.php
App\Models\Employees
model.$search
is empty then fetch 5 records from the employees
table otherwise, fetch 5 records from the employees
table where $search
is matched in the emp_name
field.Loop on the fetched records. Initialize $response
Array with value
and label
keys. Pass employee id in value
key and name in label
key.
Return $response
Array in JSON format.
Completed Code
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Employees;
class JqueryuiAutocomplete extends Component
{
public $searchEmployee = "";
public $selEmployeeId = 0;
// Fetch autocomplete Data
public function getData($search = ""){
if($search == ''){
$employees = Employees::orderby('emp_name','asc')->select('id','emp_name')->limit(5)->get();
}else{
$employees = Employees::orderby('emp_name','asc')->select('id','emp_name')->where('emp_name', 'like', '%' .$search . '%')->limit(5)->get();
}
$response = array();
foreach($employees as $employee){
$response[] = array(
"value"=>$employee->id,
"label"=>$employee->emp_name
);
}
return response()->json($response);
}
public function render()
{
return view('livewire.jqueryui-autocomplete');
}
}
resources/views/liverwire/jqueryui-autocomplete.blade.php
autocomplete
class and wire:model="searchEmployee"
.selEmployeeId
.Script –
autocomplete
class.getData()
method using @this.getData()
. In the method pass the search value.It will return JSON data with Promise
. For reading it use then
. JSON.parse
the data and pass it in response()
.
value
and label
. With @this.set
update model values. Store ui.item.label
in searchEmployee
and ui.item.value
in selEmployeeId
.Completed Code
<div>
<input type="text" class='autocomplete' wire:model="searchEmployee"> <br><br>
<br>
<input type="text" wire:model="selEmployeeId">
</div>
@section('scripts')
<!-- Script -->
<script >
$(document).ready(function(){
$( ".autocomplete" ).autocomplete({
source: function( request, response ) {
var responseData = @this.getData(request.term);
responseData.then((data) => {
var data = JSON.parse(data);
response( data );
});
},
select: function (event, ui) {
@this.set('searchEmployee', ui.item.label);
@this.set('selEmployeeId', ui.item.value);
return false;
}
});
});
</script>
@endsection
Create index.blade.php
file in resources/views/
folder.
Include jQuery and jQuery UI library –
<!-- jQuery UI CSS -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- jQuery UI JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
Include jqueryui-autocomplete
component, livewire style, and script. Also, add @yield('scripts')
.
Completed Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How to Add jQuery UI autocomplete in Livewire - Laravel</title>
<!-- jQuery UI CSS -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- jQuery UI JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
@livewireStyles
</head>
<body>
<livewire:jqueryui-autocomplete />
@livewireScripts
@yield('scripts')
</body>
</html>
Returning JSON Array response must have data with value
and label
keys otherwise, data will not load in autocomplete element.
You can also view this tutorial if you want to implement autocomplete without any library in Livewire.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1671685707
An Autocomplete textbox gives suggestions based on user input.
The user can select an option from the list.
This generally uses in the field where a user needs to select an item from the available data.
In this tutorial, I show how you can add autocomplete on a textbox element using jQuery UI in CodeIgniter.
In this example, I am using users
table and added some records –
CREATE TABLE `users` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`username` varchar(60) NOT NULL,
`fullname` varchar(70) NOT NULL,
`password` varchar(60) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Navigate to application/config/database.php
and define Database connection.
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root', // Username
'password' => '', // Password
'database' => 'tutorial', // Database name
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
Default controller
Open application/config/routes.php
and edit default_controller
value to User
.
$route['default_controller'] = 'User';
Load Database
To access the MySQL database require loading database
library.
Open application/config/autoload.php
and add the database
in libraries array()
.
$autoload['libraries'] = array("database");
Create a User_model.php
file in application/models/
folder.
Here, create a method –
search
is POST then fetch all records from users
table according to $postData['search']
.Loop on the fetched records and initialize $response
with value
and label
key.
Return the $response
Array.
Completed Code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class User_model extends CI_Model {
function getUsers($postData){
$response = array();
if(isset($postData['search']) ){
// Select record
$this->db->select('*');
$this->db->where("username like '%".$postData['search']."%' ");
$records = $this->db->get('users')->result();
foreach($records as $row ){
$response[] = array("value"=>$row->id,"label"=>$row->username);
}
}
return $response;
}
}
Create a User.php
file in application/controllers/
folder.
Here, create 3 methods –
url
helper and User_model
Model.user_view
view.Read the POST values and pass in $this->User_model->getUsers()
to get user records.
Return response in JSON format.
Completed Code
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class User extends CI_Controller {
public function __construct(){
parent::__construct();
$this->load->helper('url');
// Load model
$this->load->model('User_model');
}
public function index(){
// load view
$this->load->view('user_view');
}
public function userList(){
// POST data
$postData = $this->input->post();
// Get data
$data = $this->User_model->getUsers($postData);
echo json_encode($data);
}
}
Create user_view.php
file in application/views/
folder.
Included jQuery UI CSS, JS, and jQuery library.
Create two text elements –
Script –
Initialize autocomplete on #autouser
selector.
Use the source
option to load the suggestion list.
Send AJAX POST request to "<?=base_url()?>index.php/User/userList"
and pass the input value in the text element.
On successful callback pass response data in response()
function.
Using the select
option to get the selected suggestion label and value.
Pass ui.item.label
in #autouser
selector and ui.item.value
in #userid
selector.
Completed Code
<!doctype html>
<html>
<head>
<title>How to Autocomplete textbox in CodeIgniter 3 with jQuery UI</title>
<!-- jQuery UI CSS -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
</head>
<body>
Search User : <input type="text" id="autouser">
<br><br>
Selected user id : <input type="text" id="userid" value='0' >
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- jQuery UI -->
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type='text/javascript'>
$(document).ready(function(){
// Initialize
$( "#autouser" ).autocomplete({
source: function( request, response ) {
// Fetch data
$.ajax({
url: "<?=base_url()?>index.php/User/userList",
type: 'post',
dataType: "json",
data: {
search: request.term
},
success: function( data ) {
response( data );
}
});
},
select: function (event, ui) {
// Set selection
$('#autouser').val(ui.item.label); // display the selected text
$('#userid').val(ui.item.value); // save selected id to input
return false;
}
});
});
</script>
</body>
</html>
Use source
option to send AJAX request to the controller and load suggestion data.
Return response must have value and label keys.
You can view this tutorial to know how you can add jQuery UI autocomplete in CodeIgniter 4.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1671663360
Uploading a file without page refresh is a more user-friendly way than refreshing the whole page.
It allows displaying image preview instantly after upload.
You can upload single or multiple files using jQuery AJAX.
In this tutorial, I show how you can upload multiple image files and display preview after upload using jQuery AJAX and PHP.
Create a <form >
.
Add a file element and a button in it.
For enabling multiple file selection added multiple
attribute and name
as Array type (name='files[]'
).
Use <div id='preview'>
to show image preview using jQuery AJAX after successfully upload.
Completed Code
<style type="text/css">
#preview img{
margin: 5px;
}
</style>
<form method='post' action='' enctype="multipart/form-data">
<input type="file" id='files' name="files[]" multiple><br>
<input type="button" id="submit" value='Upload'>
</form>
<!-- Preview -->
<div id='preview'></div>
On upload button click create FormData()
object and count total files are been selected.
Loop on the selected files and append in form_data
.
Send AJAX POST request to ajaxfile.php
. Pass form_data
as data
, set dataType: 'json'
, contentType: false
, and processData: false
.
On AJAX successful callback loop on the response
to get the file path.
Append <img >
element in <div id='preview' >
where use src
variable in img
src
attribute.
Completed Code
$(document).ready(function(){
$('#submit').click(function(){
var form_data = new FormData();
// Read selected files
var totalfiles = document.getElementById('files').files.length;
for (var index = 0; index < totalfiles; index++) {
form_data.append("files[]", document.getElementById('files').files[index]);
}
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: form_data,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
for(var index = 0; index < response.length; index++) {
var src = response[index];
// Add img element in <div id='preview'>
$('#preview').append('<img src="'+src+'" width="200px;" height="200px">');
}
}
});
});
});
Create an ajaxfile.php
file and a uploads
folder to store files.
Count total files, assign upload location to $upload_location
, and create a $files_arr
Array to store file path after file upload.
Loop on the files.
Initialize $valid_ext
Array with valid image extensions.
Check if the file extension exists in $valid_ext
Array. If exists then upload the file and initialize $files_arr
Array with $path
.
Return $files_arr
in JSON format for image preview.
Completed Code
<?php
// Count total files
$countfiles = count($_FILES['files']['name']);
// Upload Location
$upload_location = "uploads/";
// To store uploaded files path
$files_arr = array();
// Loop all files
for($index = 0;$index < $countfiles;$index++){
if(isset($_FILES['files']['name'][$index]) && $_FILES['files']['name'][$index] != ''){
// File name
$filename = $_FILES['files']['name'][$index];
// Get extension
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// Valid image extension
$valid_ext = array("png","jpeg","jpg");
// Check extension
if(in_array($ext, $valid_ext)){
// File path
$path = $upload_location.$filename;
// Upload file
if(move_uploaded_file($_FILES['files']['tmp_name'][$index],$path)){
$files_arr[] = $path;
}
}
}
}
echo json_encode($files_arr);
die;
In the example, I used jQuery AJAX for uploading image files only but you can allow other files upload by specifying file extension in $valid_ext
variable.
But you need to modify the file preview code.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1671646440
About a week ago I had written about using HTTPS with Node.js and hinted at hardware based two-factor authentication as my reason for needing it. In case you’re unfamiliar with 2FA, there are numerous approaches ranging from HMAC-based one-time passwords (HOTP) and time-based one-time passwords (TOTP) which are software based, to the hardware based universal two-factor (U2F) standard.
If you’ve been keeping up with the blog, you’ll remember I had written a tutorial titled, Implement 2FA with Time-Based One-Time Passwords in a Node.js API, which focused on the software side of things. I recently picked up some YubiKey dongles and thought I’d try my luck with the hardware side of things.
In this tutorial, we’re going to see how to implement U2F functionality in our Node.js powered RESTful API and interact with the API and our hardware dongles using jQuery in the web browser.
Before getting too involved with this tutorial, there are a few things to note:
If you’re looking to buy a YubiKey, Amazon has them at a reasonable price. When it comes to the HTTPS side of things, I encourage you to look at my previous tutorial if you’re not already familiar with using self-signed certificates with Node.js.
Before we start playing around with the U2F hardware key, we need to start building our backend that will support the key. Let’s create a new project by executing the following from our command line:
npm init -y
With the project’s package.json file created, we’re going to want to download our project dependencies. From the command line, execute the following:
npm install u2f --save
npm install express --save
npm install body-parser --save
npm install cors --save
While we don’t need Express Framework to build an API, it is probably the easiest and most stable solution out there. We’re going to need to accept payloads in the requests so the body-parser package will be necessary. Likewise, our client facing application will be operating on a different port or domain, hence cross-origin resource sharing (CORS) must be configured. Finally, the u2f package will allow us to process requests with the hardware key.
Let’s create a file to hold our application source code:
touch app.js
If you don’t have the touch
command on your operating system, go ahead and create an app.js file manually. You’ll also need a set of self-signed certificates, but the assumption is that you’ve already reviewed my previous tutorial.
Open the project’s app.js so we can start adding our boilerplate project code:
const U2F = require("u2f");
const Express = require("express");
const BodyParser = require("body-parser");
const Cors = require("cors");
const HTTPS = require("https");
const FS = require("fs");
const APP_ID = "https://localhost:2015";
var app = Express();
app.use(BodyParser.json());
app.use(BodyParser.urlencoded({ extended: true }));
app.use(Cors());
var user;
app.get("/register", (request, response, next) => {});
app.post("/register", (request, response, next) => {});
app.get("/login", (request, response, next) => {});
app.post("/login", (request, response, next) => {});
HTTPS.createServer({
key: FS.readFileSync("server.key"),
cert: FS.readFileSync("server.cert")
}, app).listen(443, () => {
console.log("Listening at :443...");
});
The first thing we do in the above code is import our project dependencies. You’ll notice that we’re also importing https
and fs
for working with our certificates, but they did not need to be downloaded since they ship with Node.js. As per the documentation for the U2F package, we’ll need to strictly define the client facing application. In my example, it is being served on port 2015 using HTTPS.
When we serve the application, we’ll be using the standard 443 port as well as the self-signed certificates that you should have already created.
This is where things start to get a little interesting. We have four endpoints for various U2F operations. Don’t get confused by my naming conventions because these are not typical registrations and sign-ins. These endpoints represent the necessary secondary interactions with our hardware keys, not with the username and passwords that might exist as a first step. You’ll also notice a user
variable. Because we’re not using a database in this example, we’re going to store the registration in memory.
As part of our process, the first step is our request against the register
endpoint:
app.get("/register", (request, response, next) => {
var session = U2F.request(APP_ID);
app.set("session", JSON.stringify(session));
response.send(session);
});
Typically you’d want to do a better job than I’ve done when it comes to sessions, but what we’re doing is we’re creating a U2F request which includes things like a challenge and storing it in memory. This session is also being returned to the client facing application that requested it. We can’t trust the user to maintain the only copy because they might try to manipulate it and gain unauthorized accesses. When the user receives this request information, at this point they should be asked to activate their hardware key. When the hardware key becomes active, the user will send a request to the following endpoint:
app.post("/register", (request, response, next) => {
var registration = U2F.checkRegistration(JSON.parse(app.get("session")), request.body.registerResponse);
if(!registration.successful) {
return response.status(500).send({ message: "error" });
}
user = registration;
response.send(registration);
});
What we’re doing is we are taking the session that was created along with the U2F payload that was sent from the client facing application and are validating it. If it is valid, as in the payload was modeled around the information found in our session, we can store it in memory, or in reality, a database. While in our example we are returning the registration information, you probably shouldn’t. We are doing it so you get an idea of what it would look like in your database.
With U2F registration information in our database, we can focus on the login. Technically we could start with a clean slate, but since our user information is stored in memory, we shouldn’t. The session information could, of course, be reset though.
The login follows the same process as the registration. First we get our request with challenge information:
app.get("/login", (request, response, next) => {
var session = U2F.request(APP_ID, user.keyHandle);
app.set("session", JSON.stringify(session));
response.send(session);
});
The difference between the above endpoint and the registration is that now we are obtaining the key information about our previously registered user, which again would probably come from a database in production. After getting the request, the client should ask the user to initiate their hardware key, at which point another request with a payload should be made:
app.post("/login", (request, response, next) => {
var success = U2F.checkSignature(JSON.parse(app.get("session")), request.body.loginResponse, user.publicKey);
response.send(success);
});
In the above endpoint, we take the session that was previously created, as well as the U2F payload and the public key that resides in our database and validate the information. In this example we return the result of the validation back to the user, which is fine, but realistically you’d probably want to return a JSON web token (JWT) or something to be passed around with future requests. More information about JWT can be found in my previous tutorial titled, JWT Authentication in a Node.js Powered API.
At this point in time our U2F backend is complete. Just to reiterate, we didn’t develop the first phase for registration and login with username and password. We only focused on the second phase. We also didn’t use a database to store our registered U2F hardware key, when in production we should. Now we can focus on the client interface.
As previously mentioned, U2F with hardware keys is only officially supported in Google Chrome. While Firefox has some support, it is more or less use at your own risk. If you’re implementing U2F, make sure you offer other alternatives such as HOTP or TOTP.
Somewhere on your computer create an index.html file with the following boilerplate code:
<html>
<head></head>
<body>
<h1>U2F with Node.js</h1>
<button id="register">Start Registration</button>
<button id="login">Start Login</button>
<script>
// Logic here...
</script>
</body>
</html>
You’ll notice that we have two buttons, one to start our registration process and register our hardware key and the other to validate. To do this, we’ll need two JavaScript libraries. First, you’ll want to download Google’s u2f-api library. Next you’ll want to download jQuery, which is optional, but will make our lives easier for this example.
With the libraries downloaded, we can make the following update to our index.html file:
<html>
<head></head>
<body>
<h1>U2F with Node.js</h1>
<button id="register">Start Registration</button>
<button id="login">Start Login</button>
<script src="jquery-3.3.1.min.js"></script>
<script src="u2f-api.js"></script>
<script>
// Logic here...
</script>
</body>
</html>
We know that there will be two different interactions with our RESTful API, so let’s first look at the registration:
$("#register").click(() => {
if(window.u2f && window.u2f.register) {
$.get("https://localhost/register", result => {
console.log(result);
window.u2f.register(result.appId, [result], [], response => {
$.post("https://localhost/register", { registerResponse: response }, result => {
console.log(result);
});
console.log(response);
});
});
} else {
document.write("<p>U2F is not supported</p>");
}
});
In the above code, when the registration button is clicked, we first check to make sure that U2F is available for the current web browser. It is only available if we are using the u2f-api library and are using Google Chrome. If U2F works, we first request our challenge information from the GET endpoint. You’ll notice that I’m printing the result so you can get an idea of what it looks like.
With the challenge information, we can attempt to register our YubiKey. The browser will wait until the key is initiated, at which point the response data from the key as well as the challenge information is sent to the second part of the registration. We’ll print the results as appropriate.
Assuming that we have a registered key, we can attempt to login:
$("#login").click(() => {
if(window.u2f && window.u2f.sign) {
$.get("https://localhost/login", result => {
console.log(result);
window.u2f.sign(result.appId, result.challenge, [result], response => {
$.post("https://localhost/login", { loginResponse: response }, result => {
console.log(result);
});
console.log(response);
});
});
} else {
document.write("<p>U2F is not supported</p>");
}
});
Again we check to make sure that U2F is supported and if it is, we get our challenge information based on our user. We aren’t passing any user information, but in production you’d want to figure out your user in the first factor which would be username and password authentication. That, in theory, would get the user information, including the hardware registration. Once we have the information we need, the browser will wait until we initiate the key and then send the response as part of the payload. Assuming the key information matches what is stored in the database, we would be logged in.
If you recall, our backend assumes that our application is operating at https://localhost:2015. It is a requirement that you are using HTTPS on your frontend and a requirement that it matches what your backend expects. If you’re having trouble, I might suggest using Caddy Server for testing. You can pretty easily get where you need with the following Caddyfile setup:
localhost:2015 {
tls server.cert server.key
}
In the above example, server.cert and server.key are the same that the Node.js application is using. Again, you don’t need to use Caddy, you just need to be serving on HTTPS for both your backend and frontend. How you get there is up to you.
You just saw how to use a U2F hardware key such as the YubiKey as a second factor of authentication in your Node.js powered web application. It is advisable that all modern web applications allow for two-factor authentication (2FA) whether that be in the form of HOTP, TOTP, U2F, or something else.
When learning how to use U2F, the most difficult part for me was configuring HTTPS. It wasn’t obvious that I needed it for testing locally or how to properly configure it. Once getting beyond that hurdle, interacting with the hardware keys is actually quite easy.
If you’re interested in learning more about developing APIs with Node.js, I encourage you to check out my eBook and course titled, Web Services for the JavaScript Developer.
Original article source at: https://www.thepolyglotdeveloper.com/
1671550399
In this JQuery tutorial we will learn How To Enable/Disable Submit Button After Clicked Using jQuery. Often times, users like to press a few times on the submit button to make sure the button is surely clicked, and causing the double form submission issue. The common solution is disables the submit button after user clicked on it.
1.1 To disable a submit button, you just need to add a disabled
attribute to the submit button.
$("#btnSubmit").attr("disabled", true);
1.2 To enable a disabled button, set the disabled
attribute to false, or remove the disabled
attribute.
$('#btnSubmit').attr("disabled", false);
or
$('#btnSubmit').removeAttr("disabled");
<!DOCTYPE html>
<html lang="en">
<body>
<h1>jQuery - How to disabled submit button after clicked</h1>
<form id="formABC" action="#" method="POST">
<input type="submit" id="btnSubmit" value="Submit"></input>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input type="button" value="i am normal abc" id="btnTest"></input>
<script>
$(document).ready(function () {
$("#formABC").submit(function (e) {
//stop submitting the form to see the disabled button effect
e.preventDefault();
//disable the submit button
$("#btnSubmit").attr("disabled", true);
//disable a normal button
$("#btnTest").attr("disabled", true);
return true;
});
});
</script>
</body>
</html>
Original article sourced at: https://www.laravelcode.com
1671542880
In this Javascript and JQuery tutorial we will learn about Code Comparison Between Javascript and JQuery with an Example. In the previous article, we have discussed on what is Javascript and JQuery. We have also discussed on main differences between them. In this article we will go through code comparision between Javascript and JQuery with example.
Here is the bellow examples, so let's check bellow examples:
Javascript is directly written between <script> tags. Javascript external file can also be included in HTML document.
<script src="path/to/external/javascript-file.js"></script>
<script>
document.getElementById("myid").innerHTML = "Hello World";
</script>
JQuery code is dependant on JQuery library. So you have to include JQuery library file or CDN file before JQuery code in HTML document.
<head>
<script src="jquery-3.5.0.min.js"></script>
</head>
To select HTML tag in Javascript, use document.querySelector() method or other methods as per tag.
document.querySelector('#id');
or
document.getElementById('idname');
or select by class
document.getElementsByClassName('classname');
or select by element
document.getElementsByTagName('p');
In JQuery $ sign used with selector in bracket.
$(selector)
or
$('#idname')
or
$('.classname')
or
$('p')
To handle event in Javascript, write addEventListener()
method with event name.
document.getElementById('idname').addEventListener('click', function() {
alert('Hello World');
});
In JQuery all event has defined method to handle.
$('.classname').click(function() {
// here comes acion
});
or submit form
$('#idname').submit(function() {
// here comes acion
});
or to use multiple event with on() method
$('#input').on ('click change', function() {
// here comes acion
});
To change the style of an HTML element in Javascript, use:
document.getElementById('idname').style.color = '#f2f2f2';
in JQuery, change CSS with css() method:
$('#idname').css('color', '#f2f2f2');
To change the value of HTML element attribute in Javascript, use:
document.getElementById('idname').href = "/new-url";
To change value in JQuery, use attr() method:
$('#idname').attr('href', '/new-url');
Creating Ajax request in Javascript with new XMLHttpRequest object and send request to server. There is open('methodType', 'URL', async)
method with parameters and send() method with data creates Ajax request.
Create get method request:
var xhttp = new XMLHttpRequest();
xhttp.open('GET', 'request-url', true);
xhttp.send();
Or create post method request:
var xhttp = new XMLHttpRequest();
xhttp.open('POST', 'request-url', true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('id=5&name=javascript');
To create Ajax request, there are many syntax in JQuery. Bellow are main methods which are widely used:
$.ajax({
type: "post",
url: 'request-url',
data: data,
success: function(response) {
// what to do after ajax complete
}
});
Or shorthand method:
$.get('request-url', function(response) {
$('#result').html(response);
});
or more simply:
$('#result').load('request-url');
Creating animation is also difficult and requires many lines of code. JavaScript use the setInterval(), clearInterval(), setTimeout() and clearTimeout() methods and CSS transform, translate or animate properties to create animation.
Here is the simple animation in Javascript:
setInterval(myAnimation, 5);
function myAnimation(){
document.getElementById ("#idname").style.transform=‘translate(100px, 100px)’;
document.getElementById ("#idname").style.transform=‘rotate(30deg)’;
}
In JQuery there are several direct methods which are used to create fast and easy animation:
Css animation
$('#idname').animate({height: '100px'});
Hide/Show animation
$('.hide-class').hide();
$('show-class').show();
or toggle() to hide/show respectively.
$('show-class').toggle();
Create fade effect with fadeIn() or fadeOut() method:
$('#idname').fadeIn();
$('#idname').fadeOut();
There are many functions in JQuery to create animations. But it is also noted that Javascript can also work in graphic animations like on <canvas> tag while JQuery only works in HTML dom elements:
Javascipt is difficult compared to JQuery, so most of us use JQuery for most of work. While Javascript is language and has widly use with other technologies while Jquery is Javascript library for HTML dom manipulation. So it mostly used in web development.
In the conclusion, both have its own usage in software development. I hope you will like this article.
Original article sourced at: https://www.laravelcode.com
1671542280
JavaScript is one of the most sought after languages designed to build interactive web applications. So, JavaScript uses one of the most definitive tool that provides full power and flexibility in developing practical web applications is jQuery.
jQuery is a JavaScript library. It is mainly used to standardize and simplify the interactions between HTML elements and JavaScript Code. JavaScript allows websites to be dynamic and interactive, whereas the jQuery helps to optimize this process in a very effective manner. So today we are going to discuss 5 Key techniques in jQuery to improve the user experience and User interactions in modern web applications.
So let’s deep dive into 5 jQuery techniques to enhance UI in web applications.
jQuery is the most sought-after and rich javascript library. It is mainly used to wrap the lines of code into methods so that it becomes easy to call the lines of code using a single line of code. In order to build a better user experience and improve the performance of our projects, you need to update to the latest version of jQuery. Furthermore, to improve the efficiency and accuracy of your website you need to make use of the latest version of jQuery.
We can easily update to the latest version and the best thing about using jQuery latest version is that you must only change the script tag so that it works automatically.
jQuery can be added using CDN hosting that is provided by Google mainly for JavaScript libraries. The following code shows how to update to the latest version of jQuery.
<!-- The jQuery version you are using -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- The latest branch of the jQuery version you are using -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.3/jquery.min.js"></script>
Forms are a core part of any website that developers build.
As the forms create grab the attraction and make the developers focus on building the forms which result in improving better user experience.
An animate() method is used to replace or shift the user from one form to another.
You can view this tutorial to know how to create a login form with AJAX.
Navigation plays a key role in improving the user experience.
So in order to provide smooth navigation for the users, jQuery plugins are used. The developers must create simple jQuery tabs which are both responsive and effective in offering smooth navigation to the users.
All the jQuery plugins are available in the https://jquery.com/plugins repository link.
In a website, form submission can be done without refreshing the page with the help of jQuery.
If suppose you refresh the page in the middle of the operation or form submission it may cause an error or may have a conflict which makes users deter. So one need to submit the form without refreshing the page then you can automatically improve the user experience and can improve the performance of a website.
You can use jQuery to upload a file using AJAX. In order to implement you need to create a HTML <form method='post' enctype='multipart/form-data'>
with file element. For sending upload request you can either use file element change event or a button click.
Here, is the jQuery script –
$(document).ready(function(){
$("#but_upload").click(function(){
var fd = new FormData();
var files = $('#file')[0].files[0];
fd.append('file',files);
$.ajax({
url: 'upload.php',
type: 'post',
data: fd,
contentType: false,
processData: false,
success: function(response){
if(response != 0){
$("#img").attr("src",response);
$(".preview img").show(); // Display image element
}else{
alert('file not uploaded');
}
},
});
});
});
On button click above code send the selected file to upload.php file using jQuery AJAX. Need to use FormData object to pass the selected file to the server.
It improves user experience by not reloading the whole page for file upload.
You can view this tutorial to know how to upload a file with jQuery AJAX.
Users must not reveal any important facts and data related to their organization. By using this spoiler revealers are the one who can analyze the information that the users mostly reveal and target.
The technique of spoiler revealers is made using jQuery plugins. This aspect also helps the user in improving their experience in a better way.
We need the best scripting language to build web applications that are user-friendly. Demand for web applications has been increasing over the years.
jQuery helps you in building excellent web applications. Above mentioned techniques make use of jQuery plugins and other jQuery operations in order to satisfy users and ensure better experience to them while using the particular web application.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1671430808
On the website, there must be a unique identifier for each user. It can be the username, email-id or any string using which user can log in to the website and access it.
Before adding the user using the registration form it must be check if the username is available or not.
This can either done after submitting the form or using jQuery AJAX to display availability status before submitting the form.
In this tutorial, I show how you can check username already exists or not in the MySQL database table using jQuery AJAX PHP and PDO.
I am using users
table in the example –
CREATE TABLE `users` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`username` varchar(80) NOT NULL,
`fullname` varchar(80) NOT NULL,
`password` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Create a config.php
for a database connection.
Completed Code
<?php
$server = "localhost";
$username = "root";
$password = "";
$dbname = "tutorial";
// Create connection
try{
$conn = new PDO("mysql:host=$server;dbname=$dbname","$username","$password");
$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
die('Unable to connect with the database');
}
Create a <input type='text' id='txt_username'>
for username input and create a <div id='uname_response' >
to display a message on whether a username exists or not using jQuery.
Completed Code
<div>
<input type="text" class="textbox" id="txt_username" name="txt_username" placeholder="Enter Username" />
<!-- Response -->
<div id="uname_response" ></div>
</div>
Create ajaxfile.php
file.
Check if 'username'
is POST or not.
If POST then check $_POST['username']
is exists or not in the 'users'
table or not.
If exists then return "Not Available"
otherwise "Available"
message.
Completed Code
<?php
include 'config.php';
if(isset($_POST['username'])){
$username = $_POST['username'];
// Check username
$stmt = $conn->prepare("SELECT count(*) as cntUser FROM users WHERE username=:username");
$stmt->bindValue(':username', $username, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->fetchColumn();
$response = "<span style='color: green;'>Available.</span>";
if($count > 0){
$response = "<span style='color: red;'>Not Available.</span>";
}
echo $response;
exit;
}
Define keyup
event on #txt_username
selector.
Read the value and check if it is empty or not.
If empty then empty the #uname_response
selector otherwise send AJAX POST request to 'ajaxfile.php'
file where pass username as data
.
On successful callback write a response in #uname_response
.
Completed Code
$(document).ready(function(){
$("#txt_username").keyup(function(){
var username = $(this).val().trim();
if(username != ''){
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: {username:username},
success: function(response){
// Show response
$("#uname_response").html(response);
}
});
}else{
$("#uname_response").html("");
}
});
});
I used keyup
event to display username status while typing but you can also use other events like onblur
on the textbox or click
on the button.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/