I want to develop a dynamic form builder with jquery where users can build their own form and change form name, input type, size etc. I know there are some cool drag and drop online form builders but i want to develop a very simple form builder .
I already have started to develop this and i am facing some issues.
when user will click on the label(input field) it create an input field dynamically with jquery with edit and delete button.
The code below is appending input field in a div which is empty right now.
$(document).ready(function() {
$(".text").click(function(){
$("#textInput").append('<input class="form-control" type="text">' + '<input class="btn btn-default" type="button" value="Edit" id="editbtn"><input class="btn btn-default" type="button" value="Delete" >' ).show().css('display', 'block')});
});
.items {
border: 1px solid lightgray;
display: none;
padding: 0 10px 10px 10px;
}
<div class="items" id="textInput">
<h3>Your Form</h3>
<hr>
</div>
On clicking the text input i want to display a table or modal where user can save changes to input field first of all the edit button is not working and secondly how to edit and save changes to input field(how the process will work).
This is what i want to achieve
I have been working on dynamic form builder and borrowed ideas from some excellent open-source solutions.
They do it in this way:
describe form structure as JSON in the backend.
then use one of the following libraries to render JSON to form in the frontend.
jsonform/jsonform
source code: jsonform/jsonform
example:
rjsf-team/react-jsonschema-form
source code: https://github.com/rjsf-team/react-jsonschema-form
I'd suggest you to look at schema-to-form libraries (for example some of those described in here How to Create a form from a json-schema?).
There are multiple benefits of using such libraries, some of which are flexible layout capabilities, as well as validation hooks.
What is more, your editor has to work with JSON structure only and rendering a form from it is not your main headache.
I did this using JQuery, HTML and Bootstrap
the form was built to be as dynamic as possible and built also to me modified
there is a script to submit the form via ajax
function d(object) {
const id = $(object).data('check');
$('#' + id).remove();
}
//picks and submits form inputs
$(document).ready(function() {
$('form.myForm').on('submit', function() {
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = {};
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
$.ajax({
url: url,
type: type,
data: data,
success: function(response) {
}
});
return false;
});
});
$(function() {
//here i will populate the appendi field if the user selects file
//the user should select the file type
$('#type').on('change', function() {
let type = $("#type option:selected").val();
var add;
if (type === 'file') {
//here i will append the new option in the appendi part
add = "<label for=\"\">What type of file?</label>";
add += "<select name=\"image_type\" id=\"\" class=\"form-control\">";
add += "<option value=\"all\">All</option>";
add += "<option value=\"image\">Image</option>";
add += "<option value=\"document\">Document</option>";
add += "</select>";
$('#appendi').html(add);
}
if (type === 'radio' || type === 'checkbox') {
//here i will append the new option in the appendi part
add = "<label for=\"\">Enter the names of the option separated by a comma (,)</label>";
add += "<textarea col=\"\" class=\"form-control\" row=\"\" name=\"options\" required></textarea>";
$('#appendi').html(add);
}
if (type === 'paragraph' || type === 'text') {
$('#appendi').empty();
}
})
})
$(document).ready(function() {
$('form.myInput').on('submit', function() {
var that = $(this),
data = {};
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
addBody(data);
return false;
});
});
function addBody(data) {
//first thing first is to generate an outer shell
let id_tag = "shell_" + generateId(8);
let shell1_open = "<div class='form-group' " + "id = '" + id_tag + "'>";
shell1_open += "<button type='button' onclick='d(this)' id=\"delete\" data-check='" + id_tag + "'><i class=\"fa-minus-square\">remove</i></button>"
let shell1_close = "</div>";
let shell2, label, shell2_close;
if (data.type === 'text' || data.type === 'date' || data.type === 'file' || data.type === 'email') {
shell2 = "<input type='";
shell2 += data.type + "'";
shell2_close = ">";
}
if (data.type === 'paragraph') {
shell2 = "<textarea";
shell2_close = "></textarea>";
}
if (data.type === 'radio') {
let myArr = data.options.split(",");
shell2 = '';
let name = 'input_' + generateId(5) + '_' + data.name.replace(/\s+/g, '');
for (let i = 0; i < myArr.length; i++) {
shell2 += "<input type='radio'";
shell2 += "value ='" + myArr[i] + "'";
shell2 += "name ='" + name + "'";
//add a class to it
shell2 += " class = 'form-control'";
if (data.required === 'yes') {
shell2 += " required";
}
shell2 += ">" + myArr[i];
}
shell2_close = "";
}
if (data.type === 'checkbox') {
let myArr = data.options.split(",");
shell2 = '';
for (let i = 0; i < myArr.length; i++) {
shell2 += "<input type='checkbox'";
shell2 += "value ='" + myArr[i] + "'";
shell2 += " name='" + 'input_' + generateId(5) + '_' + data.name.replace(/\s+/g, '') + "'";
//add a class to it
shell2 += " class = 'form-control'";
if (data.required === 'yes') {
shell2 += " required";
}
shell2 += ">" + myArr[i];
}
shell2_close = "";
}
if (data.image_type) {
if (data.image_type === 'all') {
shell2 += " accept";
}
if (data.image_type === 'image') {
shell2 += " accept='.jpeg, .png'";
}
if (data.image_type === 'document') {
shell2 += " accept='.pdf, .xls, .docx'";
}
}
if (data.type !== 'radio' && data.type !== 'checkbox') {
if (data.required === 'yes') {
shell2 += " required";
}
/**
* after thinking i decided to map the name the user chose to the placeholder/label
* and squash the name to get the input name, so to remove whitespaces
* also i'll append input_ to all input names
*/
shell2 += " name='" + 'input_' + generateId(5) + '_' + data.name.replace(/\s+/g, '') + "'";
//add a class to it
shell2 += " class = 'form-control'";
//add placeholder
shell2 += " placeholder = '" + data.name + '\'';
}
$('#main-form-body').append(shell1_open + shell2 + shell2_close + shell1_close)
//console.log(shell1_open + shell2 + shell2_close +shell1_close);
}
function dec2hex(dec) {
return dec.toString(16).padStart(2, "0")
}
// generateId :: Integer -> String
function generateId(len) {
var arr = new Uint8Array((len || 40) / 2)
window.crypto.getRandomValues(arr)
return Array.from(arr, dec2hex).join('')
}
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Add input
</button>
<form action="" method="post" class="myForm">
<div id="main-form-body">
</div>
<button type='submit'>Submit</button>
</form>
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Add form input</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<form action="" method="get" class="myInput">
<!-- Modal body -->
<div class="modal-body">
<div class="form-group">
<label for="">What should this be called?</label>
<input type="text" name="name" class="form-control">
</div>
<div class="form-group">
<label for="">What type of data will it hold?</label>
<select name="type" id="type" class="form-control">
<option value="text">Text</option>
<option value="paragraph">Paragraph</option>
<option value="file">File</option>
<option value="radio">Radio</option>
<option value="checkbox">Checkbox</option>
<option value="date">Date</option>
</select>
</div>
<div class="form-group" id="appendi">
</div>
<div class="form-group">
<label>Should it be a required field?</label>
<select name="required" id="" class="form-control">
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Add</button>
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
</html>
enter image description hereYou can use this form builder..
it's available in github
https://github.com/vimal33329/Formbuilder
live url link
https://vimal33329.github.io/Formbuilder/
if you already familiar with github use git clone below code
https://github.com/vimal33329/Formbuilder.git
or download source file by clicking below link...
https://github.com/vimal33329/Formbuilder/archive/refs/heads/main.zip
Form with report
Create form, Build form, Enable or disable Form Submission, Dynamic Option creating,
View Form Report in report page, Drag and Drop position changing...
https://vimal-form.herokuapp.com
enter image description here
enter image description here
enter image description here
enter image description here
Related
I have a opened window called "http://192.168.17.109/report3_test/post-data" shown below.
Onclick Launch button I am passing textbox id and callback function here is the html and jquery function
HTML
<form id="report">
<div class="form-group">
<center><label for="post-data"><h3>Reporting Data</h3></label></center>
<textarea class="form-control" rows="20" id="post-data" name="post-data"></textarea>
</div>
<div class="form-group">
<div class="col-sm-6"><button type="submit" class="btn btn-primary btn-block" name="launch" id="launch" onclick="invoke_reporting(document.getElementById('post-data'),callback)">Launch</button>
</div>
</div>
</form>
JavaScript
function invoke_reporting(textdata,callback) {
window.open("http://192.168.17.109/report3_test/templates/ct-head");
if (callback && typeof(callback) === "function") {
callback(textdata,newwindow);
}
}
Here I am opening a this new window on click launch and it shown below http://192.168.17.109/report3_test/templates/ct-head
Onclick copy to clipboard button I want to send data back to already opened window shown on top that is "http://192.168.17.109/report3_test/post-data" and here is my callback method .
function callback(finaldata){
var arr = $.parseHTML(finaldata);
v
Window.onload = function(){
var test_data = "";
for(var i=0; i<finaldata.length;i++)
{
if(i == 0){
var first_element = 'REPORT TITLE:' + '<br/>' + finaldata[0] + '<br/>' + '<br/>';
test_data += first_element.replace(/<br.*?>/g, '\n');
}else if(i == 1){
var second_element = 'FINDINGS:' + '<br/>' + finaldata[1] + '<br/>' + '<br/>';
test_data += second_element.replace(/<br.*?>/g, '\n');
}else{
var final_element = 'IMPRESSION:' + '<br/>' + finaldata[2];
test_data += final_element.replace(/<br.*?>/g, '\n');
}
}
newWindow.document.getElementById('post-data').value = test_data;
};
}
Any help would be appreciated.
Taka a look at this fiddle here this is a form where a business user enters the offered services.I sent the data with ajax and by serializing the form.
Click edit and add(plus sign) a service...in the example an input is added where it's name attribute value is of this **form= form[5]...**contrast with this with the form of the name attribute value in the other inputs...only the newly added services have the name attribute like this and the reason for that is to serialize only these...and not the others already present in the DOM/stored in the DB.
And now my problem:
Imagine that the user goes to edit the already registered services(or that he goes to edit them and add a new one)...at this case the already registered services wont'be serialized cause of the form the name attribute value has...(and the reason for this is explained above).
What can I do in this case?Sometimes I must serialize only part of a form and sometimes whole of the form.If all the inputs have name attribute value of form[1....] then along with the newly added input...already registered services will be serialized again.
Thanks for listening.
Code follows(you can see it in the fiddle too)
$('.editservices').click(function() {
//console.log(('.wrapper_servp').length);
originals_ser_input_lgth = $('.services').length;
var originals = [];
$('.show_price')
// fetch only those sections that have a sub-element with the .value
class
.filter((i, e) => $('.value', e).length === 1)
// replace content in remaining elements
.replaceWith(function(i) {
var value = $('.value', this).data('value');
var fieldsetCount = $('#serv').length;
var index = fieldsetCount + i;
return '<div class="show_price"><p id="show_p_msg">Price
visibility</p></div>' + '\
<div class="show_p_inpts">' +
'<input class="price_show"' + (value == 1 ? "checked" : "") + '
type="radio" name="form[' + index + '][price_show]" value="1">yes' +
'<input class="price_show"' + (value == 0 ? "checked" : "") + '
type="radio" name="form[' + index + '][price_show]" value="0">no' +
'</div>'; // HTML to replace the original content with
});
$('#buttons').removeClass('prfbuttons');
$('#saveserv').addClass('hideb');
$('.actionsserv').removeClass('actionsserv');
priceavail = $(".price_show:input").serializeArray();
});
$('#addser').on('click', function() {
$('#saveserv').css('border','2px solid none');
var serviceCount = $('input.services').length + 1;
var serv_inputs = '<div class="wrapper_servp"><div class="serv_contain">\n\
<input placeholder="service" class="services text" name="form[' + serviceCount + '][service]" type="text" size="40"> \n\
<input placeholder="price" class="price text" name="form[' + serviceCount + '][price]" type="text" size="3"></div>';
var p_show = '<div class="show_p">' +
'<p id="show_p_msg">Price visibility;</p>' +
'<span id="err_show_p"></span><br>' +
'</div>';
var inputs = '<div class="show_p_inpts">' +
'<input class="price_show" type="radio" name="form[' + serviceCount + '][price_show]" value="1">yes' +
'<input class="price_show" type="radio" name="form[' + serviceCount + '][price_show]" value="0">no' +
'</div></div>';
$('.wrapper_servp').last().after(serv_inputs + p_show + inputs);
$('#saveserv').removeClass('hideb');
$('#remser').css('display', 'inline');
});
$('#cancelserv').click(function(e) {
e.preventDefault();
//var newinputs = $('.wrapper_servp').length;
//var inp_remv = newinputs - originals_ser_input_lgth;
//$('.wrapper_servp').slice(-inp_remv).remove()
$('.show_p_inpts')
.filter((i, e) => $('.price_show:checked', e).length === 1)
.replaceWith(function(i) {
var value = $('.price_show:checked').attr('value');
return '<span data-value="' + value + '" class="value">' + (value == 1 ? "yes" : "no") + '</span>'
});
});
var groupHasCheckedBox = function() {
return $(this).find('input').filter(function() {
return $(this).prop('checked');
}).length === 0;
},
inputHasValue = function(index) {
return $(this).val() === '';
};
$('#saveserv').click(function(e) {
e.preventDefault();
//from here
var $radioGroups = $('.show_p_inpts');
$('.show_p_inpts').filter(groupHasCheckedBox).closest('div').addClass("error");
$('.services, .price').filter(inputHasValue).addClass("error");
//to here
var $errorInputs = $('input.services').filter((i, e) => !e.value.trim());
if ($errorInputs.length >= 1) {
console.log($errorInputs);
$('#err_message').html('you have to fill in the service'); return;
}
if ($('input.price').filter((i, e) => !e.value.trim()).length >= 1) {
$('#err_message').html('you have to fill in the price'); return;
}
});
var IDs=new Array();
$('body').on('click', '#remser', function(e){
var inputval=$('.services:visible:last').val();
if(inputval!=='')
{r= confirm('Are you sure you want to delete this service?');}
else
{
$('.wrapper_servp:visible:last').remove();
}
switch(r)
{
case true:
IDs.push($('.services:visible:last').data('service'));
$('.wrapper_servp:visible:last').addClass('btypehide');
if($('.serv_contain').length==1)$('#remser').css('display','none');
$('#saveserv').removeClass('hideb').css('border','5px solid red');
//originals.servrem=true;
break;
case false:var i;
for(i=0;i<originals.ser_input_lgth;i++)
{
$('input[name="service'+i+'"]').val(services[i].value);
$('input[name="price'+i+'"]').val(prices[i].value);//εδω set value
}
$('.services').slice(originals.ser_input_lgth).remove();
$('.price').slice(originals.ser_input_lgth).remove();
$('.openservices').addClass('hide').find('.services,.price').prop('readonly', true);
var text='<p class="show_price">Θες να φαίνεται η τιμή;<span data-value="'+ show_pr_val.value +'" class="value">' +(show_pr_val.value==1 ? 'yes':'no') + '</span></p>';
$('.show_p_inpts').remove();
$('.show_price').replaceWith(text);;
break;
}
});
I have an Idea for you. What you can do is when you show the currently existed value in you html instead of giving name attribute just give data-name attribute. I.e
Change this
<input class="services text" data-service="21" size="40" value="hair" type="text" name="service0" readonly="">
To This
<input class="services text" data-service="21" size="40" value="hair" type="text" data-value="hair" data-name="service0" readonly="">
Now when user update this values you can bind an event in jQuery like below.
$(document).ready(function(){
$(".services input").on("change paste keyup", function() {
if($(this).val() === $(this).attr("data-value"))
{
$(this).removeAttr("name");
}else{
$(this).attr("name",$(this).attr("data-name"));
}
});
});
By this way you can give name attribute to only those elements whose values are changed. Now each time you can serialize the whole form and it will only get the value of changed elements.
Don't forget to give unique class to already existed elements so you can bind on change event. Hope its clear to you.
So, i have a simple form like this:
<div class="form-group">
<label class="">No Inventaris</label>
<div id="container">
<input type="button" name="noInv" class="form-control" id="add_field" value="Klik untuk membuat text field baru"><br>
<script type="text/javascript">
var count = 0;
$(function(){
$('#add_field').click(function(){
count += 1;
$('#container').append(
'<strong >No Inv Barang Ke ' + count + '</strong><br />'
+ '<select id="field_' + count + '" name="fields[]' + '" class="form-control no_inv"><?php $noInv = $this->modelku->select_inv() ?> <?php foreach($noInv->result() as $inv){ ?> <option value="<?php echo $inv->no_inv ?>"><?php echo $inv->no_inv ?></option><?php } ?></select><br>' );
});
});
</script>
</div>
When i click the button the field will regenerate select option, and the value is from database
select_inv function:
public function select_inv()
{
$this->db->select("no_inv");
$this->db->from('detail_barang');
$this->db->where("kondisi = 'Ada' ");
$query = $this->db->get();
return $query;
}
My Question: How can i disable value in select option when it already selected by another select option?
Try this if this is what you need.
i just created a sample dropdown and in my jquery i trigger the event change using the class of all select option then i will get the value of the select and id. after getting the value i check the val if it is empty or not if not empty then i will use the each function for all the select and get their id attribute so i can compare it with the id of the select and if their id is not the same then i will disabled the option with the same value of the selected dropdown.
and i use focus event for getting the previous value so i can reset whether the user change the value of the selected option.
$( document ).ready(function() {
$('body').on('click','#add_field',function(){
count += 1;
$('#container').append(
'<strong >No Inv Barang Ke ' + count + '</strong><br />'
+ '<select id="field_' + count + '" name="fields[]' + '" class="form-control no_inv select_alternate"> <option value="">select</option><option value="test1">test1</option><option value="test2">test2</option><option value="test3">test3</option></select><br></select><br>' );
});
var count =0;
var previous;
var selectedData = [];
$('body').on('click','.select_alternate',function(){
previous = this.value;
});
$('body').on('change','.select_alternate',function(){
var val = this.value;
var id = $(this).attr('id');
if(val != ''){
$(".select_alternate").each(function(){
var newID = $(this).attr('id');
if(id != newID){
$('#'+newID).children('option[value="' + val + '"]').prop('disabled',true);
$('#'+newID).children('option[value="' + previous + '"]').prop('disabled',false);
selectedData.splice($.inArray(val, selectedData),1);
}else{
selectedData.push(val);
}
});
}else{
$(".select_alternate").each(function(){
var newID = $(this).attr('id');
if(id != newID){
$('#'+newID).children('option[value="' + previous + '"]').prop('disabled',false);
}
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<label class="">No Inventaris</label>
<div id="container">
<input type="button" name="noInv" class="form-control" id="add_field" value="Klik untuk membuat text field baru"><br>
</div>
I have developed customise autocomplete which works fine in terms of data pulling and displaying in the page. I want to enhance it. I want to implement something like this (multiple dataset of typeahead pluggin) where I want to select or set focus on the next and previous li of my autocomplete when down / up arrow key is pressed. Here is my jquery code which populate the autocomplete.
$("input[data-tg-autocomplete]").keyup(function (e) {
if (e.keyCode == 40 || e.keyCode == 38) {
//alert(e.keyCode);
DownUpKeyPress(e.keyCode);
}
else {
var $input = $(this);
//-----------------------------Allowing user to enter atleast one character for auto search
if ($input.val().length > 0) {
var request = $.ajax({
url: $input.attr("data-tg-autocomplete"),
method: "GET",
data: { term: $input.val() },
dataType: "json"
});
request.done(function (JsonData) {
LoadAutoSuggest(JsonData);
});
request.fail(function (jqXHR, textStatus) {
//alert("Request failed: " + textStatus);
});
}
}
});
//========================populate autocomplete
function LoadAutoSuggest(result) {
var tag = "";
$('.custom-autocomplete').html("");
if (result.Destination != undefined) {
tag = tag + "<li class=''>";
tag = tag + "<a href='#' class='list-group-item active disabled AutoCompleteHeader'>";
tag = tag + "Destination";
tag = tag + "</a>";
tag = tag + "</li>";
for (i = 0; i < result.Destination.length - 1; i++) {
tag = tag + "<li class='list-group-item'>";
tag = tag + "<a class='autocompleteListItem' data-type='Destination' data-id='" + result.Destination[i].DestinationID + "'>";
tag = tag + "<div>";
tag = tag + result.Destination[i].DestinationName;
// tag = tag + "<span class='pull-right badge'>14</span>";
tag = tag + "</div>";
tag = tag + "</a>";
tag = tag + "</li>";
}
}
if (result.Business != undefined) {
tag = tag + "<li class=''>";
tag = tag + "<a href='#' class='list-group-item active disabled AutoCompleteHeader'>";
tag = tag + "Business";
tag = tag + "</a>";
tag = tag + " </li>";
for (i = 0; i < result.Business.length - 1; i++) {
tag = tag + "<li class='list-group-item'>";
tag = tag + "<a class='autocompleteListItem' data-type='Business' data-id='" + result.Business[i].BusinessID + "'>";
tag = tag + "<div>";
tag = tag + result.Business[i].BusinessName;
// tag = tag + "<span class='pull-right badge'>14</span>";
tag = tag + "</div>";
tag = tag + "</a>";
tag = tag + "</li>";
//alert(result.Business[i].BusinessName + " ID = " + result.Business[i].BusinessID)
}
}
$('.custom-autocomplete').html(tag);
$('.autocompleteListItem').click(function () {
var id = $(this).attr("data-id");
var type = $(this).attr("data-type");
var text = $(this).text();
$("#searchtext").val(text);
$('.HiddenSearchInput #id').val(id);
$('.HiddenSearchInput #type').val(type);
$('.custom-autocomplete').html("");
$('.Search-submit').trigger("click");
});
$(':not(".search-wrapper")').click(function () {
if ($('.custom-autocomplete li').length > 0) {
$('.custom-autocomplete').html("");
}
});
$('.custom-autocomplete li.list-group-item').first().addClass("focused");
}
function DownUpKeyPress(keyCode) {
//$this = $(this);
if (keyCode == 40) {
// alert('40');
// $this.next().focus();
if ($('.custom-autocomplete li').length > 0) {
var $focused = $('.custom-autocomplete li.focused');
$('.custom-autocomplete li.focused ~ .list-group-item').first().addClass('focused')
$focused.removeClass('focused')
}
return false;
} else if (keyCode == 38) {
//alert('38');
// $this.prev().focus();
if ($('.custom-autocomplete li').length > 0) {
}
return false;
}
}
and here is my html where I am populating the autocomplete
<div class="Search-container">
<span class="error search-validation"></span>
<div class="input-group input-group-lg">
<input id="searchtext" name="searchtext" type="text" class="form-control " placeholder="Find travel agents, search travel agents in your destination" data-tg-autocomplete="#Url.Action("AutocompleteBusiness")" />
<span class="input-group-btn">
<button class="btn btn-primary Search-submit" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div><!-- /input-group -->
<div class="displaynone HiddenSearchInput">
<input type="hidden" id="id" name="id" value="" />
<input type="hidden" id="type" name="type" value="" />
</div>
</div>
<ul class="list-group custom-autocomplete">
#*List will be populated from ajax call in function LoadAutoSuggest*#
</ul>
My function DownUpKeyPress is for setting focus for next and previous li. Focused li item will be used for site search but I am not been able to set focus on the next and previous li when up/down arrow is pressed. I am using MVC5 for developing my project. Probably I am wrong with jquery. May someone help me out to fix the issue. I dont want to use any pluggin for this.
Add this code in DownUpKeyPress
// for up arrow => Previous Li Focus
if (keyCode == 40) {
if ($('.custom-autocomplete li').length > 0) {
var oBox = $('.custom-autocomplete > .list-group-item.focused').next('li');
var curClass = oBox.attr("class");
if (oBox.length == 0) {
$('.custom-autocomplete > .list-group-item.focused').removeClass('focused');
$('.custom-autocomplete > .list-group-item').first().addClass('focused');
}
else if (curClass == "") {
$('.custom-autocomplete > .list-group-item.focused').removeClass('focused').next('li').next('li').addClass('focused');
}
else {
$('.custom-autocomplete > .list-group-item.focused').removeClass('focused').next('li').addClass('focused');
}
}
return false;
}
// for down arrow => Next Li Focus
else if (keyCode == 38) {
if ($('.custom-autocomplete li').length > 0) {
var oBox = $('.custom-autocomplete > .list-group-item.focused').prev('li');
var curClass = oBox.attr("class");
if (oBox.length == 0) {
$('.custom-autocomplete > .list-group-item.focused').removeClass('focused');
$('.custom-autocomplete > .list-group-item').last().addClass('focused');
}
else if (curClass == "") {
$('.custom-autocomplete > .list-group-item.focused').removeClass('focused').prev('li').prev('li').addClass('focused');
}
else {
$('.custom-autocomplete > .list-group-item.focused').removeClass('focused').prev('li').addClass('focused');
}
}
return false;
}
I have a button that adds two input field onclick. Below is the code:
<button type="button" class="btn btn-warning btn-xs" id="additem">
Click here to add Items</button>
<form>
<div id="inputboxes"></div>
<input type="submit">
</form>
and JQuery is
var i = 1,
j = 1,
k = 1,
l = 1;
$("#additem").click(function () {
$("#inputboxes").append("<div class='form-group'><input type='text' id='iname" +
(j++) +
"' name='iname" +
(i++) +
"' class='form-control' placeholder='Enter Item Name' required='required'/></div> " +
"<div class='form-group'><input type='text' id='iprice" +
(k++) +
"' name='iprice" +
(l++) +
"' class='form-control' placeholder='Enter Item Price' required='required'/></div>");
})
How can i validate these dynamically added input boxes for empty and correct values on submitting the form?
You can do something like:
$('.form-group').each(function(){
var input = $(this).children('input');
if(input.val() == '' || input.val() == undefined){
// the errors you will give
}else{
if(input.attr('id').substring(0, 5) == 'iname'){
//function to validate your iname
}else if(input.attr('id').substring(0, 6) == 'iprice'){
//function to validate your iprice
}
}
});