Dynamically create multiple nested input fields in angularjs - javascript

I have a form, but within that form I have a Add Schedule button which is to generate four input fields (Base Date Key, Forward Backward, Schedule ID) and a Add Schedules button. Additionally, that Add Schedules button (which is a child of the Add Schedule button) can generate five input fields (Schedule Amount, Schedule Charge Code, Frequency, Schedule date, Schedule type).
I have made attempt to doing so, but it is not working out for me at all. Here is a snippet of the html :
<ng-form name="" ng-repeat="form in forms1">
<button class="btn btn-success btn-md" ng-click="addNewSchedule(form)">
<i class="fa fa-plus-circle fa-fw"></i> Add Schedule
</button><br>
<div ng-repeat="cont in form.schedule">
<div class="row">
<div class="col-md-6">
<label>Base Date Key <span style="color: red;">*</span></label>
<select name="base_date_key" class="form-control" ng-model="cont.base_date_key" ng-options="base_key for base_key in base_date_key">
<option value="">Select Base Date Key</option>
</select>
</div>
<div class="col-md-6">
<label>Forward Backward <span style="color: red;">*</span></label>
<select name="forward_backward" class="form-control" ng-model="cont.forward_backward" ng-options="forward for forward in forward_backward">
<option value="">Select Forward Backward Option</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<label>Schedule ID </label>
<input type="text" name="schedule_id" class="form-control" ng-model="cont.schedule_id">
</div>
</div>
<button class="btn btn-success btn-md" ng-click="addNewSchedules($index)">
<i class="fa fa-plus-circle fa-fw"></i> Add Schedules
</button><br>
<div ng-repeat="scheduleData in schedules">
<div class="row">
<div class="col-md-4">
<label>Schedule Amount <span style="color: red;">*</span></label>
<input type="text" name="schedule_amount" class="form-control" ng-model="scheduleData.schedule_amount">
</div>
<div class="col-md-4">
<label>Schedule Charge Code</label>
<select name="charge_code" class="form-control" ng-model="scheduleData.schedule_charge_code" ng-options="charge_two.key as charge_two.value for charge_two in schedule_charge_code track by charge_two.key">
<option value="">Select Schedule Charge Code</option>
</select>
</div>
<div class="col-md-4">
<label>Frequency <span style="color: red;">*</span></label>
<input type="text" name="frequency" class="form-control" ng-model="scheduleData.frequency">
</div>
</div>
<br>
<div class="row">
<div class="col-md-4">
<label>Schedule Date <span style="color: red;">*</span> </label>
<input type="text"
class="form-control"
datepicker-popup="yyyy-MM-dd"
ng-model="scheduleData.schedule_date"
is-open="schedule_date.open"
ng-click="schedule_date.open = true"
datepicker-options="scheduleDateOptions"
date-disabled="disabled(date, mode)"
ng-required="true"
close-text="Close" />
</div>
<div class="col-md-4">
<label>Schedule Type <span style="color: red;">*</span></label>
<select name="schedule_type" class="form-control" ng-model="scheduleData.schedule_type" ng-options="schedule for schedule in schedule_type">
<option value="">Select Schedule Type</option>
</select>
</div>
</div>
</div>
</div>
<br>
Also here is what I have done on JavaScript side :
var schedules = [];
$scope.forms1 = [{base_date_key: "",forward_backward: "",schedule_id: ""}];
$scope.addNewSchedule = function(form1){
console.log(form1.schedule);
if(typeof form1.schedule === 'undefined') {
form1.schedule = [];
}
form1.schedule.push({name:"",base_date_key: "",forward_backward: "",schedule_id: ""});
schedules = form1.schedule;
};
$scope.addNewSchedules = function(index){
console.log(index);
$scope.schedules.push({schedule_amount : "", schedule_charge_code:"", frequency: "M", schedule_date:"" ,schedule_type:""});
};
the end result should be in a JSON format like this:
[{
schedule : [
base_date_key: "",
forward_backward:"",
schedule_id:"",
schedules : [{
schedule_amount : "",
schedule_charge_code: "",
frequency: "",
schedule_date: "",
schedule_type: ""
}]
]
}]
Thanks in advance for your help.

Related

Button onClick prevent focus on another form field?

I have form with few input field, one of the input fields has button where users can click. After the click on that button automatically focus will jump to the top form field. I would like to prevent focus on any field because onClick will show modal box in this case. Here is example:
<form name="frmSaveuser" id="frmSaveuser" class="frm-agencySubmit" data-frm="SaveUser" autocomplete="off">
<div class="form-group required">
<label class="control-label" for="activestaff"><span class="label label-primary">Active Staff:<span></label>
<select class="form-control" name="frmSaveaccount_activestaff" id="frmSaveaccount_activestaff" required>
<option value="">-- Select the option --</option>
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div class="form-group required">
<label class="control-label" for="position"><span class="label label-primary">Position:</span></label>
<div class="input-group">
<input type="text" class="form-control" name="frmSaveaccount_position" id="frmSaveaccount_position" placeholder="Choose Position" readonly>
<div class="input-group-btn">
<button class="btn btn-success modal-master" name="btn-position" id="btn-position" data-code="position">
<span class="glyphicon glyphicon-plus-sign"></span>
</button>
</div>
</div>
</div>
</form>
Here is JQuery code:
$('.modal-master').on('click',showMaster);
function showMaster() {
var masterCode = $(this).data('code');
console.log(masterCode);
}
If anyone know the way how to prevent focus in my function please let me know.
It focus on top field because default behaviour of button element is to submit form.
If you don't want to submit form on button click, you have to add type="button" to your html of button
<button type="button" class="btn btn-success modal-master" name="btn-position" id="btn-position" data-code="position">
Use the event prevent default :
first pass the event to your function then use the event.preventDefault(); to prevent event default action .
$('.modal-master').on('click',showMaster);
function showMaster(e) {
e.preventDefault();
var masterCode = $(this).data('code');
console.log(masterCode);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="frmSaveuser" id="frmSaveuser" class="frm-agencySubmit" data-frm="SaveUser" autocomplete="off">
<div class="form-group required">
<label class="control-label" for="activestaff"><span class="label label-primary">Active Staff:</span> </label>
<select class="form-control" name="frmSaveaccount_activestaff" id="frmSaveaccount_activestaff" required>
<option value="">-- Select the option --</option>
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<div class="form-group required">
<label class="control-label" for="position"><span class="label label-primary">Position:</span></label>
<div class="input-group">
<input type="text" class="form-control" name="frmSaveaccount_position" id="frmSaveaccount_position" placeholder="Choose Position" readonly>
<div class="input-group-btn">
<button class="btn btn-success modal-master" name="btn-position" id="btn-position" data-code="position">
<span class="glyphicon glyphicon-plus-sign"></span>
</button>
</div>
</div>
</div>
</form>

Last-child not working inside iteration of div

In browser, the HTML is generated dynamically and is rendered as
<div id="dynamic-relationship-details">
<div id="count-status0" class="relationship-container form-group">
<div class="col-sm-1"></div>
<div class="col-sm-2">
<select id="relationship-type0" class="form-control"><option value="">Select Relationship</option><option value="Father">Father</option><option value="Mother">Mother</option><option value="Brother">Brother</option><option value="Sister">Sister</option><option value="Spouse">Spouse</option><option value="Guardian">Guardian</option></select>
</div>
<div class="col-sm-3">
<input type="text" name="relationship-type-name0" id="relationship-type-name0" class="form-control" placeholder="Name"></div><div class="col-sm-2"><input type="text" name="relationship-type-contact0" id="relationship-type-contact0" class="form-control" placeholder="Contact Number">
</div>
<button value="count-status0" class="remove-relationship-field btn btn-danger"><i class="fa fa-trash"></i></button>
</div><div id="count-status1" class="relationship-container form-group">
<div class="col-sm-1"></div>
<div class="col-sm-2">
<select id="relationship-type1" class="form-control"><option value="">Select Relationship</option><option value="Father">Father</option><option value="Mother">Mother</option><option value="Brother">Brother</option><option value="Sister">Sister</option><option value="Spouse">Spouse</option><option value="Guardian">Guardian</option></select>
</div>
<div class="col-sm-3">
<input type="text" name="relationship-type-name1" id="relationship-type-name1" class="form-control" placeholder="Name"></div><div class="col-sm-2"><input type="text" name="relationship-type-contact1" id="relationship-type-contact1" class="form-control" placeholder="Contact Number">
</div>
<button value="count-status1" class="remove-relationship-field btn btn-danger"><i class="fa fa-trash"></i></button>
</div>
</div>
The code is
// Relationship details Array
$(".relationship-container").each(function(i, obj) {
var $this = $(this);
$this.find("select").each(function() {
var relationshipTypeValue = $(this).val();
var relationshipName =$this.find("input[type=text]:first-child").val();
var relationshipContactNumber =$this.find("input[type=text]:last-child").val();
var innerRelationshipArray = {};
innerRelationshipArray = {
relationshipTypeValue: relationshipTypeValue,
relationshipName: relationshipName,
relationshipContactNumber: relationshipContactNumber
};
relationship_details_array.push(innerRelationshipArray);
});
});
I am trying to fetch values of contact numbers i.e with id's relationship-type-contact(n) values in the line "
var relationshipContactNumber =$this.find("input[type=text]:last-child").val();"
This is fetching values of first-child textboxes in the variable relationshipContactNumber in the loop.
Please help !!!
This should work, use the .first() and .last() selectors.
Another way, if you have access to alter the HTML, is to add class names for the input fields and select them by using that instead.
function getData() {
var relationship_details_array = [];
// Relationship details Array
$(".relationship-container").each(function(i, obj) {
var $this = $(this);
$this.find("select").each(function() {
var relationshipTypeValue = $(this).val();
var relationshipName = $this.find("input[type=text]").first().val();
var relationshipContactNumber = $this.find("input[type=text]").last().val();
var innerRelationshipArray = {};
innerRelationshipArray = {
relationshipTypeValue: relationshipTypeValue,
relationshipName: relationshipName,
relationshipContactNumber: relationshipContactNumber
};
relationship_details_array.push(innerRelationshipArray);
});
});
console.log(relationship_details_array);
}
$("#getData").on("click", getData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="getData">Show data in console log</button>
<div id="dynamic-relationship-details">
<div id="count-status0" class="relationship-container form-group">
<div class="col-sm-1"></div>
<div class="col-sm-2">
<select id="relationship-type0" class="form-control">
<option value="">Select Relationship</option>
<option value="Father">Father</option>
<option value="Mother" selected>Mother</option>
<option value="Brother">Brother</option>
<option value="Sister">Sister</option>
<option value="Spouse">Spouse</option>
<option value="Guardian">Guardian</option>
</select>
</div>
<div class="col-sm-3">
<input type="text" name="relationship-type-name0" id="relationship-type-name0" class="form-control" value="Mommy" placeholder="Name">
</div>
<div class="col-sm-2">
<input type="text" name="relationship-type-contact0" id="relationship-type-contact0" class="form-control" value="1234" placeholder="Contact Number">
</div>
</div>
<div id="count-status1" class="relationship-container form-group">
<div class="col-sm-1"></div>
<div class="col-sm-2">
<select id="relationship-type1" class="form-control">
<option value="">Select Relationship</option>
<option value="Father" selected>Father</option>
<option value="Mother">Mother</option>
<option value="Brother">Brother</option>
<option value="Sister">Sister</option>
<option value="Spouse">Spouse</option>
<option value="Guardian">Guardian</option>
</select>
</div>
<div class="col-sm-3">
<input type="text" name="relationship-type-name1" id="relationship-type-name1" class="form-control" value="Daddy" placeholder="Name">
</div>
<div class="col-sm-2">
<input type="text" name="relationship-type-contact1" id="relationship-type-contact1" class="form-control" value="5678" placeholder="Contact Number">
</div>
</div>
</div>

angular: Function is not getting invoke

there is form in my html and I am using default validation "required" field property to validate the fields and checking using $valid at last and calling a function which is not getting invoke. when I removed "batchAttForm.$valid" then funciton is working but with that line its not getiing called. what can be the problem ??
html
<form id="batchAttForm" name="batchAttForm" class="form-horizontal">
<div class="form-group row">
<label class="control-label col-md-1" align="right" for="batchDate"></label>
<label class="control-label col-md-1" align="right" for="batchDate">Date</label>
<div class="col-md-2 ">
<div class="input-group" >
<span class="input-group-btn">
<button class="btn btn-default"><i class="fa fa-calendar"></i></button>
</span>
<input type="text" id="batchDate" ng-change="dateChange()" name="batchDate" ng-model="batch.date" datepicker class="form-control digits" required>
</div>
</div>
<label class="control-label col-md-1" align="right" for="selectBatch">Batch</label>
<div class="col-md-2" >
<select id="selectBatch" name="selectBatch" ng-change="selectedBatch(batch.id)" ng-model="batch.id" class="form-control" required>
<option value="">Select</option>
<option ng-repeat="batch in batch.batches" value="{{batch.id}}">{{batch.batch}}</option>
</select>
</div>
<label class="control-label col-md-1" align="right" for="selectBatch">Timing</label>
<div class="col-md-2 ">
<select id="selectBatch" name="selectBatch" ng-model="batch.time" class="form-control" required>
<option value="">Select</option>
<option ng-repeat="time in batch.times" value="{{batch.time}}">{{time.start_time_string}} - {{time.end_time_string}}</option>
</select>
</div>
</div>
<br>
<div class="form-group form-action">
<label class="control-label col-md-3" align="right" for=""></label>
<div class="col-md-2">
<button type="submit" id="reschedule" ng-click="batchAttForm.$valid && reschedule()" class="btn btn-default"><i class="fa fa-undo"></i> Re-schedule</button>
</div>
<div class="col-md-2" >
<button type="submit" id="punchAtt" ng-click="batchAttForm.$valid && punchAttendance()" class="btn btn-success"> <i class="fa fa-check"></i> Punch </button>
</div>
</div>
</form>
controller
app.controller('batchAttendanceController',function($scope,apiCall) {
$scope.batch = {};
$scope.batch.date = moment().format("DD-MM-YYYY");
//methods
$scope.selectedBatch = selectedBatch;
$scope.punchAttendance = punchAttendance;
$scope.reschedule = reschedule;
$scope.dateChange = dateChange;
function punchAttendance() {
console.log("foo");
}
function reschedule() {
console.log("bar");
}
function dateChange() {
initController($scope.batch.date);
}
function selectedBatch(batch_id) {
var b = $scope.batch.batches;
for (var i=0; i < b.length; i++) {
if (b[i].id == batch_id) {
for (var j=0; j < b[i].batch_time.length; j++) {
b[i].batch_time[j].start_time_string = moment(b[i].batch_time[j].start_time,"HH:mm:ss").format("hh:mm A");
b[i].batch_time[j].end_time_string = moment(b[i].batch_time[j].end_time,"HH:mm:ss").format("hh:mm A");
}
$scope.batch.times = b[i].batch_time;
} else {
$scope.batch.times = [];
}
}
}
});
The reason for error is, you have two form elements select with same name and idattribute . This is the reason, your form is always invalid. .
<label class="control-label col-md-1" align="right" for="selectBatch">Batch</label>
<div class="col-md-2" >
<select id="selectBatch" name="selectBatch" ng-change="selectedBatch(batch.id)" ng-model="batch.id" class="form-control" required>//same name and id
<option value="">Select</option>
<option ng-repeat="batch in batch.batches" value="{{batch.id}}">{{batch.batch}}</option>
</select>
</div>
<label class="control-label col-md-1" align="right" for="selectBatch">Timing</label>
<div class="col-md-2 ">
<select id="selectBatch" name="selectBatch" ng-model="batch.time" class="form-control" required>//same name and id
<option value="">Select</option>
<option ng-repeat="time in batch.times" value="{{batch.time}}">{{time.start_time_string}} - {{time.end_time_string}}</option>
</select>
</div>
Try using the ng-click as ng-submit in form element and remove ng-click in button

jquery increment only works in chrome

$(".incrementer").click(function(){
var values = $("#layernumber").val();
var item = $("input[type=file]:last").clone(true);
var txt = $(".layer_selector:last").after('<br>').clone(true);
if($("#layernumber").val() < 4){
$("#attach").append(item);
$("#attach").append(txt);
}
if($("#layernumber").val() > 2){
$(".incrementer").hide();
}
});
The above code increments the value of layers
as the layers increments the file upload option will also.
But this works only in Chrome. Not in FireFox or Internet Explorer.
HTML code is:
<div class="tab-pane active" id="tab2">
<h3 class="block">Provide your layer details</h3>
<div class="form-group">
<label class="control-label col-md-3">Number of layer
<span class="required" aria-required="true"> * </span>
</label>
<div class="col-md-4">
<div class="input-group bootstrap-touchspin">
<span class="input-group-addon bootstrap-touchspin-prefix" style="display: none;"></span>
<input id="layernumber" type="text" class="form-control" name="layernumber" style="display: block;">
<span class="input-group-addon bootstrap-touchspin-postfix" style="display: none;"></span>
<span class="input-group-btn-vertical">
<button class="btn btn-default bootstrap-touchspin-up" type="button">
<i class="glyphicon glyphicon-plus incrementer"></i>
</button>
<button class="btn btn-default bootstrap-touchspin-down" type="button">
<i class="glyphicon glyphicon-minus decrementer"></i>
</button>
</span>
</div>
<span class="help-block"> Provide your number of layers </span>
</div>
</div>
<!-- fileupload starts-->
<!-- -->
<div class="form-group">
<label class="control-label col-md-3">Choose Layer
<span class="required" aria-required="true"> * </span>
</label>
<div class="col-md-9">
<div id="attach">
<div id="previewImg"></div>
<div class="col-md-9">
<input type="file" name="layerimages[]" onchange="preview(this);" class="myfile" id="fileid" multiple="">
<select id="layerid" class="layer_selector" name="layer_selector">
<option value="">Please Select</option>
<option value="0">First</option>
<option value="1">Second</option>
<option value="2">Intermediate</option>
<option value="3">Final</option>
</select>
</div>
</div>
<br>
</div>
</div>
<!-- fileupload ends-->
</div>
I have made a fiddle for this.
https://jsfiddle.net/w1gy8ruj/1/
The changes i did to your code is basically initialise the value of the layernumber input to 0 and increment it on every click.
$(document).ready(function() {
$(".incrementer").click(function() {
var values = $("#layernumber").val();
var item = $("input[type=file]:last").clone(true);
var txt = $(".layer_selector:last").after('<br>').clone(true);
if ($("#layernumber").val() < 4) {
$("#attach").append(item);
$("#attach").append(txt);
}
if ($("#layernumber").val() > 2) {
$(".incrementer-button").hide();
}
values++;
$("#layernumber").val(values);
});
});
You do not use
var values = $("#layernumber").val();
anywhere in this scope, so this is unneeded unless you don't want to use it in the if statement below and for incrementing.
And you do not increment the layernumber, so
if($("#layernumber").val() > 2) {
will never execute. You should increment it and set it like
$("#layernumber").val(values)

Jquery get value of select in div above

I have the following HTML form. I'm trying to get the value of the .plotNumber select and also the value of the sub_category field.
Note: The user is able to add new rows to the form, so there may be multiple blocks of <div class="standard-row add-admin-row input-row">.
My code so far (which works) apart from the plot and category is:
$('.wrapper').on('input', '.inp-calculate', function(e)
{
var input = $(this);
//var plot = input.val(); // get plot id
//var category = input.val(); // get category id
var units = input.val(); // get units
$.post('checkUnits.php', {
plot_id: plot,
category_id: category,
units: units
}, function(data) {
var data = $.parseJSON(data);
if(data[0] !== true) {
alert(data);
input.focus();
input.val('');
}
});
});
I have tried the following solutions which do not work:
$(this).parent().siblings().find('.plotNumber').val();
HTML Code:
<form class="commentForm add-project-form clearfix" id="addWorksheet">
<div class="box box3 clearfix">
<div id="messages"></div>
<div class="sectionbox">
<fieldset class="clonable">
<legend><span>Worksheet</span></legend>
<p class="error-summary error-message"></p>
<div class="standard-row add-admin-row input-row">
<label class="ib">
<span class="label-stacked">Employee</span>
<span class="plain-select">
<select class="inp" data-myname="worksheet[*][employee]" name="employee">
<option value="">Select one...</option>
<option value="1">Test 1</option>
</select>
</span>
</label>
<label class="ib">
<span class="label-stacked">Week ending</span>
<span class="plain-select">
<select class="inp" data-myname="worksheet[*][week_ending]" name="week_ending">
<option value="">Select one...</option>
<option value="Sunday 22 Nov 2015">Sunday 22 Nov 2015</option>
</select>
</span>
</label>
<label class="ib">
<span class="label-stacked">Project</span>
<span class="plain-select">
<select class="inp project" data-myname="worksheet[*][project]" name="project">
<option value="">Select one...</option>
<option value="2">TEST</option>
</select>
</span>
</label>
</div>
<div class="standard-row wsheet-row input-row">
<label class="ib plothead ">
<span class="label-stacked">Plot Number</span>
<span class="plain-select">
<select class="inp plotNumber plotheadclone" data-myname="worksheet[*][plots][!][plot_number]" name="plot_number">
<option value="">Select one...</option>
<option value="6672">444</option>
<option value="6673">555</option>
<option value="6674">666</option>
</select>
</span>
</label>
<div class="plot-offset clearfix">
<div class="standard-row wsheet-row input-row" id="5438">
<label class="ib">
<span class="label-stacked">Category</span>
<select class="inp inp220 inp-disabled" readonly="" data-myname="worksheet[*][plots][!][sub_category][]" name="sub_category">
<option value="5438">NON LABOUR</option>
</select>
</label>
<label class="ib"><span class="label-stacked">Total</span>
<input class="inp inp110 data-addup-total inp-calculate" data-myname="worksheet[*][plots][!][total_cost][]" name="total_cost" value="0.00" type="text">
<input data-myname="worksheet[*][plots][!][price][]" name="price" value="" type="hidden">
<input data-myname="worksheet[*][plots][!][number_units][]" name="number_units" value="" type="hidden">
</label>
</div>
<div class="standard-row wsheet-row input-row" id="5240">
<label class="ib">
<span class="label-stacked">Category</span>
<select class="inp inp220 inp-disabled" readonly="" data-myname="worksheet[*][plots][!][sub_category][]" name="sub_category">
<option value="5240">1ST FIX CYLINDER</option>
</select>
</label>
<label class="ib">
<span class="label-stacked">Price</span>
<input class="inp inp110 inp-disabled" readonly="" data-myname="worksheet[*][plots][!][price][]" name="price" value="£40.00" type="text"></label>
<label class="ib"> <span class="label-stacked">Number</span>
<input class="inp inp55 inp-calculate" data-myname="worksheet[*][plots][!][number_units][]" name="number_units" value="" type="text"></label><label class="ib"><span class="label-stacked">Total</span><input class="inp inp110 inp-disabled data-addup-total" readonly="" data-myname="worksheet[*][plots][!][total_cost][]" name="total_cost" value="£0.00" type="text"></label>
</div>
<div class="wsheet-labour-total">LABOUR: £80.00</div>
<div class="wsheet-nonlabour-total">NON LABOUR: £0.00</div>
<div class="wsheet-final-total">TOTAL CLAIM: £80.00</div>
</div>
</div>
</fieldset>
<div class="reveal-plot showingPlot"> Choose another plot</div>
</div>
<!-- end section box -->
<hr class="divider">
<div class="clonable">
<div class="clone empty"></div>
<div class="cb">
<div>
<p class="add remove-data"><i class="sprite minus2"></i> <span>Remove last row</span></p>
</div>
<div>
<p class="add add-data add-another-worksheet-employee"><i class="sprite plus2"></i> <span>Add another worksheet</span></p>
</div>
</div>
</div>
<div class="save-submit">
<button class="button" type="submit" data-url="addWorksheet.php" data-id="#addWorksheet">Submit</button>
</div>
</div>
<!-- end box -->
</form>
Can someone help find the solution?
You're not traversing far enough up the DOM with .parent() since the select is contained in a <div> three levels above .inp-calculate. How about:
$(this).closest('fieldset').find('.plotNumber').val();
Try like following. Hope this will help you.
var container=$(this).closest('.standard-row.add-admin-row.input-row');
var plot=container.find('.plotNumber').val();
var category=container.find('.inp220').val();

Categories