using range date filtering with datatable - database

I am using datatable with yii1. I have following code in my view file:
<div class="form-group col-xs-12 col-md-4">
<label class="col-sm-6 control-label" for="formGroupInputSmall">Member From</label>
<div class="col-sm-6">
<input type='date' class="form-control" value='' id='fini' data-column-index='8'>
</div>
</div>
<div class="form-group col-xs-12 col-md-4">
<label class="col-sm-6 control-label" for="formGroupInputSmall">Member to</label>
<div class="col-sm-6">
<input type='date' class="form-control" value='' id='ffin' data-column-index='9'>
</div>
</div>
In js file I have following code:
$(document).ready(function() {
var table = $('#table_id').DataTable();
/* Add event listeners to the two range filtering inputs */
$('#fini').keyup( function() { table.draw(); } );
$('#ffin').keyup( function() { table.draw(); } );
} );
$.fn.dataTableExt.afnFiltering.push(
function( oSettings, aData, iDataIndex ) {
var iFini = document.getElementById('fini').value;
var iFfin = document.getElementById('ffin').value;
var iStartDateCol = 8;
var iEndDateCol = 9;
iFini=iFini.substring(6,10) + iFini.substring(3,5)+ iFini.substring(0,2);
iFfin=iFfin.substring(6,10) + iFfin.substring(3,5)+ iFfin.substring(0,2);
var datofini=aData[iStartDateCol].substring(6,10) + aData[iStartDateCol].substring(3,5)+ aData[iStartDateCol].substring(0,2);
var datoffin=aData[iEndDateCol].substring(6,10) + aData[iEndDateCol].substring(3,5)+ aData[iEndDateCol].substring(0,2);
if ( iFini === "" && iFfin === "" )
{
return true;
}
else if ( iFini <= datofini && iFfin === "")
{
return true;
}
else if ( iFfin >= datoffin && iFini === "")
{
return true;
}
else if (iFini <= datofini && iFfin >= datoffin)
{
return true;
}
return false;
}
);
When I input date, datatable returns no results. If I change type of <input/> to text, It will search for exact date (not specific date range).

Related

How to bind dynamic element to DOM in angularjs 1.6?

I am creating a dynamic report builder which can have multiple rows. These rows are created dynamically based on the field selected. I am appending the dynamic HTML through my js controller but ng-model is not binded to the DOM. I tried adding $compile(element)($scope) but it didnt work. Please find the screenshot shared below.
HTML
<div class="page-content-wrap">
<form name="reportform" class="reportBuilder" ng-submit="getReport(reportform,report)">
<div class="row">
<div class="form-group col-md-4">
<select class="form-control" name="module" id="module"
ng-model="modules"
ng-options="module as module.formname for module in allModules track by module.id"
ng-change="getFields()">
<option value="" class="">Select Module</option>
</select>
</div>
</div>
<div class="dynamic_block">
<div class="row">
<div class="form-group">
<div class="col-md-4">
<select class="form-control field_type"
ng-model="fields[row_count]"
ng-options="moduleField.name as (moduleField.label) for moduleField in moduleFields">
<option value="" class="">Select Fields</option>
</select>
</div>
{{options}}
<div class="col-md-7 field_to_be_added">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<span ng-click="cloneRow()"><i class="fa fa-plus-circle"></i></span>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button class="btn btn-primary" type="submit">Generate Report</button>
</div>
</div>
</form>
</div>
JavaScript
$scope.cloneRow = function() {
$scope.row_count++;
$scope.model_name = 'field_'+$scope.row_count;
var new_html = $('#dynamic_block_fixed').clone();
$('.dynamic_block:last').after(new_html);
$compile(new_html)($scope);
$('.minus-icon').unbind().bind('click',function(item){
$(item.target).closest('div.dynamic_block').remove();
});
$('.field_type').unbind().bind('change',function(item){
var item_id = $(this).val().split(':');
for(fields in $scope.moduleFields){
if(typeof $scope.moduleFields[fields] != 'undefined') {
if($scope.moduleFields[fields]['name'] == item_id[1]){
createFieldOptions($scope.moduleFields[fields],item.target.parentElement);
}
}
}
});
}
function createFieldOptions(field, target) {
for (f in field) {
var name = field['name'];
if (field[f] == 'text') {
var element = `<input class="form-control" dynamic type="text" ng-model="report.${name}"/>`;
} else if (field[f] == 'textarea') {
var element = `<textarea class="form-control" ng-model="report.${name}"></textarea>`;
} else if (field[f] == 'select') {
var options = [];
for (key in $scope.moduleFields) {
var objectValues = $scope.moduleFields[key];
if (objectValues['type'] == 'select' && objectValues['name'] == name) {
options = objectValues['values'];
}
}
var element = `<select class="form-control" ng-model="report.${name}"><option>Select</option>`;
options.forEach(function(object) {
element += `<option value="${object.value}">${object.label}</option>`;
});
element += "</select>";
} else if (field[f] == 'checkbox-group') {
var checkoptions = [];
for (key in $scope.moduleFields) {
var objectValues = $scope.moduleFields[key];
if (objectValues['type'] == 'checkbox-group' && objectValues['name'] == name) {
checkoptions = objectValues['values'];
}
}
var element = "<span>";
checkoptions.forEach(function(object) {
element += `<label class="check"><input type="checkbox" name="${name}" ng-model="report.${name}" value="${object.value}"/>${object.label}</label>`;
});
element += "</span>";
} else if (field[f] == 'date') {
element = `<input type="date" name="${name}" ng-model="report.${name}"/>`;
} else if (field[f] == 'radio-group') {
var radiooptions = [];
for (key in $scope.moduleFields) {
var objectValues = $scope.moduleFields[key];
if (objectValues['type'] == 'radio-group' && objectValues['name'] == name) {
radiooptions = objectValues['values'];
}
}
var element = "<span>";
radiooptions.forEach(function(object) {
element += `<label class="check"><input type="radio" name="${name}" ng-model="report.${name}" value="${object.value}"/>${object.label}</label>`;
});
element += "</span>";
}
}
angular.element(target).next('div.col-md-7').html(element);
//$(target).next('div.col-md-7').html(element);
$compile(element)($scope);
$scope.$apply();
}
Open to alternative approach if any.
It sounds like you're appending the dynamic HTML in the JQuery style, with parent.append(newHTML) kinda thing; That's not great practice in AngularJS, and also when you have to use $compile, you know something's not quite right.
I would recommend structuring your code in directives and showing and hiding each directive via ng-if.
If you give some HTML examples, I could go more in depth

Open a modal from another modal using bootstrap and angularJs

I am trying to open a modal by clicking on link on the another modal.
Here is my code:
.controller('payoutCtrl', ['$scope', '$uibModal', 'payoutService', function($scope, $uibModal, payoutService) {
console.log('payout');
var vm = this;
$scope.openAddPayout = function(){
var modalInstance = $uibModal.open({
templateUrl: "app/modules/homePage/payment/Payout/addPayoutMethod.tmpl.html",
controller: 'payoutModalCtrl',
controllerAs: 'vm',
size: 'lg',
resolve: {
payoutMethods: function(){
return vm.payoutMethods;
}
}
});
modalInstance.result.then(function() {
console.log('success');
}, function(){
//Do stuff with respect to dismissal
console.log('error');
$state.go('homePage.payment.payout');
});
}
}])
the upper modal is getting open and calling the below controller as well.
.controller('payoutModalCtrl', ['$rootScope', '$scope', '$uibModal', '$uibModalInstance', 'payoutMethods', function($rootScope, $scope, $uibModal, $uibModalInstance, payoutMethods){
var vm = this;
vm.payoutMethods = payoutMethods;
vm.pay = function(method){
console.log(method);
vm.templateUrl;
if(method == 1){
vm.templateUrl = "app/modules/homePage/payment/Payout/check.tmpl.html"
}
else if(method == 2){
vm.templateUrl = "app/modules/homePage/payment/Payout/payPal.tmpl.html"
}
else if(method == 3){
vm.templateUrl = "app/modules/homePage/payment/Payout/directDeposite.tmpl.html"
}
console.log(vm.templateUrl);
var modalScope = $rootScope.$new();
modalScope.modalInstance = $uibModal.open({
templateUrl:vm.templateUrl,
controller: 'addPayoutDetailModalCtrl',
size: 'sm'
});
}
}])
on calling vm.pay function, another modal should open, where I am getting failed. And the best part I am not able to debug is it is not giving any error.
But from Network and Console from developer tool I have noticed that template is getting called but the controller is not getting call.
.controller('addPayoutDetailModalCtrl', ['$uibModalInstance', 'payoutMethods', function($uibModalInstance, payoutMethods){
// $uibModalInstance.close();
console.log('addPayoutDetailModalCtrl call');
}]);
So I am getting the first modal, but from that controller I am not able to open another modal.
Can anyone help!
I have updated the controllers jsfiddle
.controller('payoutCtrl', ['$scope', '$uibModal', function($scope, $uibModal) {
console.log('payoutCtrl');
var vm = this;
$scope.openAddPayout = function(){
var modalInstance = $uibModal.open({
templateUrl: "addPayoutMethod.tmpl.html",
controller: 'payoutModalCtrl',
controllerAs: 'vm',
size: 'lg',
resolve: {
payoutMethods: function(){
return vm.payoutMethods;
}
}
});
modalInstance.result.then(function() {
console.log('success');
}, function(){
console.log('error');
});
}
}])
.controller('payoutModalCtrl', ['$rootScope', '$scope', '$uibModal', '$uibModalInstance', 'payoutMethods', function($rootScope, $scope, $uibModal, $uibModalInstance, payoutMethods){
var vm = this;
console.log('payoutModalCtrl');
vm.payoutMethods = payoutMethods;
$scope.pay = function(method){
vm.templateUrl = "check.tmpl.html";
console.log(vm.templateUrl);
var modalScope = $rootScope.$new();
modalScope.modalInstance = $uibModal.open({
templateUrl:vm.templateUrl,
controller: 'addPayoutDetailModalCtrl',
size: 'sm'
});
}
}])
.controller('addPayoutDetailModalCtrl', ['$uibModalInstance', function($uibModalInstance){
console.log('addPayoutDetailModalCtrl call');
}]);
Here is an example I have used. I deleted a bunch of stuff just to give you an idea. And the main idea is to hide sections you don't want to show, and to show the sections you want to:
Controller:
(function () {
'use strict';
angular.module('app.createReportSchedule')
.controller('createReportScheduleController', createReportScheduleController);
createReportScheduleController.$inject = ['logger', 'manageReportSchedulesFactory', '$scope', '$modalInstance'];
function createReportScheduleController(logger, manageReportSchedulesFactory, $scope, $modalInstance) {
var vm = $scope;
vm.isUpdate = false;
vm.isUpdateNext = false;
vm.schedule = vm.$parent.schedule;
vm.ReportSchedule = {};
vm.SchedulingOptions = {};
vm.SchedulingUpdateOptions = {};
vm.ReportFilters = {};
vm.showReportSchedule = true;
// Reports Begin
vm.showMasterCallReport = false;
vm.showTimeAndMileage = false;
vm.showAllCallsRemote = false;
vm.showAllCalls = false;
// Reports End
vm.showReportScheduleUpdate = false;
// Report Modal Data
vm.MasterCallReportData = null;
vm.TimeAndMileageReportData = null;
vm.allCallsRemoteReportData = null;
// Modal Back Function
vm.back = function () {
if (vm.showReportSchedule || vm.showReportScheduleUpdate) {
$modalInstance.dismiss('cancel');
}
else if (vm.showMasterCallReport) {
vm.showReportSchedule = true;
vm.showMasterCallReport = false;
}
else if (vm.showTimeAndMileage) {
vm.showReportSchedule = true;
vm.showTimeAndMileage = false;
}
else if (vm.showAllCallsRemote) {
vm.showReportSchedule = true;
vm.showAllCallsRemote = false;
}
};
// Create Report Schedule
vm.next = function () {
if (vm.showReportSchedule) {
if (this.formCreateReportSchedule.$valid) {
vm.showReportSchedule = false;
vm.isUpdateNext = false;
if (vm.ReportSchedule.ReportTemplate.ReportTemplateId == 7) {
vm.showMasterCallReport = true;
return masterCallReportFactory.getData().then(function (data) {
if (logger.displayCommandResult(data)) {
vm.MasterCallReportData = data.Records[0];
}
});
}
if (vm.ReportSchedule.ReportTemplate.ReportTemplateId == 8) {
vm.showTimeAndMileage = true;
return timeAndMileageReportFactory.getData().then(function (data) {
if (logger.displayCommandResult(data)) {
vm.TimeAndMileageReportData = data.Records[0];
}
});
}
if (vm.ReportSchedule.ReportTemplate.ReportTemplateId == 9) {
vm.showAllCallsRemote = true;
return allCallsRemoteReportFactory.getData().then(function (data) {
if (logger.displayCommandResult(data)) {
vm.allCallsRemoteReportData = data.Records[0];
}
});
}
if (vm.ReportSchedule.ReportTemplate.ReportTemplateId == 20) {
vm.formSubmmision = true;
return vm.postScheduleCreationData();
}
} else {
logger.error('Error: Validation failed. Please correct data and try again');
}
}
else if (vm.isUpdate === true) {
if (this.formUpdateReportSchedule.$valid) {
vm.showReportScheduleUpdate = false;
vm.isUpdate = false;
vm.isUpdateNext = true;
if (vm.schedule.ReportTemplate.ReportTemplateId == 7) {
vm.showMasterCallReport = true;
}
if (vm.schedule.ReportTemplate.ReportTemplateId == 8) {
vm.showTimeAndMileage = true;
}
} else {
logger.error('Error: Validation failed. Please correct data and try again');
}
}
else if (vm.isUpdateNext === true) {
if (vm.showMasterCallReport || vm.showTimeAndMileage || vm.showAllCallsRemote || vm.showAllCalls || vm.showAllCallsSLALeft
|| vm.showBreakFix || vm.showCallAssetLine || vm.showDailyStatus || vm.showDailyStatusExtended || vm.showHighPriorityCalls
|| vm.showSLAMasterCalls || vm.showStockMovement) {
// Report Forms
if (this.masterCallReport.$valid || this.timeAndMileageReport.$valid || this.allCallsRemoteReport.$valid || this.allCallsReport.$valid
|| this.allCallsSLALeftReport.$valid || this.callAssetLinesReport.$valid || this.dailyStatusReport.$valid || this.dailyStatusExtendedReport.$valid
|| this.reportHighPriorityCalls.$valid || this.slaMasterCallReport.$valid || this.stockMovementReport.$valid) {
vm.formSubmmision = true;
console.log(vm.schedule);
return vm.postScheduleUpdateData();
}
} else {
return logger.error('Error: Validation failed. Please correct data and try again');
}
}
else if (vm.isUpdateNext === false) {
if (vm.showMasterCallReport || vm.showTimeAndMileage || vm.showAllCallsRemote || vm.showAllCalls || vm.showAllCallsSLALeft
|| vm.showBreakFix || vm.showCallAssetLine || vm.showDailyStatus || vm.showDailyStatusExtended || vm.showHighPriorityCalls
|| vm.showSLAMasterCalls || vm.showStockMovement) {
// Report Forms
if (this.masterCallReport.$valid || this.timeAndMileageReport.$valid || this.allCallsRemoteReport.$valid || this.allCallsReport.$valid
|| this.allCallsSLALeftReport.$valid || this.callAssetLinesReport.$valid || this.dailyStatusReport.$valid || this.dailyStatusExtendedReport.$valid
|| this.reportHighPriorityCalls.$valid || this.slaMasterCallReport.$valid || this.stockMovementReport.$valid) {
vm.formSubmmision = true;
return vm.postScheduleCreationData();
}
} else {
return logger.error('Error: Validation failed. Please correct data and try again');
}
}
};
}
})();
HTML:
<!-- Begin Report Schedule Create-->
<form name="formCreateReportSchedule" novalidate ng-show="showReportSchedule">
<div class="modal-header">
<h3 class="modal-title">Report Scheduling Options</h3>
</div>
<div class="modal-body">
<!-- New Modal -->
<div class="row">
<!-- Report Name -->
<div class="col-md-6">
<label>Report Schedule Name:</label>
<div class="input-text">
<input type="text" name="iScheduleName" ng-model="ReportSchedule.ScheduleName" ng-required="true" />
<div class="fadeInOut" ng-class="{error : iScheduleNameError}" ng-mouseenter="iScheduleNameError = true" ng-mouseleave="iScheduleNameError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iScheduleName.$touched) && formCreateReportSchedule.iScheduleName.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Enter a Schedule Name</span>
</p>
</div>
</div>
</div>
</div>
<!-- Report Template -->
<div class="col-md-6">
<label>Report Type</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Report Name"
ng-model="ReportSchedule.ReportTemplate"
ng-options="SchedulingOptions.SelectableReportTemplates"
cc-fields="ReportTemplateName"
cc-key-field="ReportTemplateId"
cc-allow-search="SchedulingOptions.SelectableReportTemplates != null && SchedulingOptions.SelectableReportTemplates.length > 5"
ng-required="true"
name="iReportTemplate">
</cc-dropdown>
<div class="fadeInOut" ng-class="{error : iReportTemplateError}" ng-mouseenter="iReportTemplateError = true" ng-mouseleave="iReportTemplateError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iReportTemplate.$touched) && formCreateReportSchedule.iReportTemplate.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Select a Template</span>
</p>
</div>
</div>
</div>
</div>
<!-- Hours -->
<div class="col-md-6">
<label>Execution Time</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Report Time"
ng-model="ReportSchedule.ExecutionTime"
ng-options="SelectableExecutionTimes"
cc-fields="<self>"
cc-allow-search="true"
ng-required="true"
name="iExecutionTime">
</cc-dropdown>
<div class="fadeInOut" ng-class="{error : iExecutionTimeError}" ng-mouseenter="iExecutionTimeError = true" ng-mouseleave="iExecutionTimeError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iExecutionTime.$touched) && formCreateReportSchedule.iExecutionTime.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Select an Execution Time</span>
</p>
</div>
</div>
</div>
</div>
<!-- Reporting Period -->
<div class="col-md-6">
<label>Period</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Reporting Period"
ng-model="ReportSchedule.ReportPeriod"
ng-options="SchedulingOptions.SelectableReportingPeriods"
cc-fields="ReportPeriodName"
cc-key-field="ReportPeriodId"
cc-allow-search="SchedulingOptions.SelectableReportPeriods != null && SchedulingOptions.SelectableReportPeriods.length > 5"
ng-required="true"
name="iReportPeriod">
</cc-dropdown>
<div class="fadeInOut" ng-class="{error : iReportPeriodError}" ng-mouseenter="iReportPeriodError = true" ng-mouseleave="iReportPeriodError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iReportPeriod.$touched) && formCreateReportSchedule.iReportPeriod.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Select a Reporting Period</span>
</p>
</div>
</div>
</div>
</div>
<!-- Frequency -->
<div class="col-md-6">
<label>Frequency</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Report Frequency"
ng-model="ReportSchedule.ReportFrequency"
ng-options="SchedulingOptions.SelectableReportFrequencies"
ng-change="frequencyChanged()"
cc-fields="ReportFrequencyName"
cc-key-field="ReportFrequencyId"
cc-allow-search="SchedulingOptions.SelectableReportFrequencies != null && SchedulingOptions.SelectableReportFrequencies.length > 5"
ng-required="true"
name="iReportFrequency">
</cc-dropdown>
<div class="fadeInOut" ng-class="{error : iReportFrequencyError}" ng-mouseenter="iReportFrequencyError = true" ng-mouseleave="iReportFrequencyError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iReportFrequency.$touched) && formCreateReportSchedule.iReportFrequency.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Select a Report Frequency</span>
</p>
</div>
</div>
</div>
</div>
<!-- Frequency Options -->
<div class="col-md-6">
<label>Frequency Options</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Report Frequency Option"
ng-model="ReportSchedule.ReportFrequencyOption"
ng-options="FrequencyOptions"
ng-disabled="FrequencyOptions.length == 0"
cc-fields="ReportFrequencyOptionName"
cc-key-field="ReportFrequencyOptionId"
cc-allow-search="SchedulingOptions.SelectableReportFrequencyOptions != null && SchedulingOptions.SelectableReportFrequencyOptions.length > 5"
ng-required="FrequencyOptions.length != 0"
name="iReportFrequencyOption">
</cc-dropdown>
<div class="fadeInOut" ng-class="{error : iReportFrequencyOptionError}" ng-mouseenter="iReportFrequencyOptionError = true" ng-mouseleave="iReportFrequencyOptionError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iReportFrequencyOption.$touched) && formCreateReportSchedule.iReportFrequencyOption.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Select a Report Frequency Option</span>
</p>
</div>
</div>
</div>
</div>
<!-- Email -->
<div class="col-md-12">
<label>Recipient Email:</label>
<div class="input-text">
<input type="text" name="iEmail" ng-required="true" ng-model="ReportSchedule.EmailRecipients" />
<div class="fadeInOut" ng-class="{error : iEmailError}" ng-mouseenter="iEmailError = true" ng-mouseleave="iEmailError = false" ng-show="(formCreateReportSchedule.$submitted || formCreateReportSchedule.iEmail.$touched) && formCreateReportSchedule.iEmail.$error.required">
<span class="icon-warning"></span>
<div>
<p>
<span>Please Enter a Recipient Email Address</span>
</p>
</div>
</div>
</div>
</div>
</div><!-- row -->
</div> <!--body-->
<div class="modal-footer">
<button class="btn btn-warning left" ng-click="back()" ng-disabled="formSubmmision">Cancel</button>
<button class="btn btn-primary right" type="submit" ng-click="next()" ng-disabled="formSubmmision">Next</button>
</div>
</form>
<!-- Selected Report Settings: Master Call Report -->
<form name="masterCallReport" novalidate ng-show="showMasterCallReport">
<div class="modal-header">
<h3 class="modal-title">Schedule: Master Call Report</h3>
</div>
<div class="modal-body">
<div class="row">
<!-- Customer -->
<div class="col-md-6">
<label>Customer</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Select a Customer"
ng-model="MasterCallReportData.Customer"
ng-options="MasterCallReportData.SelectableCustomer"
cc-fields="CustomerName"
cc-key-field="CustomerId"
cc-allow-search="MasterCallReportData.SelectableCustomer != null && MasterCallReportData.SelectableCustomer.length > 5"
name="iCustomer">
</cc-dropdown>
</div>
</div>
<!-- Resolver Group -->
<div class="col-md-6">
<label>Resolver Group</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="ALL Resolver Groups"
ng-model="MasterCallReportData.ResolverGroup"
ng-options="MasterCallReportData.SelectableResolverGroup"
cc-fields="ResolverGroupDescription"
cc-key-field="ResolverGroupId"
cc-allow-search="MasterCallReportData.SelectableResolverGroup != null && MasterCallReportData.SelectableResolverGroup.length > 5"
name="iResolverGroup">
</cc-dropdown>
</div>
</div>
<!-- Region -->
<div class="col-md-6">
<label>Region</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="ALL Regions"
ng-model="MasterCallReportData.Region"
ng-options="MasterCallReportData.SelectableRegion"
cc-fields="RegionDescription"
cc-key-field="RegionId"
cc-allow-search="MasterCallReportData.SelectableRegion != null && MasterCallReportData.SelectableRegion.length > 5"
name="iRegion">
</cc-dropdown>
</div>
</div>
<!-- Status -->
<div class="col-md-6">
<label>Status</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Open"
ng-model="MasterCallReportData.CallStatus"
ng-options="MasterCallReportData.SelectableStatus"
cc-fields="Status + ' - ' + Reason"
cc-key-field="CallStatusId"
cc-allow-search="MasterCallReportData.SelectableStatus != null && MasterCallReportData.SelectableStatus.length > 5"
name="iStatus">
</cc-dropdown>
</div>
</div>
<!-- Affected End User -->
<div class="col-md-6">
<label>Affected End User</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Select a Contact Person"
ng-model="MasterCallReportData.AffectedEndUser"
ng-options="MasterCallReportData.SelectableAffectedEndUser"
cc-fields="FullName"
cc-key-field="ContactPersonId"
cc-allow-search="MasterCallReportData.SelectableAffectedEndUser != null && MasterCallReportData.SelectableAffectedEndUser.length > 5"
name="iAffectedEndUser">
</cc-dropdown>
</div>
</div>
<!-- Resolution Method -->
<div class="col-md-6">
<label>Resolution Method</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="ALL Method"
ng-model="MasterCallReportData.ResolutionMethod"
ng-options="MasterCallReportData.SelectableResolutionMethod"
cc-fields="ResolutionMethodDescription"
cc-key-field="ResolutionMethodId"
cc-allow-search="false"
name="iResolutionMethod">
</cc-dropdown>
</div>
</div>
<!-- SLA Filter -->
<div class="col-md-6">
<label>SLA Filter</label>
<div class="input-text">
<input type="text" name="iSLAFilter" ng-model="MasterCallReportData.SLAFilter" />
</div>
</div>
<!-- Logged By -->
<div class="col-md-6">
<label>Logged By</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="Select an Employee"
ng-model="MasterCallReportData.LoggedBy"
ng-options="MasterCallReportData.SelectableLoggedBy"
cc-fields="FullName"
cc-key-field="EmployeeId"
cc-allow-search="MasterCallReportData.SelectableLoggedBy != null && MasterCallReportData.SelectableLoggedBy.length > 5"
name="iLoggedBy">
</cc-dropdown>
</div>
</div>
<!-- Call Priority -->
<div class="col-md-6">
<label>Call Priority</label>
<div class="input-dropdown">
<cc-dropdown cc-placeholder="ALL Priorities"
ng-model="MasterCallReportData.Priority"
ng-options="MasterCallReportData.SelectableCallPriority"
cc-fields="CallPriorityDescription"
cc-key-field="CallPriorityId"
cc-allow-search="false"
name="iPriority">
</cc-dropdown>
</div>
</div>
<!-- SLA Breaching Warning -->
<div class="col-md-6">
<label>SLA Breaching Warning</label>
<div class="input-switch">
<input id="toggle-2" class="toggle toggle-yes-no" type="checkbox" ng-model="MasterCallReportData.SLABreachWarning">
<label for="toggle-2" data-on="Yes" data-off="No"></label>
</div>
</div>
<!-- Logged -->
<div class="col-md-6">
<label>Logged</label>
<div class="input-switch">
<input id="toggle-3" class="toggle toggle-yes-no" type="checkbox" ng-model="MasterCallReportData.Logged">
<label for="toggle-3" data-on="Yes" data-off="No"></label>
</div>
</div>
<!-- Resolved -->
<div class="col-md-6">
<label>Resolved</label>
<div class="input-switch">
<input id="toggle-4" class="toggle toggle-yes-no" type="checkbox" ng-model="MasterCallReportData.Resolved">
<label for="toggle-4" data-on="Yes" data-off="No"></label>
</div>
</div>
</div><!-- Row End-->
</div>
<div class="modal-footer">
<button class="btn btn-warning left" ng-click="back()" ng-disabled="formSubmmision">Back</button>
<button class="btn btn-primary right" type="submit" ng-click="next()" ng-disabled="formSubmmision">Next</button>
</div>
</form>

weird behavior of ngrepeat in angularJS

I am having issue with ng-repeat , its replacing all values with latest one.
E.g. I am adding a value to textbox then adding that value in ng-repeat div but its replacing all values with last value entered.
Here is Jsfiddle
https://jsfiddle.net/mahajan344/9bz4Lwxa/656/
This is happening because you have only one statusObj and you are modifying it every time someone clicks the Add New Status button. Delete the statusObj you have now, and have the AddNewStatus method create a new one each time:
var xyzApi = xyzApi || {
sayHello: function() {
return "hey there\n";
}
};
angular.module('demoApp', [])
.controller('MainController', MainController)
.provider('xyzApi', function XyzApiProvider() {
this.$get = function() {
var xyzApiFactory = {
otherFunction: function() {
//$log.log('other function called');
return 'other function \n';
}
};
//console.log(xyzApiFactory, xyzApi);
angular.merge(xyzApiFactory, xyzApi);
return xyzApiFactory;
};
});
function MainController(xyzApi) {
var vm = this;
vm.test = '';
vm.listOfStatus = [];
vm.showStatusError = false;
vm.statusText = "";
vm.sayHello = function() {
vm.test += xyzApi.sayHello() + xyzApi.otherFunction();
}
vm.AddNewStatus = function(statusText) {
if (statusText.length < 1) {
vm.showStatusError = true;
return;
} else {
vm.showStatusError = false;
}
var statusObj = {
StatusComment: statusText,
scId: 0,
scTimeStamp: new Date(),
JobNum: 0,
IsNew: 0,
};
vm.listOfStatus.push(statusObj);
vm.statusText = "";
};
vm.RemoveStatus = function(index) {
vm.listOfStatus.splice(index, 1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.0/angular.js"></script>
<div ng-app="demoApp" ng-controller="MainController as mainCtrl">
<pre>{{mainCtrl.test}}</pre>
<button ng-click="mainCtrl.sayHello()">
say hello!!
</button>
<div id="DivStatus">
<div class="form-group">
Status
<div class="col-md-3 col-sm-3 col-xs-12">
<input type="text" ng-model="mainCtrl.statusText" id="txtStatus" class="form-control col-md-7 col-xs-12">
<div class="text-danger error-message" id="txtStatusError" ng-show="showStatusError">Please enter new status</div>
</div>
<div class="col-md-3 col-md-3x col-sm-3 col-xs-12">
<input type="button" class="btn" ng-click="mainCtrl.AddNewStatus(mainCtrl.statusText)" value="Add New Status" />
</div>
</div>
<div class="form-group" ng-repeat="statusObj in mainCtrl.listOfStatus track by $index">
<div class="col-md-3 col-sm-3 col-xs-12">
<input type="text" value="{{statusObj.StatusComment}}" ng-disabled="true" class="form-control col-md-7 col-xs-12">
</div>
<span class="remove-record" ng-click="mainCtrl.RemoveStatus($index)" style="cursor:pointer"><i class="fa fa-times"></i></span>
</div>
</div>
</div>

angualrjs, find duplicate as input validation with ng-repeat , ng-form nested under form

i am trying to find duplicate value enter in textbox which check each input value on ng-change.then show message "sos number has a match".tried this one but still sort make list data in order. resulting, regular message jsfiddle
so far i am unsuccessful. following is code. :
html code:
<form name="settingForm" ng-submit="mangeDeviceSettings()"><div class="form-group">
<div data-ng-repeat="i in sosLength track by $index">
<ng-form name="sosNumForm">
<span class="input-icon"> <input type="text" ng-disabled="!showPendingStatus" watch-change="change()"
class="form-control" name="SOSNumber" ng-minlength="10" ng-maxlength="13" placeholder="SOSNumber{{$index+1}} No." ng-pattern="/^[0-9]+$/"
ng-model="deviceSettings.sos[$index]" ng-change="sosChange($index,this)">
<i class="fa fa-mobile"></i></span>
<span ng-show="IsMatch{{$index}} && sampleSOS && sosNumForm.SOSNumber.$dirty">SOS Number has a match!</span>
<span ng-show="(sosNumForm.SOSNumber.$error.minlength || sosNumForm.SOSNumber.$error.maxlength) && sosNumForm.SOSNumber.$dirty">Mobile Number must be between 10 and 13 digits </span>
<span ng-show="!sosNumForm.SOSNumber.$error.minlength && !sosNumForm.SOSNumber.$error.maxlength && sosNumForm.SOSNumber.$error.pattern && sosNumForm.SOSNumber.$dirty">Number must contain only numbers</span>
</ng-form>
</div>
</div>
</div></form>
ng-change method:
$scope.sosChange=function(idx, obj){
$scope.sampleSOS = true;
$scope.fnfDuplicate=true;
obj.$parent.settingForm.$valid = obj.sosNumForm.$valid;
// console.log(obj.$parent.settingForm.$valid);
// console.log(obj.sosNumForm.$valid);
console.log($scope.deviceSettings.sos[idx]);
console.log($scope.deviceSettings.sos[i] );
// console.log(obj.sosNumForm.$valid);
// console.log($scope.deviceSettings.sos[idx]!="");
for (var i = 0; i < 3; i++) {
if(idx != i ){
if ($scope.deviceSettings.sos[idx] == $scope.deviceSettings.sos[i]
&& obj.sosNumForm.$valid && $scope.deviceSettings.sos[idx]!="") {
if(idx==0){
$scope.IsMatch0=true; $scope.sosDuplicate=true;
return false;
}
if(idx==1){
$scope.IsMatch1=true; $scope.sosDuplicate=true;
return false;
}
if(idx==2){
$scope.IsMatch2=true; $scope.sosDuplicate=true;
return false;
}
}
else{
if(idx==0){
$scope.IsMatch0=false; $scope.sosDuplicate=false;
return false;
}
if(idx==1){
$scope.IsMatch1=false; $scope.sosDuplicate=false;
return false;
}
if(idx==2){
$scope.IsMatch2=false; $scope.sosDuplicate=false;
return false;
}
}
// $scope.sosDuplicate=true;
}
}
}
If I understood you correctly you simply want to have a validation that two fields have the same value... like password and confirm password... Ill paste a snippet with that (its for password and confirm password) but from there Im sure you can get what you need
I also dont see a need for ngChange since the two items are in the scope so you just want to do a validation if they are not equal.
<div class="form-group required" ng-class="{ 'has-error' : changePasswordForm.password.$invalid && submitted}">
<label class="col-md-3 control-label">New Password </label>
<div class="col-md-8">
<input class="form-control" name="password" ng-model="user.password" ng-minLength="6" type="password" required>
<p ng-show="changePasswordForm.password.$error.minlength && submitted" class="help-block">Password must be atleast 6 characters long.</p>
<p ng-show="changePasswordForm.password.$error.required && !changePasswordForm.password.$error.minlength && submitted" class="help-block">Password is required.</p>
</div>
</div>
<div class="form-group required" ng-class="{ 'has-error' : (changePasswordForm.confPassword.$invalid || user.password!== user.confPassword) && submitted}">
<label class="col-md-3 control-label">Confirm password </label>
<div class="col-md-8">
<input class="form-control" name="confPassword" ng-model="user.confPassword" type="password" required>
<p ng-show="changePasswordForm.confPassword.$invalid && submitted" class="help-block">This field is required.</p>
<p ng-show="changePasswordForm.confPassword.$valid && user.password!== user.confPassword && submitted" class="help-block">Passwords must match.</p>
</div>
</div>
and submitted is for checking when submitted... not required
so here you see we check if the two scope items are not equal and accordingly we show the error...
in the controller all you need is
$scope.onSubmit = function () {
$scope.submitted = true;
if ($scope.createProfileForm.createUserForm.$valid && $scope.user.password === $scope.user.confPassword) {
$scope.submitted = false;
}
}
html code:
<div class="form-group"> <!-- <div data-ng-repeat="i in sosLength track by $index"> -->
<div data-ng-repeat="i in persons track by $index">
<ng-form name="sosNumForm">
<span class="input-icon"> <input type="text" ng-disabled="!showPendingStatus" watch-change="change()"
class="form-control" name="SOSNumber" ng-minlength="10" ng-maxlength="13" placeholder="SOSNumber{{$index+1}} No." ng-pattern="/^[0-9]+$/"
ng-model="deviceSettings.sos[$index]" ng-change="sosChange(this,deviceSettings.sos[$index])">
<i class="fa fa-mobile"></i></span>
<!-- <span ng-show="IsMatch{{$index}} && sampleSOS && sosNumForm.SOSNumber.$dirty">SOS Number has a match!</span> -->
<span ng-if="i.isDuplicate"> SOS Number has a match!</span>
<span ng-show="(sosNumForm.SOSNumber.$error.minlength || sosNumForm.SOSNumber.$error.maxlength) && sosNumForm.SOSNumber.$dirty">Mobile Number must be between 10 and 13 digits </span>
<span ng-show="!sosNumForm.SOSNumber.$error.minlength && !sosNumForm.SOSNumber.$error.maxlength && sosNumForm.SOSNumber.$error.pattern && sosNumForm.SOSNumber.$dirty">Number must contain only numbers</span>
</ng-form>
</div>
</div>
JS code:
$scope.sosDuplicate=true;
$scope.fnfDuplicate=true;
$scope.persons = [{sos:""},{sos:""},{sos:""}];
$scope._persons = [{fnf:""},{fnf:""}];
$scope.fnfValid = true;
$scope.sosValid = true;
$scope.sosChange=function(obj,value){
var sorted, i;
var count =0, checker;
// obj.$parent.settingForm.$valid = obj.sosNumForm.$valid;
$scope.sosValid = obj.sosNumForm.$valid;
if(value!="undefined" || value != "")
{
for (var i = 0; i < 3; i++) {
checker = parseInt($scope.deviceSettings.sos[i]);
$scope.persons[i].sos = checker==NaN ? "" : checker;
};
sorted = $scope.persons.concat().sort(function (a, b) {
if (a.sos > b.sos) return 1;
if (a.sos < b.sos) return -1;
return 0;
});
for(i = 0; i < $scope.persons.length; i++) {
sorted[i].isDuplicate = ((sorted[i-1] && sorted[i-1].sos == sorted[i].sos) || (sorted[i+1] && sorted[i+1].sos == sorted[i].sos)
|| (sorted[i+2] && sorted[i+2].sos == sorted[i].sos)|| (sorted[i-2] && sorted[i-2].sos == sorted[i].sos));
if(sorted[i].isDuplicate==true){
count+=1;
console.log(count);
}
$scope.sosDuplicate= (count>1) ? true : false;
}
}
}

Cleaning up validation logic

I've just got validation working the way I want with the following code:
<div class="control-group" ng-class="{ error : (submitted || accountForm.name.$dirty) && accountForm.name.$invalid }">
<label for="name" class="control-label">Company Name:</label>
<input type="text" name="name" ng-model="account.name" ng-maxlength="50" required />
<span class="help-inline" ng-show="(submitted || accountForm.name.$dirty) && accountForm.name.$error.maxlength">Name too long</span>
<span class="help-inline" ng-show="(submitted || accountForm.name.$dirty) && accountForm.name.$error.required">Required</span>
</div>
But there seems to be a lot of similar code with only slight differences. What would be the best method of simplifying this to make it a) clearer, b) more maintainable?
Update 23/07 Doesn't seem like there's an immediate best practice.
You could make an error variable in the $scope of the controller that controls that template. Something like this:
html
<div ng-controller="FormCtrl" class="control-group" ng-class="{ error : (submitted || accountForm.name.$dirty) && accountForm.name.$invalid }">
<label for="name" class="control-label">Company Name:</label>
<input type="text" name="name" ng-model="account.name" ng-maxlength="50" required />
<input type="button" ng-click="submitForm()" />
<span class="help-inline">{{ error }}</span>
</div>
controller
window.FormCtrl = function ($scope) {
$scope.error = "";
$scope.submitForm = function() {
if ($scope.accountForm.name.length > 50) {
$scope.error = "Name too long";
}
else if ($scope.accountForm.name == null || $scope.accountForm.name == undefined) {
$scope.error = "Name required";
}
else {
$scope.error = "";
//submit logic
}
}
}
Since you want to reuse the same code for other form fields, and the validation logic seems to be similar for each of them, i could not find anything with ngForm that would help reuse the code. Rather I would suggest a different approach, where you don't use ngForm and do the validation in js yourself. This way you can reuse the method everywhere.
Here is the link for the jsFiddle:
http://jsfiddle.net/rCDg8/1/
<div ng-app>
<div ng-controller="DemoCtrl">
<form name="accountForm" ng-submit="submit()">
<div class="control-group" ng-class="class">
<label for="name" class="control-label">Company Name:</label>
<input type="text" name="name" ng-model="account.name" ng-change="validateEntry(account.name)" required></input>
<span class="help-inline" ng-show="accountForm.$dirty||accountForm.$invalid">{{msg}}</span>
</div>
</form>
</div>
</div>
Controller:
function DemoCtrl($scope) {
var longName = 'Name too long';
var nameRequired = 'Name is required!';
$scope.class = '';
$scope.showMsg = false;
$scope.validateEntry = function (validateItem) {
if (angular.isDefined(validateItem)) {
if (validateItem.length > 50) {
showErrorMsg(longName);
} else if (validateItem.length === 0) {
showErrorMsg(nameRequired);
} else {
$scope.class = '';
$scope.showMsg = false;
$scope.accountForm.$dirty = false;
$scope.accountForm.$pristine = true;
}
} else {
showErrorMsg(nameRequired);
}
};
$scope.submit = function(){
alert('IS Form Dirty: '+$scope.accountForm.$dirty);
};
function showErrorMsg(msg) {
$scope.class = 'error';
$scope.showMsg = true;
$scope.msg = msg;
$scope.accountForm.$dirty = true;
}
};

Resources