jQuery: "jQuery is a fast, small, and feature-rich JavaScript library. It makes
things like HTML document traversal and manipulation, event handling,
animation, and Ajax much simpler with an easy-to-use API that works across
a multitude of browsers. With a combination of versatility and
extensibility, jQuery has changed the way that millions of people write
JavaScript. " (From https://jquery.com/)
Bootstrap: "Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web. Bootstrap makes front-end web development faster and easier. It's made
for folks of all skill levels, devices of all shapes, and projects of
all sizes. Millions of amazing sites across the web are being built with Bootstrap." (From http://getbootstrap.com/)
FormValidation : "Best jQuery plugin to validate form fields." (From http://formvalidation.io/ )
For the detail of each one above, you can just click the links for detail.
I've used jQuery before, this is my first time to use Bootstrap and Form Validation. But this is a very good experience, it makes the UI development job easier and fun.
Below is the form I am building. In the previous blog, I introduced how to use jQuery to build drag and drop sorting table, and how to add a new row or remove a row.
Here, I use Bootstrap form validation to validate the form.
Features for this form:
1, Each row can be drag and drop to the any place.
2. User can add a new row and remove an existing row.
3. Internal name, display name, Search weight columns are required for each row.
4. If there is a current image, the new image is not required.
5. If there is not a current image, the new image is required.
HTML code as below:
<form id="classconfigform">
<button type="button" class="btn btn-default btn-xs" id="addbutton">Add New Class</button>
<table id="classtable" class="table table-striped">
<thead>
<tr>
<th class="hidden-xs hidden-sm hidden-md hidden-lg">Order</th>
<th>Class Internal Name</th>
<th>Display Name</th>
<th>Enabled</th>
<th>Search Weight</th>
<th>Current Image</th>
<th>New Image</th>
<th>Delete class</th>
</tr>
</thead>
<tbody id="sortable">
<c:forEach items="${classes}" var="class">
<tr>
<td class="hidden-xs hidden-sm hidden-md hidden-lg ui-state-default">
<input type="hidden" id="displayOrder" name="displayOrder[]" class="form-control" value='<c:out value="${class.displayOrder}"/>'></input>
</td>
<td><input type="text" id="internalClassName" name="internalClassName[]" class="form-control" placeholder="Class Internal Name" value='<c:out value="${class.internalClassName}"/>'></td>
<td><input type="text" id="displayName" name="displayName[]" class="form-control" placeholder="Display Name" value='<c:out value="${class.displayName}"/>'></td>
<td><input type="checkbox" name="enabled[]" class="form-control" checked ></td>
<td><input type="text" id="searchWeight[]" name="searchWeight[]" class="form-control" value='<c:out value="${class.searchWeight}"/>'></td>
<td><input type="hidden" id="fileid" name="fileid[]" class="form-control" value='<c:out value="${class.fileStore.fileId}"/>'><img src="${pageContext.request.contextPath}/download/${class.fileStore.fileId}"></td>
<td><input type="file" id="uploadimage" name="uploadimage[]" class="form-control" value=''>
</td>
<td><button type="button" class="removebutton" title="Remove this class"><span class="glyphicon glyphicon-remove "></span></button> </td>
</tr>
</c:forEach>
<!-- The new row template containing -->
<tr class="hide" id="newClassRowTemplate">
<td class="hidden-xs hidden-sm hidden-md hidden-lg ui-state-default">
<input type="hidden" id="displayOrder" name="displayOrder[]" class="form-control" value='<c:out value="${class.displayOrder}"/>'>
</td>
<td><input type="text" id="internalClassName" name="internalClassName[]" class="form-control" placeholder="Class Internal Name"></td>
<td><input type="text" id="displayName" name="displayName[]" class="form-control" placeholder="Display Name"></td>
<td><input type="checkbox" name="enabled[]" class="form-control" checked ></td>
<td><input type="text" id="searchWeight[]" name="searchWeight[]" class="form-control"></td>
<td><input type="hidden" id="fileid" name="fileid[]" class="form-control"/> </td>
<td><input type="file" id="uploadimage" name="uploadimage[]" class="form-control" value=''>
</td>
<td><button type="button" class="removebutton" title="Remove this class"><span class="glyphicon glyphicon-remove "></span></button> </td>
</tr>
</tbody>
</table>
<button type="submit" id="saveClasses" class="btn btn-primary">Save Classes</button>
</form>
Javascript code as below:
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="${pageContext.request.contextPath}/resources/scripts/jquery.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/resources/scripts/jquery-ui.min.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/resources/scripts/bootstrap-3.3.2-dist/js/bootstrap.min.js" type="text/javascript"></script>
<!-- FormValidation CSS file -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/scripts/formvalidation-0.6.2/dist/css/formValidation.min.css">
<!-- FormValidation plugin and the class supports validating Bootstrap form -->
<script src="${pageContext.request.contextPath}/resources/scripts/formvalidation-0.6.2/dist/js/formValidation.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/scripts/formvalidation-0.6.2/dist/js/framework/bootstrap.min.js"></script>
<script>
$(document).ready(function() {
$("#sortable").sortable();
$('#classconfigform').formValidation({
framework: 'bootstrap',
err: {
container: 'tooltip'
},
row: {
selector: 'td'
},
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
'internalClassName[]': {
validators: {
notEmpty: {
message: 'Internal class name is required'
}
}
},
'displayName[]': {
validators: {
notEmpty: {
message: 'Display name is required'
}
}
},
'searchWeight[]': {
validators: {
notEmpty: {
message: 'Search Weight is required'
}
}
},
'uploadimage[]': {
validators: {
callback: {
message: 'An image is required',
callback: function (value, validator, $field) {
var $fileid='';
var $classimg = $field.closest('tr');
$fileid = $classimg.find('#fileid').val();
if (($fileid==null||$fileid=='')&&(value==null ||value==''))
return false;
else
return true;
}
}//end of callback
}
}
}
})//end of validation
.on("click","#addbutton",function (){
var $template = $('#newClassRowTemplate'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.insertBefore($template)
.find('input')
.each(function(){
$('#classconfigform').formValidation('addField',$(this) );
});
})
.on("click",".removebutton",function () {
if (confirm("Do you want to delete the class?")){
var $removeclass = $(this).closest('tr');
$removeclass.remove()
.find('input')
.each(function(){
$('#classconfigform').formValidation('removeField',$(this) );
});
}
});
});
</script>
Challenges in this development:
1. After add/remove a new row, how to add/remove it from the validation?
There is a simple example (adding dynamic field) from form validation web site. But the form above is more complicated because this one has multiple rows, and each row has multiple fields.
2. Validation on the images.
(If there is a current image, the new image is not required.
If there is not a current image, the new image is required.)
The callback function examples can be found here. Since the form above has more rows, so it makes this callback more challenge.
This comment has been removed by the author.
ReplyDeleteThanks For Sharin With Us.It gave me a lot of Helpful information..
ReplyDeleteUI Development Training
UI Development Training in Hyderabad
UI Development Online Training
It gave me a lot of Helpful information.Most useful one
ReplyDeleteFull Stack Training in Chennai | Certification | Online Training Course | Full Stack Training in Bangalore | Certification | Online Training Course | Full Stack Training in Hyderabad | Certification | Online Training Course | Full Stack Training in Pune | Certification | Online Training Course | Full Stack Training | Certification | Full Stack Online Training Course
Hi, just wanted to say, I loved this article. It was helpful. Keep on posting!
ReplyDeleteExcellent blog, really awesome and informative content. Useful to many people. Keep sharing more blogs like this, thank you.
ReplyDeleteUI Development Online Training
RPA Online Training in Hyderabad
Python Training in Hyderabad
Mern stack Online Training